]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/alsa-ca0106-pm-support
Changed checkfs to auto reboot after correctable fsck fixes.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / alsa-ca0106-pm-support
CommitLineData
00e5a55c
BS
1From 2c5dd6425e72a6e97d9fb9fee9910a58f02d77df Mon Sep 17 00:00:00 2001
2From: Takashi Iwai <tiwai@suse.de>
3Subject: ALSA: ca0106 - Add power-amangement support
4Patch-mainline:
5References: bnc#447624
6
7Added the missing PM support for snd-ca0106 driver.
8
9Signed-off-by: Takashi Iwai <tiwai@suse.de>
10
11---
12
13--- a/sound/pci/ca0106/ca0106_mixer.c
14+++ b/sound/pci/ca0106/ca0106_mixer.c
15@@ -75,6 +75,84 @@
16
17 #include "ca0106.h"
18
19+static void ca0106_spdif_enable(struct snd_ca0106 *emu)
20+{
21+ unsigned int val;
22+
23+ if (emu->spdif_enable) {
24+ /* Digital */
25+ snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
26+ snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
27+ val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
28+ snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
29+ val = inl(emu->port + GPIO) & ~0x101;
30+ outl(val, emu->port + GPIO);
31+
32+ } else {
33+ /* Analog */
34+ snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
35+ snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
36+ val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
37+ snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
38+ val = inl(emu->port + GPIO) | 0x101;
39+ outl(val, emu->port + GPIO);
40+ }
41+}
42+
43+static void ca0106_set_capture_source(struct snd_ca0106 *emu)
44+{
45+ unsigned int val = emu->capture_source;
46+ unsigned int source, mask;
47+ source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
48+ mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
49+ snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
50+}
51+
52+static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
53+ unsigned int val, int force)
54+{
55+ unsigned int ngain, ogain;
56+ u32 source;
57+
58+ snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
59+ ngain = emu->i2c_capture_volume[val][0]; /* Left */
60+ ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
61+ if (force || ngain != ogain)
62+ snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
63+ ngain = emu->i2c_capture_volume[val][1]; /* Right */
64+ ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
65+ if (force || ngain != ogain)
66+ snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
67+ source = 1 << val;
68+ snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
69+ emu->i2c_capture_source = val;
70+}
71+
72+static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
73+{
74+ u32 tmp;
75+
76+ if (emu->capture_mic_line_in) {
77+ /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
78+ tmp = inl(emu->port+GPIO) & ~0x400;
79+ tmp = tmp | 0x400;
80+ outl(tmp, emu->port+GPIO);
81+ /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
82+ } else {
83+ /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
84+ tmp = inl(emu->port+GPIO) & ~0x400;
85+ outl(tmp, emu->port+GPIO);
86+ /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
87+ }
88+}
89+
90+static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
91+{
92+ snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_bits[idx]);
93+}
94+
95+/*
96+ */
97 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
98 static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
99
100@@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(s
101 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
102 unsigned int val;
103 int change = 0;
104- u32 mask;
105
106 val = !!ucontrol->value.integer.value[0];
107 change = (emu->spdif_enable != val);
108 if (change) {
109 emu->spdif_enable = val;
110- if (val) {
111- /* Digital */
112- snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
113- snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
114- snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
115- snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
116- mask = inl(emu->port + GPIO) & ~0x101;
117- outl(mask, emu->port + GPIO);
118-
119- } else {
120- /* Analog */
121- snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
122- snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
123- snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
124- snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
125- mask = inl(emu->port + GPIO) | 0x101;
126- outl(mask, emu->port + GPIO);
127- }
128+ ca0106_spdif_enable(emu);
129 }
130 return change;
131 }
132@@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put
133 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
134 unsigned int val;
135 int change = 0;
136- u32 mask;
137- u32 source;
138
139 val = ucontrol->value.enumerated.item[0] ;
140 if (val >= 6)
141@@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put
142 change = (emu->capture_source != val);
143 if (change) {
144 emu->capture_source = val;
145- source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
146- mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
147- snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
148+ ca0106_set_capture_source(emu);
149 }
150 return change;
151 }
152@@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source
153 {
154 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
155 unsigned int source_id;
156- unsigned int ngain, ogain;
157 int change = 0;
158- u32 source;
159 /* If the capture source has changed,
160 * update the capture volume from the cached value
161 * for the particular source.
162@@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source
163 return -EINVAL;
164 change = (emu->i2c_capture_source != source_id);
165 if (change) {
166- snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
167- ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
168- ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
169- if (ngain != ogain)
170- snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
171- ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
172- ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
173- if (ngain != ogain)
174- snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
175- source = 1 << source_id;
176- snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
177- emu->i2c_capture_source = source_id;
178+ ca0106_set_i2c_capture_source(emu, source_id, 0);
179 }
180 return change;
181 }
182@@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_i
183 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
184 unsigned int val;
185 int change = 0;
186- u32 tmp;
187
188 val = ucontrol->value.enumerated.item[0] ;
189 if (val > 1)
190@@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_i
191 change = (emu->capture_mic_line_in != val);
192 if (change) {
193 emu->capture_mic_line_in = val;
194- if (val) {
195- //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
196- tmp = inl(emu->port+GPIO) & ~0x400;
197- tmp = tmp | 0x400;
198- outl(tmp, emu->port+GPIO);
199- //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
200- } else {
201- //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
202- tmp = inl(emu->port+GPIO) & ~0x400;
203- outl(tmp, emu->port+GPIO);
204- //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
205- }
206+ ca0106_set_capture_mic_line_in(emu);
207 }
208 return change;
209 }
210@@ -359,8 +390,8 @@ static int snd_ca0106_spdif_put(struct s
211 (ucontrol->value.iec958.status[3] << 24);
212 change = val != emu->spdif_bits[idx];
213 if (change) {
214- snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
215 emu->spdif_bits[idx] = val;
216+ ca0106_set_spdif_bits(emu, idx);
217 }
218 return change;
219 }
220@@ -773,3 +804,50 @@ int __devinit snd_ca0106_mixer(struct sn
221 return 0;
222 }
223
224+#ifdef CONFIG_PM
225+struct ca0106_vol_tbl {
226+ unsigned int channel_id;
227+ unsigned int reg;
228+};
229+
230+static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
231+ { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
232+ { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
233+ { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
234+ { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
235+ { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
236+ { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
237+ { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
238+ { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
239+ { 1, CAPTURE_CONTROL },
240+};
241+
242+void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
243+{
244+ int i;
245+
246+ /* save volumes */
247+ for (i = 0; i < NUM_SAVED_VOLUMES; i++)
248+ chip->saved_vol[i] =
249+ snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
250+ saved_volumes[i].channel_id);
251+}
252+
253+void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
254+{
255+ int i;
256+
257+ for (i = 0; i < NUM_SAVED_VOLUMES; i++)
258+ snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
259+ saved_volumes[i].channel_id,
260+ chip->saved_vol[i]);
261+
262+ ca0106_spdif_enable(chip);
263+ ca0106_set_capture_source(chip);
264+ ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
265+ for (i = 0; i < 4; i++)
266+ ca0106_set_spdif_bits(chip, i);
267+ if (chip->details->i2c_adc)
268+ ca0106_set_capture_mic_line_in(chip);
269+}
270+#endif /* CONFIG_PM */
271--- a/sound/pci/ca0106/ca0106.h
272+++ b/sound/pci/ca0106/ca0106.h
273@@ -686,7 +686,7 @@ struct snd_ca0106 {
274 spinlock_t emu_lock;
275
276 struct snd_ac97 *ac97;
277- struct snd_pcm *pcm;
278+ struct snd_pcm *pcm[4];
279
280 struct snd_ca0106_channel playback_channels[4];
281 struct snd_ca0106_channel capture_channels[4];
282@@ -703,6 +703,11 @@ struct snd_ca0106 {
283 struct snd_ca_midi midi2;
284
285 u16 spi_dac_reg[16];
286+
287+#ifdef CONFIG_PM
288+#define NUM_SAVED_VOLUMES 9
289+ unsigned int saved_vol[NUM_SAVED_VOLUMES];
290+#endif
291 };
292
293 int snd_ca0106_mixer(struct snd_ca0106 *emu);
294@@ -721,3 +726,11 @@ int snd_ca0106_i2c_write(struct snd_ca01
295
296 int snd_ca0106_spi_write(struct snd_ca0106 * emu,
297 unsigned int data);
298+
299+#ifdef CONFIG_PM
300+void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
301+void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
302+#else
303+#define snd_ca0106_mixer_suspend(chip) do { } while (0)
304+#define snd_ca0106_mixer_resume(chip) do { } while (0)
305+#endif
306--- a/sound/pci/ca0106/ca0106_main.c
307+++ b/sound/pci/ca0106/ca0106_main.c
308@@ -848,15 +848,18 @@ static int snd_ca0106_pcm_trigger_playba
309 struct snd_pcm_substream *s;
310 u32 basic = 0;
311 u32 extended = 0;
312- int running=0;
313+ u32 bits;
314+ int running = 0;
315
316 switch (cmd) {
317 case SNDRV_PCM_TRIGGER_START:
318- running=1;
319+ case SNDRV_PCM_TRIGGER_RESUME:
320+ running = 1;
321 break;
322 case SNDRV_PCM_TRIGGER_STOP:
323+ case SNDRV_PCM_TRIGGER_SUSPEND:
324 default:
325- running=0;
326+ running = 0;
327 break;
328 }
329 snd_pcm_group_for_each_entry(s, substream) {
330@@ -866,22 +869,32 @@ static int snd_ca0106_pcm_trigger_playba
331 runtime = s->runtime;
332 epcm = runtime->private_data;
333 channel = epcm->channel_id;
334- //snd_printk("channel=%d\n",channel);
335+ /* snd_printk("channel=%d\n",channel); */
336 epcm->running = running;
337- basic |= (0x1<<channel);
338- extended |= (0x10<<channel);
339+ basic |= (0x1 << channel);
340+ extended |= (0x10 << channel);
341 snd_pcm_trigger_done(s, substream);
342 }
343- //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended);
344+ /* snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); */
345
346 switch (cmd) {
347 case SNDRV_PCM_TRIGGER_START:
348- snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended));
349- snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic));
350+ case SNDRV_PCM_TRIGGER_RESUME:
351+ bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
352+ bits |= extended;
353+ snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
354+ bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
355+ bits |= basic;
356+ snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
357 break;
358 case SNDRV_PCM_TRIGGER_STOP:
359- snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
360- snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended));
361+ case SNDRV_PCM_TRIGGER_SUSPEND:
362+ bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
363+ bits &= ~basic;
364+ snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
365+ bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
366+ bits &= ~extended;
367+ snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
368 break;
369 default:
370 result = -EINVAL;
371@@ -1104,21 +1117,13 @@ static int snd_ca0106_ac97(struct snd_ca
372 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
373 }
374
375+static void ca0106_stop_chip(struct snd_ca0106 *chip);
376+
377 static int snd_ca0106_free(struct snd_ca0106 *chip)
378 {
379- if (chip->res_port != NULL) { /* avoid access to already used hardware */
380- // disable interrupts
381- snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
382- outl(0, chip->port + INTE);
383- snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
384- udelay(1000);
385- // disable audio
386- //outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
387- outl(0, chip->port + HCFG);
388- /* FIXME: We need to stop and DMA transfers here.
389- * But as I am not sure how yet, we cannot from the dma pages.
390- * So we can fix: snd-malloc: Memory leak? pages not freed = 8
391- */
392+ if (chip->res_port != NULL) {
393+ /* avoid access to already used hardware */
394+ ca0106_stop_chip(chip);
395 }
396 if (chip->irq >= 0)
397 free_irq(chip->irq, chip);
398@@ -1204,15 +1209,14 @@ static irqreturn_t snd_ca0106_interrupt(
399 return IRQ_HANDLED;
400 }
401
402-static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct snd_pcm **rpcm)
403+static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
404 {
405 struct snd_pcm *pcm;
406 struct snd_pcm_substream *substream;
407 int err;
408
409- if (rpcm)
410- *rpcm = NULL;
411- if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
412+ err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
413+ if (err < 0)
414 return err;
415
416 pcm->private_data = emu;
417@@ -1239,7 +1243,6 @@ static int __devinit snd_ca0106_pcm(stru
418 pcm->info_flags = 0;
419 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
420 strcpy(pcm->name, "CA0106");
421- emu->pcm = pcm;
422
423 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
424 substream;
425@@ -1261,8 +1264,7 @@ static int __devinit snd_ca0106_pcm(stru
426 return err;
427 }
428
429- if (rpcm)
430- *rpcm = pcm;
431+ emu->pcm[device] = pcm;
432
433 return 0;
434 }
435@@ -1302,89 +1304,10 @@ static unsigned int i2c_adc_init[][2] =
436 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
437 };
438
439-static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
440- struct pci_dev *pci,
441- struct snd_ca0106 **rchip)
442+static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
443 {
444- struct snd_ca0106 *chip;
445- struct snd_ca0106_details *c;
446- int err;
447 int ch;
448- static struct snd_device_ops ops = {
449- .dev_free = snd_ca0106_dev_free,
450- };
451-
452- *rchip = NULL;
453-
454- if ((err = pci_enable_device(pci)) < 0)
455- return err;
456- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
457- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
458- printk(KERN_ERR "error to set 32bit mask DMA\n");
459- pci_disable_device(pci);
460- return -ENXIO;
461- }
462-
463- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
464- if (chip == NULL) {
465- pci_disable_device(pci);
466- return -ENOMEM;
467- }
468-
469- chip->card = card;
470- chip->pci = pci;
471- chip->irq = -1;
472-
473- spin_lock_init(&chip->emu_lock);
474-
475- chip->port = pci_resource_start(pci, 0);
476- if ((chip->res_port = request_region(chip->port, 0x20,
477- "snd_ca0106")) == NULL) {
478- snd_ca0106_free(chip);
479- printk(KERN_ERR "cannot allocate the port\n");
480- return -EBUSY;
481- }
482-
483- if (request_irq(pci->irq, snd_ca0106_interrupt,
484- IRQF_SHARED, "snd_ca0106", chip)) {
485- snd_ca0106_free(chip);
486- printk(KERN_ERR "cannot grab irq\n");
487- return -EBUSY;
488- }
489- chip->irq = pci->irq;
490-
491- /* This stores the periods table. */
492- if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
493- snd_ca0106_free(chip);
494- return -ENOMEM;
495- }
496-
497- pci_set_master(pci);
498- /* read serial */
499- pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
500- pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
501-#if 1
502- printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
503- pci->revision, chip->serial);
504-#endif
505- strcpy(card->driver, "CA0106");
506- strcpy(card->shortname, "CA0106");
507-
508- for (c = ca0106_chip_details; c->serial; c++) {
509- if (subsystem[dev]) {
510- if (c->serial == subsystem[dev])
511- break;
512- } else if (c->serial == chip->serial)
513- break;
514- }
515- chip->details = c;
516- if (subsystem[dev]) {
517- printk(KERN_INFO "snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x\n",
518- c->name, chip->serial, subsystem[dev]);
519- }
520-
521- sprintf(card->longname, "%s at 0x%lx irq %i",
522- c->name, chip->port, chip->irq);
523+ unsigned int def_bits;
524
525 outl(0, chip->port + INTE);
526
527@@ -1402,31 +1325,22 @@ static int __devinit snd_ca0106_create(i
528 * AN = 0 (Audio data)
529 * P = 0 (Consumer)
530 */
531- snd_ca0106_ptr_write(chip, SPCS0, 0,
532- chip->spdif_bits[0] =
533- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
534- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
535- SPCS_GENERATIONSTATUS | 0x00001200 |
536- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
537+ def_bits =
538+ SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
539+ SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
540+ SPCS_GENERATIONSTATUS | 0x00001200 |
541+ 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
542+ if (!resume) {
543+ chip->spdif_bits[0] = def_bits;
544+ chip->spdif_bits[1] = def_bits;
545+ chip->spdif_bits[2] = def_bits;
546+ chip->spdif_bits[3] = def_bits;
547+ }
548 /* Only SPCS1 has been tested */
549- snd_ca0106_ptr_write(chip, SPCS1, 0,
550- chip->spdif_bits[1] =
551- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
552- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
553- SPCS_GENERATIONSTATUS | 0x00001200 |
554- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
555- snd_ca0106_ptr_write(chip, SPCS2, 0,
556- chip->spdif_bits[2] =
557- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
558- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
559- SPCS_GENERATIONSTATUS | 0x00001200 |
560- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
561- snd_ca0106_ptr_write(chip, SPCS3, 0,
562- chip->spdif_bits[3] =
563- SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
564- SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
565- SPCS_GENERATIONSTATUS | 0x00001200 |
566- 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
567+ snd_ca0106_ptr_write(chip, SPCS1, 0, chip->spdif_bits[1]);
568+ snd_ca0106_ptr_write(chip, SPCS0, 0, chip->spdif_bits[0]);
569+ snd_ca0106_ptr_write(chip, SPCS2, 0, chip->spdif_bits[2]);
570+ snd_ca0106_ptr_write(chip, SPCS3, 0, chip->spdif_bits[3]);
571
572 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
573 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
574@@ -1434,92 +1348,124 @@ static int __devinit snd_ca0106_create(i
575 /* Write 0x8000 to AC97_REC_GAIN to mute it. */
576 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
577 outw(0x8000, chip->port + AC97DATA);
578-#if 0
579+#if 0 /* FIXME: what are these? */
580 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
581 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
582 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
583 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
584 #endif
585
586- //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */
587+ /* OSS drivers set this. */
588+ /* snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); */
589+
590 /* Analog or Digital output */
591 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
592- snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */
593+ /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers.
594+ * Use 0x000f0000 for surround71
595+ */
596+ snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000);
597+
598 chip->spdif_enable = 0; /* Set digital SPDIF output off */
599- //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */
600- //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */
601+ /*snd_ca0106_ptr_write(chip, 0x45, 0, 0);*/ /* Analogue out */
602+ /*snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00);*/ /* Digital out */
603+
604+ /* goes to 0x40c80000 when doing SPDIF IN/OUT */
605+ snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000);
606+ /* (Mute) CAPTURE feedback into PLAYBACK volume.
607+ * Only lower 16 bits matter.
608+ */
609+ snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff);
610+ /* SPDIF IN Volume */
611+ snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000);
612+ /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
613+ snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000);
614
615- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
616- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
617- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
618- snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
619 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
620 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
621 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
622 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
623- for(ch = 0; ch < 4; ch++) {
624- snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */
625+
626+ for (ch = 0; ch < 4; ch++) {
627+ /* Only high 16 bits matter */
628+ snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030);
629 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
630- //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */
631- //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */
632- snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */
633- snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */
634+#if 0 /* Mute */
635+ snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040);
636+ snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040);
637+ snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff);
638+ snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff);
639+#endif
640 }
641 if (chip->details->i2c_adc == 1) {
642 /* Select MIC, Line in, TAD in, AUX in */
643 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
644 /* Default to CAPTURE_SOURCE to i2s in */
645- chip->capture_source = 3;
646+ if (!resume)
647+ chip->capture_source = 3;
648 } else if (chip->details->ac97 == 1) {
649 /* Default to AC97 in */
650 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4);
651 /* Default to CAPTURE_SOURCE to AC97 in */
652- chip->capture_source = 4;
653+ if (!resume)
654+ chip->capture_source = 4;
655 } else {
656 /* Select MIC, Line in, TAD in, AUX in */
657 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
658 /* Default to Set CAPTURE_SOURCE to i2s in */
659- chip->capture_source = 3;
660+ if (!resume)
661+ chip->capture_source = 3;
662 }
663
664- if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */
665- /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
666+ if (chip->details->gpio_type == 2) {
667+ /* The SB0438 use GPIO differently. */
668+ /* FIXME: Still need to find out what the other GPIO bits do.
669+ * E.g. For digital spdif out.
670+ */
671 outl(0x0, chip->port+GPIO);
672- //outl(0x00f0e000, chip->port+GPIO); /* Analog */
673+ /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
674 outl(0x005f5301, chip->port+GPIO); /* Analog */
675- } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */
676- /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
677+ } else if (chip->details->gpio_type == 1) {
678+ /* The SB0410 and SB0413 use GPIO differently. */
679+ /* FIXME: Still need to find out what the other GPIO bits do.
680+ * E.g. For digital spdif out.
681+ */
682 outl(0x0, chip->port+GPIO);
683- //outl(0x00f0e000, chip->port+GPIO); /* Analog */
684+ /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
685 outl(0x005f5301, chip->port+GPIO); /* Analog */
686 } else {
687 outl(0x0, chip->port+GPIO);
688 outl(0x005f03a3, chip->port+GPIO); /* Analog */
689- //outl(0x005f02a2, chip->port+GPIO); /* SPDIF */
690+ /* outl(0x005f02a2, chip->port+GPIO); */ /* SPDIF */
691 }
692 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
693
694- //outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
695- //outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
696- //outl(0x00000009, chip->port+HCFG);
697- outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
698+ /* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
699+ /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
700+ /* outl(0x00001409, chip->port+HCFG); */
701+ /* outl(0x00000009, chip->port+HCFG); */
702+ /* AC97 2.0, Enable outputs. */
703+ outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG);
704
705- if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
706+ if (chip->details->i2c_adc == 1) {
707+ /* The SB0410 and SB0413 use I2C to control ADC. */
708 int size, n;
709
710 size = ARRAY_SIZE(i2c_adc_init);
711- //snd_printk("I2C:array size=0x%x\n", size);
712- for (n=0; n < size; n++) {
713- snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]);
714- }
715- for (n=0; n < 4; n++) {
716- chip->i2c_capture_volume[n][0]= 0xcf;
717- chip->i2c_capture_volume[n][1]= 0xcf;
718+ /* snd_printk("I2C:array size=0x%x\n", size); */
719+ for (n = 0; n < size; n++)
720+ snd_ca0106_i2c_write(chip, i2c_adc_init[n][0],
721+ i2c_adc_init[n][1]);
722+ for (n = 0; n < 4; n++) {
723+ chip->i2c_capture_volume[n][0] = 0xcf;
724+ chip->i2c_capture_volume[n][1] = 0xcf;
725 }
726- chip->i2c_capture_source=2; /* Line in */
727- //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
728+ chip->i2c_capture_source = 2; /* Line in */
729+ /* Enable Line-in capture. MIC in currently untested. */
730+ /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
731 }
732- if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */
733+
734+ if (chip->details->spi_dac == 1) {
735+ /* The SB0570 use SPI to control DAC. */
736 int size, n;
737
738 size = ARRAY_SIZE(spi_dac_init);
739@@ -1531,9 +1477,112 @@ static int __devinit snd_ca0106_create(i
740 chip->spi_dac_reg[reg] = spi_dac_init[n];
741 }
742 }
743+}
744+
745+static void ca0106_stop_chip(struct snd_ca0106 *chip)
746+{
747+ /* disable interrupts */
748+ snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
749+ outl(0, chip->port + INTE);
750+ snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
751+ udelay(1000);
752+ /* disable audio */
753+ /* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
754+ outl(0, chip->port + HCFG);
755+ /* FIXME: We need to stop and DMA transfers here.
756+ * But as I am not sure how yet, we cannot from the dma pages.
757+ * So we can fix: snd-malloc: Memory leak? pages not freed = 8
758+ */
759+}
760
761- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
762- chip, &ops)) < 0) {
763+static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
764+ struct pci_dev *pci,
765+ struct snd_ca0106 **rchip)
766+{
767+ struct snd_ca0106 *chip;
768+ struct snd_ca0106_details *c;
769+ int err;
770+ static struct snd_device_ops ops = {
771+ .dev_free = snd_ca0106_dev_free,
772+ };
773+
774+ *rchip = NULL;
775+
776+ err = pci_enable_device(pci);
777+ if (err < 0)
778+ return err;
779+ if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
780+ pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
781+ printk(KERN_ERR "error to set 32bit mask DMA\n");
782+ pci_disable_device(pci);
783+ return -ENXIO;
784+ }
785+
786+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
787+ if (chip == NULL) {
788+ pci_disable_device(pci);
789+ return -ENOMEM;
790+ }
791+
792+ chip->card = card;
793+ chip->pci = pci;
794+ chip->irq = -1;
795+
796+ spin_lock_init(&chip->emu_lock);
797+
798+ chip->port = pci_resource_start(pci, 0);
799+ chip->res_port = request_region(chip->port, 0x20, "snd_ca0106");
800+ if (!chip->res_port) {
801+ snd_ca0106_free(chip);
802+ printk(KERN_ERR "cannot allocate the port\n");
803+ return -EBUSY;
804+ }
805+
806+ if (request_irq(pci->irq, snd_ca0106_interrupt,
807+ IRQF_SHARED, "snd_ca0106", chip)) {
808+ snd_ca0106_free(chip);
809+ printk(KERN_ERR "cannot grab irq\n");
810+ return -EBUSY;
811+ }
812+ chip->irq = pci->irq;
813+
814+ /* This stores the periods table. */
815+ if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
816+ 1024, &chip->buffer) < 0) {
817+ snd_ca0106_free(chip);
818+ return -ENOMEM;
819+ }
820+
821+ pci_set_master(pci);
822+ /* read serial */
823+ pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
824+ pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
825+ printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n",
826+ chip->model, pci->revision, chip->serial);
827+ strcpy(card->driver, "CA0106");
828+ strcpy(card->shortname, "CA0106");
829+
830+ for (c = ca0106_chip_details; c->serial; c++) {
831+ if (subsystem[dev]) {
832+ if (c->serial == subsystem[dev])
833+ break;
834+ } else if (c->serial == chip->serial)
835+ break;
836+ }
837+ chip->details = c;
838+ if (subsystem[dev]) {
839+ printk(KERN_INFO "snd-ca0106: Sound card name=%s, "
840+ "subsystem=0x%x. Forced to subsystem=0x%x\n",
841+ c->name, chip->serial, subsystem[dev]);
842+ }
843+
844+ sprintf(card->longname, "%s at 0x%lx irq %i",
845+ c->name, chip->port, chip->irq);
846+
847+ ca0106_init_chip(chip, 0);
848+
849+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
850+ if (err < 0) {
851 snd_ca0106_free(chip);
852 return err;
853 }
854@@ -1630,7 +1679,7 @@ static int __devinit snd_ca0106_probe(st
855 static int dev;
856 struct snd_card *card;
857 struct snd_ca0106 *chip;
858- int err;
859+ int i, err;
860
861 if (dev >= SNDRV_CARDS)
862 return -ENODEV;
863@@ -1643,44 +1692,31 @@ static int __devinit snd_ca0106_probe(st
864 if (card == NULL)
865 return -ENOMEM;
866
867- if ((err = snd_ca0106_create(dev, card, pci, &chip)) < 0) {
868- snd_card_free(card);
869- return err;
870- }
871-
872- if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) {
873- snd_card_free(card);
874- return err;
875- }
876- if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
877- snd_card_free(card);
878- return err;
879- }
880- if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
881- snd_card_free(card);
882- return err;
883- }
884- if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
885- snd_card_free(card);
886- return err;
887- }
888- if (chip->details->ac97 == 1) { /* The SB0410 and SB0413 do not have an AC97 chip. */
889- if ((err = snd_ca0106_ac97(chip)) < 0) {
890- snd_card_free(card);
891- return err;
892- }
893- }
894- if ((err = snd_ca0106_mixer(chip)) < 0) {
895- snd_card_free(card);
896- return err;
897- }
898+ err = snd_ca0106_create(dev, card, pci, &chip);
899+ if (err < 0)
900+ goto error;
901+ card->private_data = chip;
902+
903+ for (i = 0; i < 4; i++) {
904+ err = snd_ca0106_pcm(chip, i);
905+ if (err < 0)
906+ goto error;
907+ }
908+
909+ if (chip->details->ac97 == 1) {
910+ /* The SB0410 and SB0413 do not have an AC97 chip. */
911+ err = snd_ca0106_ac97(chip);
912+ if (err < 0)
913+ goto error;
914+ }
915+ err = snd_ca0106_mixer(chip);
916+ if (err < 0)
917+ goto error;
918
919 snd_printdd("ca0106: probe for MIDI channel A ...");
920- if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) {
921- snd_card_free(card);
922- snd_printdd(" failed, err=0x%x\n",err);
923- return err;
924- }
925+ err = snd_ca0106_midi(chip, CA0106_MIDI_CHAN_A);
926+ if (err < 0)
927+ goto error;
928 snd_printdd(" done.\n");
929
930 #ifdef CONFIG_PROC_FS
931@@ -1689,14 +1725,17 @@ static int __devinit snd_ca0106_probe(st
932
933 snd_card_set_dev(card, &pci->dev);
934
935- if ((err = snd_card_register(card)) < 0) {
936- snd_card_free(card);
937- return err;
938- }
939+ err = snd_card_register(card);
940+ if (err < 0)
941+ goto error;
942
943 pci_set_drvdata(pci, card);
944 dev++;
945 return 0;
946+
947+ error:
948+ snd_card_free(card);
949+ return err;
950 }
951
952 static void __devexit snd_ca0106_remove(struct pci_dev *pci)
953@@ -1705,6 +1744,59 @@ static void __devexit snd_ca0106_remove(
954 pci_set_drvdata(pci, NULL);
955 }
956
957+#ifdef CONFIG_PM
958+static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
959+{
960+ struct snd_card *card = pci_get_drvdata(pci);
961+ struct snd_ca0106 *chip = card->private_data;
962+ int i;
963+
964+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
965+ for (i = 0; i < 4; i++)
966+ snd_pcm_suspend_all(chip->pcm[i]);
967+ if (chip->details->ac97)
968+ snd_ac97_suspend(chip->ac97);
969+ snd_ca0106_mixer_suspend(chip);
970+
971+ ca0106_stop_chip(chip);
972+
973+ pci_disable_device(pci);
974+ pci_save_state(pci);
975+ pci_set_power_state(pci, pci_choose_state(pci, state));
976+ return 0;
977+}
978+
979+static int snd_ca0106_resume(struct pci_dev *pci)
980+{
981+ struct snd_card *card = pci_get_drvdata(pci);
982+ struct snd_ca0106 *chip = card->private_data;
983+ int i;
984+
985+ pci_set_power_state(pci, PCI_D0);
986+ pci_restore_state(pci);
987+
988+ if (pci_enable_device(pci) < 0) {
989+ snd_card_disconnect(card);
990+ return -EIO;
991+ }
992+
993+ pci_set_master(pci);
994+
995+ ca0106_init_chip(chip, 1);
996+
997+ if (chip->details->ac97)
998+ snd_ac97_resume(chip->ac97);
999+ snd_ca0106_mixer_resume(chip);
1000+ if (chip->details->spi_dac) {
1001+ for (i = 0; i < ARRAY_SIZE(chip->spi_dac_reg); i++)
1002+ snd_ca0106_spi_write(chip, chip->spi_dac_reg[i]);
1003+ }
1004+
1005+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1006+ return 0;
1007+}
1008+#endif
1009+
1010 // PCI IDs
1011 static struct pci_device_id snd_ca0106_ids[] = {
1012 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
1013@@ -1718,6 +1810,8 @@ static struct pci_driver driver = {
1014 .id_table = snd_ca0106_ids,
1015 .probe = snd_ca0106_probe,
1016 .remove = __devexit_p(snd_ca0106_remove),
1017+ .suspend = snd_ca0106_suspend,
1018+ .resume = snd_ca0106_resume,
1019 };
1020
1021 // initialization of the module