2 * C-Media CMI8788 driver - main driver module
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <linux/delay.h>
21 #include <linux/interrupt.h>
22 #include <linux/mutex.h>
23 #include <linux/pci.h>
24 #include <sound/ac97_codec.h>
25 #include <sound/asoundef.h>
26 #include <sound/core.h>
27 #include <sound/info.h>
28 #include <sound/mpu401.h>
29 #include <sound/pcm.h>
32 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
33 MODULE_DESCRIPTION("C-Media CMI8788 helper library");
34 MODULE_LICENSE("GPL");
37 static irqreturn_t
oxygen_interrupt(int dummy
, void *dev_id
)
39 struct oxygen
*chip
= dev_id
;
40 unsigned int status
, clear
, elapsed_streams
, i
;
42 status
= oxygen_read16(chip
, OXYGEN_INTERRUPT_STATUS
);
46 spin_lock(&chip
->reg_lock
);
48 clear
= status
& (OXYGEN_CHANNEL_A
|
51 OXYGEN_CHANNEL_SPDIF
|
52 OXYGEN_CHANNEL_MULTICH
|
54 OXYGEN_INT_SPDIF_IN_DETECT
|
57 if (clear
& OXYGEN_INT_SPDIF_IN_DETECT
)
58 chip
->interrupt_mask
&= ~OXYGEN_INT_SPDIF_IN_DETECT
;
59 oxygen_write16(chip
, OXYGEN_INTERRUPT_MASK
,
60 chip
->interrupt_mask
& ~clear
);
61 oxygen_write16(chip
, OXYGEN_INTERRUPT_MASK
,
62 chip
->interrupt_mask
);
65 elapsed_streams
= status
& chip
->pcm_running
;
67 spin_unlock(&chip
->reg_lock
);
69 for (i
= 0; i
< PCM_COUNT
; ++i
)
70 if ((elapsed_streams
& (1 << i
)) && chip
->streams
[i
])
71 snd_pcm_period_elapsed(chip
->streams
[i
]);
73 if (status
& OXYGEN_INT_SPDIF_IN_DETECT
) {
74 spin_lock(&chip
->reg_lock
);
75 i
= oxygen_read32(chip
, OXYGEN_SPDIF_CONTROL
);
76 if (i
& OXYGEN_SPDIF_RATE_INT
) {
77 oxygen_write32(chip
, OXYGEN_SPDIF_CONTROL
, i
);
78 schedule_work(&chip
->spdif_input_bits_work
);
80 spin_unlock(&chip
->reg_lock
);
83 if (status
& OXYGEN_INT_GPIO
)
86 if ((status
& OXYGEN_INT_MIDI
) && chip
->midi
)
87 snd_mpu401_uart_interrupt(0, chip
->midi
->private_data
);
92 static void oxygen_spdif_input_bits_changed(struct work_struct
*work
)
94 struct oxygen
*chip
= container_of(work
, struct oxygen
,
95 spdif_input_bits_work
);
97 spin_lock_irq(&chip
->reg_lock
);
98 oxygen_write32_masked(chip
, OXYGEN_SPDIF_CONTROL
,
99 OXYGEN_SPDIF_IN_CLOCK_96
,
100 OXYGEN_SPDIF_IN_CLOCK_MASK
);
101 spin_unlock_irq(&chip
->reg_lock
);
103 if (!(oxygen_read32(chip
, OXYGEN_SPDIF_CONTROL
)
104 & OXYGEN_SPDIF_LOCK_STATUS
)) {
105 spin_lock_irq(&chip
->reg_lock
);
106 oxygen_write32_masked(chip
, OXYGEN_SPDIF_CONTROL
,
107 OXYGEN_SPDIF_IN_CLOCK_192
,
108 OXYGEN_SPDIF_IN_CLOCK_MASK
);
109 spin_unlock_irq(&chip
->reg_lock
);
111 if (!(oxygen_read32(chip
, OXYGEN_SPDIF_CONTROL
)
112 & OXYGEN_SPDIF_LOCK_STATUS
)) {
113 spin_lock_irq(&chip
->reg_lock
);
114 oxygen_write32_masked(chip
, OXYGEN_SPDIF_CONTROL
,
115 OXYGEN_SPDIF_IN_CLOCK_96
,
116 OXYGEN_SPDIF_IN_CLOCK_MASK
);
117 spin_unlock_irq(&chip
->reg_lock
);
121 if (chip
->controls
[CONTROL_SPDIF_INPUT_BITS
]) {
122 spin_lock_irq(&chip
->reg_lock
);
123 chip
->interrupt_mask
|= OXYGEN_INT_SPDIF_IN_DETECT
;
124 oxygen_write16(chip
, OXYGEN_INTERRUPT_MASK
,
125 chip
->interrupt_mask
);
126 spin_unlock_irq(&chip
->reg_lock
);
128 snd_ctl_notify(chip
->card
, SNDRV_CTL_EVENT_MASK_VALUE
,
129 &chip
->controls
[CONTROL_SPDIF_INPUT_BITS
]->id
);
133 #ifdef CONFIG_PROC_FS
134 static void oxygen_proc_read(struct snd_info_entry
*entry
,
135 struct snd_info_buffer
*buffer
)
137 struct oxygen
*chip
= entry
->private_data
;
140 snd_iprintf(buffer
, "CMI8788\n\n");
141 for (i
= 0; i
< 0x100; i
+= 0x10) {
142 snd_iprintf(buffer
, "%02x:", i
);
143 for (j
= 0; j
< 0x10; ++j
)
144 snd_iprintf(buffer
, " %02x", oxygen_read8(chip
, i
+ j
));
145 snd_iprintf(buffer
, "\n");
147 if (mutex_lock_interruptible(&chip
->mutex
) < 0)
149 if (chip
->has_ac97_0
) {
150 snd_iprintf(buffer
, "\nAC97\n");
151 for (i
= 0; i
< 0x80; i
+= 0x10) {
152 snd_iprintf(buffer
, "%02x:", i
);
153 for (j
= 0; j
< 0x10; j
+= 2)
154 snd_iprintf(buffer
, " %04x",
155 oxygen_read_ac97(chip
, 0, i
+ j
));
156 snd_iprintf(buffer
, "\n");
159 if (chip
->has_ac97_1
) {
160 snd_iprintf(buffer
, "\nAC97 2\n");
161 for (i
= 0; i
< 0x80; i
+= 0x10) {
162 snd_iprintf(buffer
, "%02x:", i
);
163 for (j
= 0; j
< 0x10; j
+= 2)
164 snd_iprintf(buffer
, " %04x",
165 oxygen_read_ac97(chip
, 1, i
+ j
));
166 snd_iprintf(buffer
, "\n");
169 mutex_unlock(&chip
->mutex
);
172 static void __devinit
oxygen_proc_init(struct oxygen
*chip
)
174 struct snd_info_entry
*entry
;
176 if (!snd_card_proc_new(chip
->card
, "cmi8788", &entry
))
177 snd_info_set_text_ops(entry
, chip
, oxygen_proc_read
);
180 #define oxygen_proc_init(chip)
183 static void __devinit
oxygen_init(struct oxygen
*chip
)
187 chip
->dac_routing
= 1;
188 for (i
= 0; i
< 8; ++i
)
189 chip
->dac_volume
[i
] = 0xff;
190 chip
->spdif_playback_enable
= 1;
191 chip
->spdif_bits
= OXYGEN_SPDIF_C
| OXYGEN_SPDIF_ORIGINAL
|
192 (IEC958_AES1_CON_PCM_CODER
<< OXYGEN_SPDIF_CATEGORY_SHIFT
);
193 chip
->spdif_pcm_bits
= chip
->spdif_bits
;
195 if (oxygen_read8(chip
, OXYGEN_REVISION
) & OXYGEN_REVISION_2
)
200 if (chip
->revision
== 1)
201 oxygen_set_bits8(chip
, OXYGEN_MISC
,
202 OXYGEN_MISC_PCI_MEM_W_1_CLOCK
);
204 i
= oxygen_read16(chip
, OXYGEN_AC97_CONTROL
);
205 chip
->has_ac97_0
= (i
& OXYGEN_AC97_CODEC_0
) != 0;
206 chip
->has_ac97_1
= (i
& OXYGEN_AC97_CODEC_1
) != 0;
208 oxygen_set_bits8(chip
, OXYGEN_FUNCTION
,
209 OXYGEN_FUNCTION_RESET_CODEC
|
210 chip
->model
->function_flags
);
211 oxygen_write16(chip
, OXYGEN_I2S_MULTICH_FORMAT
,
212 OXYGEN_RATE_48000
| OXYGEN_I2S_FORMAT_LJUST
|
213 OXYGEN_I2S_MCLK_128
| OXYGEN_I2S_BITS_16
|
214 OXYGEN_I2S_MASTER
| OXYGEN_I2S_BCLK_64
);
215 oxygen_write16(chip
, OXYGEN_I2S_A_FORMAT
,
216 OXYGEN_RATE_48000
| OXYGEN_I2S_FORMAT_LJUST
|
217 OXYGEN_I2S_MCLK_128
| OXYGEN_I2S_BITS_16
|
218 OXYGEN_I2S_MASTER
| OXYGEN_I2S_BCLK_64
);
219 oxygen_write16(chip
, OXYGEN_I2S_B_FORMAT
,
220 OXYGEN_RATE_48000
| OXYGEN_I2S_FORMAT_LJUST
|
221 OXYGEN_I2S_MCLK_128
| OXYGEN_I2S_BITS_16
|
222 OXYGEN_I2S_MASTER
| OXYGEN_I2S_BCLK_64
);
223 oxygen_write16(chip
, OXYGEN_I2S_C_FORMAT
,
224 OXYGEN_RATE_48000
| OXYGEN_I2S_FORMAT_LJUST
|
225 OXYGEN_I2S_MCLK_128
| OXYGEN_I2S_BITS_16
|
226 OXYGEN_I2S_MASTER
| OXYGEN_I2S_BCLK_64
);
227 oxygen_set_bits32(chip
, OXYGEN_SPDIF_CONTROL
, OXYGEN_SPDIF_RATE_MASK
);
228 oxygen_write32(chip
, OXYGEN_SPDIF_OUTPUT_BITS
, chip
->spdif_bits
);
229 oxygen_write16(chip
, OXYGEN_PLAY_ROUTING
,
230 OXYGEN_PLAY_MULTICH_I2S_DAC
| OXYGEN_PLAY_SPDIF_SPDIF
|
231 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT
) |
232 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT
) |
233 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT
) |
234 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT
));
235 oxygen_write8(chip
, OXYGEN_REC_ROUTING
,
236 OXYGEN_REC_A_ROUTE_I2S_ADC_1
|
237 OXYGEN_REC_B_ROUTE_AC97_1
|
238 OXYGEN_REC_C_ROUTE_SPDIF
);
239 oxygen_write8(chip
, OXYGEN_ADC_MONITOR
, 0);
240 oxygen_write8(chip
, OXYGEN_A_MONITOR_ROUTING
,
241 (0 << OXYGEN_A_MONITOR_ROUTE_0_SHIFT
) |
242 (1 << OXYGEN_A_MONITOR_ROUTE_1_SHIFT
) |
243 (2 << OXYGEN_A_MONITOR_ROUTE_2_SHIFT
) |
244 (3 << OXYGEN_A_MONITOR_ROUTE_3_SHIFT
));
246 oxygen_write16(chip
, OXYGEN_INTERRUPT_MASK
, 0);
247 oxygen_write16(chip
, OXYGEN_DMA_STATUS
, 0);
249 oxygen_write8(chip
, OXYGEN_AC97_INTERRUPT_MASK
, 0);
250 if (chip
->has_ac97_0
) {
251 oxygen_clear_bits16(chip
, OXYGEN_AC97_OUT_CONFIG
,
252 OXYGEN_AC97_CODEC0_FRONTL
|
253 OXYGEN_AC97_CODEC0_FRONTR
|
254 OXYGEN_AC97_CODEC0_SIDEL
|
255 OXYGEN_AC97_CODEC0_SIDER
|
256 OXYGEN_AC97_CODEC0_CENTER
|
257 OXYGEN_AC97_CODEC0_BASE
|
258 OXYGEN_AC97_CODEC0_REARL
|
259 OXYGEN_AC97_CODEC0_REARR
);
260 oxygen_set_bits16(chip
, OXYGEN_AC97_IN_CONFIG
,
261 OXYGEN_AC97_CODEC0_LINEL
|
262 OXYGEN_AC97_CODEC0_LINER
);
263 oxygen_write_ac97(chip
, 0, AC97_RESET
, 0);
265 oxygen_ac97_set_bits(chip
, 0, 0x70, 0x0300);
266 oxygen_ac97_set_bits(chip
, 0, 0x64, 0x8043);
267 oxygen_ac97_set_bits(chip
, 0, 0x62, 0x180f);
268 oxygen_write_ac97(chip
, 0, AC97_MASTER
, 0x0000);
269 oxygen_write_ac97(chip
, 0, AC97_PC_BEEP
, 0x8000);
270 oxygen_write_ac97(chip
, 0, AC97_MIC
, 0x8808);
271 oxygen_write_ac97(chip
, 0, AC97_LINE
, 0x0808);
272 oxygen_write_ac97(chip
, 0, AC97_CD
, 0x8808);
273 oxygen_write_ac97(chip
, 0, AC97_VIDEO
, 0x8808);
274 oxygen_write_ac97(chip
, 0, AC97_AUX
, 0x8808);
275 oxygen_write_ac97(chip
, 0, AC97_REC_GAIN
, 0x8000);
276 oxygen_write_ac97(chip
, 0, AC97_CENTER_LFE_MASTER
, 0x8080);
277 oxygen_write_ac97(chip
, 0, AC97_SURROUND_MASTER
, 0x8080);
278 oxygen_ac97_clear_bits(chip
, 0, 0x72, 0x0001);
279 /* power down unused ADCs and DACs */
280 oxygen_ac97_set_bits(chip
, 0, AC97_POWERDOWN
,
281 AC97_PD_PR0
| AC97_PD_PR1
);
282 oxygen_ac97_set_bits(chip
, 0, AC97_EXTENDED_STATUS
,
283 AC97_EA_PRI
| AC97_EA_PRJ
| AC97_EA_PRK
);
287 static void oxygen_card_free(struct snd_card
*card
)
289 struct oxygen
*chip
= card
->private_data
;
291 spin_lock_irq(&chip
->reg_lock
);
292 chip
->interrupt_mask
= 0;
293 chip
->pcm_running
= 0;
294 oxygen_write16(chip
, OXYGEN_DMA_STATUS
, 0);
295 oxygen_write16(chip
, OXYGEN_INTERRUPT_MASK
, 0);
296 spin_unlock_irq(&chip
->reg_lock
);
297 if (chip
->irq
>= 0) {
298 free_irq(chip
->irq
, chip
);
299 synchronize_irq(chip
->irq
);
301 flush_scheduled_work();
302 chip
->model
->cleanup(chip
);
303 mutex_destroy(&chip
->mutex
);
304 pci_release_regions(chip
->pci
);
305 pci_disable_device(chip
->pci
);
308 int __devinit
oxygen_pci_probe(struct pci_dev
*pci
, int index
, char *id
,
309 const struct oxygen_model
*model
)
311 struct snd_card
*card
;
315 card
= snd_card_new(index
, id
, model
->owner
, sizeof *chip
);
319 chip
= card
->private_data
;
324 spin_lock_init(&chip
->reg_lock
);
325 mutex_init(&chip
->mutex
);
326 INIT_WORK(&chip
->spdif_input_bits_work
,
327 oxygen_spdif_input_bits_changed
);
329 err
= pci_enable_device(pci
);
333 err
= pci_request_regions(pci
, model
->chip
);
335 snd_printk(KERN_ERR
"cannot reserve PCI resources\n");
339 if (!(pci_resource_flags(pci
, 0) & IORESOURCE_IO
) ||
340 pci_resource_len(pci
, 0) < 0x100) {
341 snd_printk(KERN_ERR
"invalid PCI I/O range\n");
343 goto err_pci_regions
;
345 chip
->addr
= pci_resource_start(pci
, 0);
348 snd_card_set_dev(card
, &pci
->dev
);
349 card
->private_free
= oxygen_card_free
;
354 err
= request_irq(pci
->irq
, oxygen_interrupt
, IRQF_SHARED
,
357 snd_printk(KERN_ERR
"cannot grab interrupt %d\n", pci
->irq
);
360 chip
->irq
= pci
->irq
;
362 strcpy(card
->driver
, model
->chip
);
363 strcpy(card
->shortname
, model
->shortname
);
364 sprintf(card
->longname
, "%s (rev %u) at %#lx, irq %i",
365 model
->longname
, chip
->revision
, chip
->addr
, chip
->irq
);
366 strcpy(card
->mixername
, model
->chip
);
367 snd_component_add(card
, model
->chip
);
369 err
= oxygen_pcm_init(chip
);
373 err
= oxygen_mixer_init(chip
);
377 if (oxygen_read8(chip
, OXYGEN_MISC
) & OXYGEN_MISC_MIDI
) {
378 err
= snd_mpu401_uart_new(card
, 0, MPU401_HW_CMIPCI
,
379 chip
->addr
+ OXYGEN_MPU401
,
380 MPU401_INFO_INTEGRATED
, 0, 0,
386 oxygen_proc_init(chip
);
388 spin_lock_irq(&chip
->reg_lock
);
389 chip
->interrupt_mask
|= OXYGEN_INT_SPDIF_IN_DETECT
;
390 oxygen_write16(chip
, OXYGEN_INTERRUPT_MASK
, chip
->interrupt_mask
);
391 spin_unlock_irq(&chip
->reg_lock
);
393 err
= snd_card_register(card
);
397 pci_set_drvdata(pci
, card
);
401 pci_release_regions(pci
);
403 pci_disable_device(pci
);
408 EXPORT_SYMBOL(oxygen_pci_probe
);
410 void __devexit
oxygen_pci_remove(struct pci_dev
*pci
)
412 snd_card_free(pci_get_drvdata(pci
));
413 pci_set_drvdata(pci
, NULL
);
415 EXPORT_SYMBOL(oxygen_pci_remove
);