]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/pci/oxygen/oxygen_lib.c
[ALSA] oxygen: make AC97 codec optional
[linux-2.6-omap-h63xx.git] / sound / pci / oxygen / oxygen_lib.c
1 /*
2  * C-Media CMI8788 driver - main driver module
3  *
4  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5  *
6  *
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.
9  *
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.
14  *
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
18  */
19
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>
30 #include "oxygen.h"
31
32 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
33 MODULE_DESCRIPTION("C-Media CMI8788 helper library");
34 MODULE_LICENSE("GPL");
35
36
37 static irqreturn_t oxygen_interrupt(int dummy, void *dev_id)
38 {
39         struct oxygen *chip = dev_id;
40         unsigned int status, clear, elapsed_streams, i;
41
42         status = oxygen_read16(chip, OXYGEN_INTERRUPT_STATUS);
43         if (!status)
44                 return IRQ_NONE;
45
46         spin_lock(&chip->reg_lock);
47
48         clear = status & (OXYGEN_CHANNEL_A |
49                           OXYGEN_CHANNEL_B |
50                           OXYGEN_CHANNEL_C |
51                           OXYGEN_CHANNEL_SPDIF |
52                           OXYGEN_CHANNEL_MULTICH |
53                           OXYGEN_CHANNEL_AC97 |
54                           OXYGEN_INT_SPDIF_IN_CHANGE |
55                           OXYGEN_INT_GPIO);
56         if (clear) {
57                 if (clear & OXYGEN_INT_SPDIF_IN_CHANGE)
58                         chip->interrupt_mask &= ~OXYGEN_INT_SPDIF_IN_CHANGE;
59                 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
60                                chip->interrupt_mask & ~clear);
61                 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
62                                chip->interrupt_mask);
63         }
64
65         elapsed_streams = status & chip->pcm_running;
66
67         spin_unlock(&chip->reg_lock);
68
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]);
72
73         if (status & OXYGEN_INT_SPDIF_IN_CHANGE) {
74                 spin_lock(&chip->reg_lock);
75                 i = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
76                 if (i & OXYGEN_SPDIF_IN_CHANGE) {
77                         oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, i);
78                         schedule_work(&chip->spdif_input_bits_work);
79                 }
80                 spin_unlock(&chip->reg_lock);
81         }
82
83         if (status & OXYGEN_INT_GPIO)
84                 ;
85
86         if ((status & OXYGEN_INT_MIDI) && chip->midi)
87                 snd_mpu401_uart_interrupt(0, chip->midi->private_data);
88
89         return IRQ_HANDLED;
90 }
91
92 static void oxygen_spdif_input_bits_changed(struct work_struct *work)
93 {
94         struct oxygen *chip = container_of(work, struct oxygen,
95                                            spdif_input_bits_work);
96
97         spin_lock_irq(&chip->reg_lock);
98         oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_IN_INVERT);
99         spin_unlock_irq(&chip->reg_lock);
100         msleep(1);
101         if (!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL)
102               & OXYGEN_SPDIF_IN_VALID)) {
103                 spin_lock_irq(&chip->reg_lock);
104                 oxygen_set_bits32(chip, OXYGEN_SPDIF_CONTROL,
105                                   OXYGEN_SPDIF_IN_INVERT);
106                 spin_unlock_irq(&chip->reg_lock);
107                 msleep(1);
108                 if (!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL)
109                       & OXYGEN_SPDIF_IN_VALID)) {
110                         spin_lock_irq(&chip->reg_lock);
111                         oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
112                                             OXYGEN_SPDIF_IN_INVERT);
113                         spin_unlock_irq(&chip->reg_lock);
114                 }
115         }
116
117         if (chip->controls[CONTROL_SPDIF_INPUT_BITS]) {
118                 spin_lock_irq(&chip->reg_lock);
119                 chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_CHANGE;
120                 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
121                                chip->interrupt_mask);
122                 spin_unlock_irq(&chip->reg_lock);
123
124                 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
125                                &chip->controls[CONTROL_SPDIF_INPUT_BITS]->id);
126         }
127 }
128
129 #ifdef CONFIG_PROC_FS
130 static void oxygen_proc_read(struct snd_info_entry *entry,
131                              struct snd_info_buffer *buffer)
132 {
133         struct oxygen *chip = entry->private_data;
134         int i, j;
135
136         snd_iprintf(buffer, "CMI8788\n\n");
137         for (i = 0; i < 0x100; i += 0x10) {
138                 snd_iprintf(buffer, "%02x:", i);
139                 for (j = 0; j < 0x10; ++j)
140                         snd_iprintf(buffer, " %02x", oxygen_read8(chip, i + j));
141                 snd_iprintf(buffer, "\n");
142         }
143         if (mutex_lock_interruptible(&chip->mutex) < 0)
144                 return;
145         if (chip->has_ac97_0) {
146                 snd_iprintf(buffer, "\nAC97\n");
147                 for (i = 0; i < 0x80; i += 0x10) {
148                         snd_iprintf(buffer, "%02x:", i);
149                         for (j = 0; j < 0x10; j += 2)
150                                 snd_iprintf(buffer, " %04x",
151                                             oxygen_read_ac97(chip, 0, i + j));
152                         snd_iprintf(buffer, "\n");
153                 }
154         }
155         if (chip->has_ac97_1) {
156                 snd_iprintf(buffer, "\nAC97 2\n");
157                 for (i = 0; i < 0x80; i += 0x10) {
158                         snd_iprintf(buffer, "%02x:", i);
159                         for (j = 0; j < 0x10; j += 2)
160                                 snd_iprintf(buffer, " %04x",
161                                             oxygen_read_ac97(chip, 1, i + j));
162                         snd_iprintf(buffer, "\n");
163                 }
164         }
165         mutex_unlock(&chip->mutex);
166 }
167
168 static void __devinit oxygen_proc_init(struct oxygen *chip)
169 {
170         struct snd_info_entry *entry;
171
172         if (!snd_card_proc_new(chip->card, "cmi8788", &entry))
173                 snd_info_set_text_ops(entry, chip, oxygen_proc_read);
174 }
175 #else
176 #define oxygen_proc_init(chip)
177 #endif
178
179 static void __devinit oxygen_init(struct oxygen *chip)
180 {
181         unsigned int i;
182
183         chip->dac_routing = 1;
184         for (i = 0; i < 8; ++i)
185                 chip->dac_volume[i] = 0xff;
186         chip->spdif_playback_enable = 1;
187         chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL |
188                 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
189         chip->spdif_pcm_bits = chip->spdif_bits;
190
191         if (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2)
192                 chip->revision = 2;
193         else
194                 chip->revision = 1;
195
196         if (chip->revision == 1)
197                 oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_MAGIC);
198
199         i = oxygen_read16(chip, OXYGEN_AC97_CONTROL);
200         chip->has_ac97_0 = (i & OXYGEN_AC97_CODEC_0) != 0;
201         chip->has_ac97_1 = (i & OXYGEN_AC97_CODEC_1) != 0;
202
203         oxygen_set_bits8(chip, OXYGEN_FUNCTION,
204                          OXYGEN_FUNCTION_RESET_CODEC |
205                          OXYGEN_FUNCTION_ENABLE_SPI_4_5);
206         oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, 0x010a);
207         oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 0x010a);
208         oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 0x010a);
209         oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, 0x010a);
210         oxygen_set_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_MAGIC2);
211         oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits);
212         oxygen_write16(chip, OXYGEN_PLAY_ROUTING, 0xe100);
213         oxygen_write8(chip, OXYGEN_REC_ROUTING, 0x10);
214         oxygen_write8(chip, OXYGEN_ADC_MONITOR, 0x00);
215         oxygen_write8(chip, OXYGEN_A_MONITOR_ROUTING, 0xe4);
216
217         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
218         oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
219
220         oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00);
221         if (chip->has_ac97_0) {
222                 oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG,
223                                     OXYGEN_AC97_OUT_MAGIC3);
224                 oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG,
225                                   OXYGEN_AC97_IN_MAGIC3);
226                 oxygen_write_ac97(chip, 0, AC97_RESET, 0);
227                 msleep(1);
228                 oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300);
229                 oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043);
230                 oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f);
231                 oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000);
232                 oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000);
233                 oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808);
234                 oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808);
235                 oxygen_write_ac97(chip, 0, AC97_CD, 0x8808);
236                 oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808);
237                 oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808);
238                 oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000);
239                 oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080);
240                 oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080);
241                 oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001);
242                 /* power down unused ADCs and DACs */
243                 oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN,
244                                      AC97_PD_PR0 | AC97_PD_PR1);
245                 oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS,
246                                      AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK);
247         }
248 }
249
250 static void oxygen_card_free(struct snd_card *card)
251 {
252         struct oxygen *chip = card->private_data;
253
254         spin_lock_irq(&chip->reg_lock);
255         chip->interrupt_mask = 0;
256         chip->pcm_running = 0;
257         oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
258         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
259         spin_unlock_irq(&chip->reg_lock);
260         if (chip->irq >= 0) {
261                 free_irq(chip->irq, chip);
262                 synchronize_irq(chip->irq);
263         }
264         flush_scheduled_work();
265         chip->model->cleanup(chip);
266         mutex_destroy(&chip->mutex);
267         pci_release_regions(chip->pci);
268         pci_disable_device(chip->pci);
269 }
270
271 int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
272                                const struct oxygen_model *model)
273 {
274         struct snd_card *card;
275         struct oxygen *chip;
276         int err;
277
278         card = snd_card_new(index, id, model->owner, sizeof *chip);
279         if (!card)
280                 return -ENOMEM;
281
282         chip = card->private_data;
283         chip->card = card;
284         chip->pci = pci;
285         chip->irq = -1;
286         chip->model = model;
287         spin_lock_init(&chip->reg_lock);
288         mutex_init(&chip->mutex);
289         INIT_WORK(&chip->spdif_input_bits_work,
290                   oxygen_spdif_input_bits_changed);
291
292         err = pci_enable_device(pci);
293         if (err < 0)
294                 goto err_card;
295
296         err = pci_request_regions(pci, model->chip);
297         if (err < 0) {
298                 snd_printk(KERN_ERR "cannot reserve PCI resources\n");
299                 goto err_pci_enable;
300         }
301
302         if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) ||
303             pci_resource_len(pci, 0) < 0x100) {
304                 snd_printk(KERN_ERR "invalid PCI I/O range\n");
305                 err = -ENXIO;
306                 goto err_pci_regions;
307         }
308         chip->addr = pci_resource_start(pci, 0);
309
310         pci_set_master(pci);
311         snd_card_set_dev(card, &pci->dev);
312         card->private_free = oxygen_card_free;
313
314         oxygen_init(chip);
315         model->init(chip);
316
317         err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
318                           model->chip, chip);
319         if (err < 0) {
320                 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
321                 goto err_card;
322         }
323         chip->irq = pci->irq;
324
325         strcpy(card->driver, model->chip);
326         strcpy(card->shortname, model->shortname);
327         sprintf(card->longname, "%s (rev %u) at %#lx, irq %i",
328                 model->longname, chip->revision, chip->addr, chip->irq);
329         strcpy(card->mixername, model->chip);
330         snd_component_add(card, model->chip);
331
332         err = oxygen_pcm_init(chip);
333         if (err < 0)
334                 goto err_card;
335
336         err = oxygen_mixer_init(chip);
337         if (err < 0)
338                 goto err_card;
339
340         if (oxygen_read8(chip, OXYGEN_MISC) & OXYGEN_MISC_MIDI) {
341                 err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
342                                           chip->addr + OXYGEN_MPU401,
343                                           MPU401_INFO_INTEGRATED, 0, 0,
344                                           &chip->midi);
345                 if (err < 0)
346                         goto err_card;
347         }
348
349         oxygen_proc_init(chip);
350
351         spin_lock_irq(&chip->reg_lock);
352         chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_CHANGE;
353         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
354         spin_unlock_irq(&chip->reg_lock);
355
356         err = snd_card_register(card);
357         if (err < 0)
358                 goto err_card;
359
360         pci_set_drvdata(pci, card);
361         return 0;
362
363 err_pci_regions:
364         pci_release_regions(pci);
365 err_pci_enable:
366         pci_disable_device(pci);
367 err_card:
368         snd_card_free(card);
369         return err;
370 }
371 EXPORT_SYMBOL(oxygen_pci_probe);
372
373 void __devexit oxygen_pci_remove(struct pci_dev *pci)
374 {
375         snd_card_free(pci_get_drvdata(pci));
376         pci_set_drvdata(pci, NULL);
377 }
378 EXPORT_SYMBOL(oxygen_pci_remove);