]> git.karo-electronics.de Git - karo-tx-linux.git/blob - sound/pci/oxygen/oxygen_lib.c
[ALSA] oxygen: use an array of snd_kcontrol pointers
[karo-tx-linux.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         snd_iprintf(buffer, "\nAC97\n");
146         for (i = 0; i < 0x80; i += 0x10) {
147                 snd_iprintf(buffer, "%02x:", i);
148                 for (j = 0; j < 0x10; j += 2)
149                         snd_iprintf(buffer, " %04x",
150                                     oxygen_read_ac97(chip, 0, i + j));
151                 snd_iprintf(buffer, "\n");
152         }
153         mutex_unlock(&chip->mutex);
154 }
155
156 static void __devinit oxygen_proc_init(struct oxygen *chip)
157 {
158         struct snd_info_entry *entry;
159
160         if (!snd_card_proc_new(chip->card, "cmi8788", &entry))
161                 snd_info_set_text_ops(entry, chip, oxygen_proc_read);
162 }
163 #else
164 #define oxygen_proc_init(chip)
165 #endif
166
167 static void __devinit oxygen_init(struct oxygen *chip)
168 {
169         unsigned int i;
170
171         chip->dac_routing = 1;
172         for (i = 0; i < 8; ++i)
173                 chip->dac_volume[i] = 0xff;
174         chip->spdif_playback_enable = 1;
175         chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL |
176                 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
177         chip->spdif_pcm_bits = chip->spdif_bits;
178
179         if (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2)
180                 chip->revision = 2;
181         else
182                 chip->revision = 1;
183
184         if (chip->revision == 1)
185                 oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_MAGIC);
186
187         oxygen_set_bits8(chip, OXYGEN_FUNCTION,
188                          OXYGEN_FUNCTION_RESET_CODEC |
189                          OXYGEN_FUNCTION_ENABLE_SPI_4_5);
190         oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, 0x010a);
191         oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 0x010a);
192         oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 0x010a);
193         oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, 0x010a);
194         oxygen_set_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_MAGIC2);
195         oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits);
196         oxygen_write16(chip, OXYGEN_PLAY_ROUTING, 0xe100);
197         oxygen_write8(chip, OXYGEN_REC_ROUTING, 0x10);
198         oxygen_write8(chip, OXYGEN_ADC_MONITOR, 0x00);
199         oxygen_write8(chip, OXYGEN_A_MONITOR_ROUTING, 0xe4);
200
201         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
202         oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
203
204         oxygen_write8(chip, OXYGEN_AC97_INTERRUPT_MASK, 0x00);
205         oxygen_clear_bits16(chip, OXYGEN_AC97_OUT_CONFIG,
206                             OXYGEN_AC97_OUT_MAGIC3);
207         oxygen_set_bits16(chip, OXYGEN_AC97_IN_CONFIG,
208                           OXYGEN_AC97_IN_MAGIC3);
209         oxygen_write_ac97(chip, 0, AC97_RESET, 0);
210         msleep(1);
211         oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300);
212         oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043);
213         oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f);
214         oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000);
215         oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000);
216         oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808);
217         oxygen_write_ac97(chip, 0, AC97_LINE, 0x0808);
218         oxygen_write_ac97(chip, 0, AC97_CD, 0x8808);
219         oxygen_write_ac97(chip, 0, AC97_VIDEO, 0x8808);
220         oxygen_write_ac97(chip, 0, AC97_AUX, 0x8808);
221         oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000);
222         oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080);
223         oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080);
224         oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001);
225         /* power down unused ADCs and DACs */
226         oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN,
227                              AC97_PD_PR0 | AC97_PD_PR1);
228         oxygen_ac97_set_bits(chip, 0, AC97_EXTENDED_STATUS,
229                              AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK);
230 }
231
232 static void oxygen_card_free(struct snd_card *card)
233 {
234         struct oxygen *chip = card->private_data;
235
236         spin_lock_irq(&chip->reg_lock);
237         chip->interrupt_mask = 0;
238         chip->pcm_running = 0;
239         oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
240         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
241         spin_unlock_irq(&chip->reg_lock);
242         if (chip->irq >= 0) {
243                 free_irq(chip->irq, chip);
244                 synchronize_irq(chip->irq);
245         }
246         flush_scheduled_work();
247         chip->model->cleanup(chip);
248         mutex_destroy(&chip->mutex);
249         pci_release_regions(chip->pci);
250         pci_disable_device(chip->pci);
251 }
252
253 int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
254                                const struct oxygen_model *model)
255 {
256         struct snd_card *card;
257         struct oxygen *chip;
258         int err;
259
260         card = snd_card_new(index, id, model->owner, sizeof *chip);
261         if (!card)
262                 return -ENOMEM;
263
264         chip = card->private_data;
265         chip->card = card;
266         chip->pci = pci;
267         chip->irq = -1;
268         chip->model = model;
269         spin_lock_init(&chip->reg_lock);
270         mutex_init(&chip->mutex);
271         INIT_WORK(&chip->spdif_input_bits_work,
272                   oxygen_spdif_input_bits_changed);
273
274         err = pci_enable_device(pci);
275         if (err < 0)
276                 goto err_card;
277
278         err = pci_request_regions(pci, model->chip);
279         if (err < 0) {
280                 snd_printk(KERN_ERR "cannot reserve PCI resources\n");
281                 goto err_pci_enable;
282         }
283
284         if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) ||
285             pci_resource_len(pci, 0) < 0x100) {
286                 snd_printk(KERN_ERR "invalid PCI I/O range\n");
287                 err = -ENXIO;
288                 goto err_pci_regions;
289         }
290         chip->addr = pci_resource_start(pci, 0);
291
292         pci_set_master(pci);
293         snd_card_set_dev(card, &pci->dev);
294         card->private_free = oxygen_card_free;
295
296         oxygen_init(chip);
297         model->init(chip);
298
299         err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
300                           model->chip, chip);
301         if (err < 0) {
302                 snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
303                 goto err_card;
304         }
305         chip->irq = pci->irq;
306
307         strcpy(card->driver, model->chip);
308         strcpy(card->shortname, model->shortname);
309         sprintf(card->longname, "%s (rev %u) at %#lx, irq %i",
310                 model->longname, chip->revision, chip->addr, chip->irq);
311         strcpy(card->mixername, model->chip);
312         snd_component_add(card, model->chip);
313
314         err = oxygen_pcm_init(chip);
315         if (err < 0)
316                 goto err_card;
317
318         err = oxygen_mixer_init(chip);
319         if (err < 0)
320                 goto err_card;
321
322         if (oxygen_read8(chip, OXYGEN_MISC) & OXYGEN_MISC_MIDI) {
323                 err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
324                                           chip->addr + OXYGEN_MPU401,
325                                           MPU401_INFO_INTEGRATED, 0, 0,
326                                           &chip->midi);
327                 if (err < 0)
328                         goto err_card;
329         }
330
331         oxygen_proc_init(chip);
332
333         spin_lock_irq(&chip->reg_lock);
334         chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_CHANGE;
335         oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
336         spin_unlock_irq(&chip->reg_lock);
337
338         err = snd_card_register(card);
339         if (err < 0)
340                 goto err_card;
341
342         pci_set_drvdata(pci, card);
343         return 0;
344
345 err_pci_regions:
346         pci_release_regions(pci);
347 err_pci_enable:
348         pci_disable_device(pci);
349 err_card:
350         snd_card_free(card);
351         return err;
352 }
353 EXPORT_SYMBOL(oxygen_pci_probe);
354
355 void __devexit oxygen_pci_remove(struct pci_dev *pci)
356 {
357         snd_card_free(pci_get_drvdata(pci));
358         pci_set_drvdata(pci, NULL);
359 }
360 EXPORT_SYMBOL(oxygen_pci_remove);