vserver 1.9.3
[linux-2.6.git] / sound / isa / ad1848 / ad1848_lib.c
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3  *  Routines for control of AD1848/AD1847/CS4248
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21
22 #define SNDRV_MAIN_OBJECT_FILE
23 #include <sound/driver.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/pm.h>
28 #include <linux/slab.h>
29 #include <linux/ioport.h>
30 #include <sound/core.h>
31 #include <sound/ad1848.h>
32 #include <sound/control.h>
33 #include <sound/pcm_params.h>
34
35 #include <asm/io.h>
36 #include <asm/dma.h>
37
38 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
39 MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248");
40 MODULE_LICENSE("GPL");
41
42 #if 0
43 #define SNDRV_DEBUG_MCE
44 #endif
45
46 /*
47  *  Some variables
48  */
49
50 static unsigned char freq_bits[14] = {
51         /* 5510 */      0x00 | AD1848_XTAL2,
52         /* 6620 */      0x0E | AD1848_XTAL2,
53         /* 8000 */      0x00 | AD1848_XTAL1,
54         /* 9600 */      0x0E | AD1848_XTAL1,
55         /* 11025 */     0x02 | AD1848_XTAL2,
56         /* 16000 */     0x02 | AD1848_XTAL1,
57         /* 18900 */     0x04 | AD1848_XTAL2,
58         /* 22050 */     0x06 | AD1848_XTAL2,
59         /* 27042 */     0x04 | AD1848_XTAL1,
60         /* 32000 */     0x06 | AD1848_XTAL1,
61         /* 33075 */     0x0C | AD1848_XTAL2,
62         /* 37800 */     0x08 | AD1848_XTAL2,
63         /* 44100 */     0x0A | AD1848_XTAL2,
64         /* 48000 */     0x0C | AD1848_XTAL1
65 };
66
67 static unsigned int rates[14] = {
68         5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
69         27042, 32000, 33075, 37800, 44100, 48000
70 };
71
72 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
73         .count = 14,
74         .list = rates,
75         .mask = 0,
76 };
77
78 static unsigned char snd_ad1848_original_image[16] =
79 {
80         0x00,                   /* 00 - lic */
81         0x00,                   /* 01 - ric */
82         0x9f,                   /* 02 - la1ic */
83         0x9f,                   /* 03 - ra1ic */
84         0x9f,                   /* 04 - la2ic */
85         0x9f,                   /* 05 - ra2ic */
86         0xbf,                   /* 06 - loc */
87         0xbf,                   /* 07 - roc */
88         0x20,                   /* 08 - dfr */
89         AD1848_AUTOCALIB,       /* 09 - ic */
90         0x00,                   /* 0a - pc */
91         0x00,                   /* 0b - ti */
92         0x00,                   /* 0c - mi */
93         0x00,                   /* 0d - lbc */
94         0x00,                   /* 0e - dru */
95         0x00,                   /* 0f - drl */
96 };
97
98 /*
99  *  Basic I/O functions
100  */
101
102 void snd_ad1848_out(ad1848_t *chip,
103                            unsigned char reg,
104                            unsigned char value)
105 {
106         int timeout;
107
108         for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
109                 udelay(100);
110 #ifdef CONFIG_SND_DEBUG
111         if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
112                 snd_printk("auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
113 #endif
114         outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
115         outb(chip->image[reg] = value, AD1848P(chip, REG));
116         mb();
117 #if 0
118         printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
119 #endif
120 }
121
122 void snd_ad1848_dout(ad1848_t *chip,
123                      unsigned char reg,
124                      unsigned char value)
125 {
126         int timeout;
127
128         for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
129                 udelay(100);
130         outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
131         outb(value, AD1848P(chip, REG));
132         mb();
133 }
134
135 unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
136 {
137         int timeout;
138
139         for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
140                 udelay(100);
141 #ifdef CONFIG_SND_DEBUG
142         if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
143                 snd_printk("auto calibration time out - reg = 0x%x\n", reg);
144 #endif
145         outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
146         mb();
147         return inb(AD1848P(chip, REG));
148 }
149
150 #ifdef CONFIG_SND_DEBUG
151
152 void snd_ad1848_debug(ad1848_t *chip)
153 {
154         printk("AD1848 REGS:      INDEX = 0x%02x  ", inb(AD1848P(chip, REGSEL)));
155         printk("                 STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS)));
156         printk("  0x00: left input      = 0x%02x  ", snd_ad1848_in(chip, 0x00));
157         printk("  0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08));
158         printk("  0x01: right input     = 0x%02x  ", snd_ad1848_in(chip, 0x01));
159         printk("  0x09: iface (CFIG 1)  = 0x%02x\n", snd_ad1848_in(chip, 0x09));
160         printk("  0x02: AUXA left       = 0x%02x  ", snd_ad1848_in(chip, 0x02));
161         printk("  0x0a: pin control     = 0x%02x\n", snd_ad1848_in(chip, 0x0a));
162         printk("  0x03: AUXA right      = 0x%02x  ", snd_ad1848_in(chip, 0x03));
163         printk("  0x0b: init & status   = 0x%02x\n", snd_ad1848_in(chip, 0x0b));
164         printk("  0x04: AUXB left       = 0x%02x  ", snd_ad1848_in(chip, 0x04));
165         printk("  0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c));
166         printk("  0x05: AUXB right      = 0x%02x  ", snd_ad1848_in(chip, 0x05));
167         printk("  0x0d: loopback        = 0x%02x\n", snd_ad1848_in(chip, 0x0d));
168         printk("  0x06: left output     = 0x%02x  ", snd_ad1848_in(chip, 0x06));
169         printk("  0x0e: data upr count  = 0x%02x\n", snd_ad1848_in(chip, 0x0e));
170         printk("  0x07: right output    = 0x%02x  ", snd_ad1848_in(chip, 0x07));
171         printk("  0x0f: data lwr count  = 0x%02x\n", snd_ad1848_in(chip, 0x0f));
172 }
173
174 #endif
175
176 /*
177  *  AD1848 detection / MCE routines
178  */
179
180 void snd_ad1848_mce_up(ad1848_t *chip)
181 {
182         unsigned long flags;
183         int timeout;
184
185         for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
186                 udelay(100);
187 #ifdef CONFIG_SND_DEBUG
188         if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
189                 snd_printk("mce_up - auto calibration time out (0)\n");
190 #endif
191         spin_lock_irqsave(&chip->reg_lock, flags);
192         chip->mce_bit |= AD1848_MCE;
193         timeout = inb(AD1848P(chip, REGSEL));
194         if (timeout == 0x80)
195                 snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
196         if (!(timeout & AD1848_MCE))
197                 outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
198         spin_unlock_irqrestore(&chip->reg_lock, flags);
199 }
200
201 void snd_ad1848_mce_down(ad1848_t *chip)
202 {
203         unsigned long flags;
204         int timeout;
205         signed long time;
206
207         spin_lock_irqsave(&chip->reg_lock, flags);
208         for (timeout = 5; timeout > 0; timeout--)
209                 inb(AD1848P(chip, REGSEL));
210         /* end of cleanup sequence */
211         for (timeout = 12000; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
212                 udelay(100);
213 #if 0
214         printk("(1) timeout = %i\n", timeout);
215 #endif
216 #ifdef CONFIG_SND_DEBUG
217         if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
218                 snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
219 #endif
220         chip->mce_bit &= ~AD1848_MCE;
221         timeout = inb(AD1848P(chip, REGSEL));
222         outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
223         if (timeout == 0x80)
224                 snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
225         if ((timeout & AD1848_MCE) == 0) {
226                 spin_unlock_irqrestore(&chip->reg_lock, flags);
227                 return;
228         }
229         /* calibration process */
230
231         for (timeout = 500; timeout > 0 && (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) == 0; timeout--);
232         if ((snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) == 0) {
233                 snd_printd("mce_down - auto calibration time out (1)\n");
234                 spin_unlock_irqrestore(&chip->reg_lock, flags);
235                 return;
236         }
237 #if 0
238         printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
239 #endif
240         time = HZ / 4;
241         while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
242                 spin_unlock_irqrestore(&chip->reg_lock, flags);
243                 if (time <= 0) {
244                         snd_printk("mce_down - auto calibration time out (2)\n");
245                         return;
246                 }
247                 set_current_state(TASK_INTERRUPTIBLE);
248                 time = schedule_timeout(time);
249                 spin_lock_irqsave(&chip->reg_lock, flags);
250         }
251 #if 0
252         printk("(3) jiffies = %li\n", jiffies);
253 #endif
254         time = HZ / 10;
255         while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) {
256                 spin_unlock_irqrestore(&chip->reg_lock, flags);
257                 if (time <= 0) {
258                         snd_printk("mce_down - auto calibration time out (3)\n");
259                         return;
260                 }
261                 set_current_state(TASK_INTERRUPTIBLE);
262                 time = schedule_timeout(time);
263                 spin_lock_irqsave(&chip->reg_lock, flags);
264         }
265         spin_unlock_irqrestore(&chip->reg_lock, flags);
266 #if 0
267         printk("(4) jiffies = %li\n", jiffies);
268         snd_printk("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL)));
269 #endif
270 }
271
272 static unsigned int snd_ad1848_get_count(unsigned char format,
273                                          unsigned int size)
274 {
275         switch (format & 0xe0) {
276         case AD1848_LINEAR_16:
277                 size >>= 1;
278                 break;
279         }
280         if (format & AD1848_STEREO)
281                 size >>= 1;
282         return size;
283 }
284
285 static int snd_ad1848_trigger(ad1848_t *chip, unsigned char what,
286                               int channel, int cmd)
287 {
288         int result = 0;
289
290 #if 0
291         printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(AD1848P(card, STATUS)));
292 #endif
293         spin_lock(&chip->reg_lock);
294         if (cmd == SNDRV_PCM_TRIGGER_START) {
295                 if (chip->image[AD1848_IFACE_CTRL] & what) {
296                         spin_unlock(&chip->reg_lock);
297                         return 0;
298                 }
299                 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what);
300                 chip->mode |= AD1848_MODE_RUNNING;
301         } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
302                 if (!(chip->image[AD1848_IFACE_CTRL] & what)) {
303                         spin_unlock(&chip->reg_lock);
304                         return 0;
305                 }
306                 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what);
307                 chip->mode &= ~AD1848_MODE_RUNNING;
308         } else {
309                 result = -EINVAL;
310         }
311         spin_unlock(&chip->reg_lock);
312         return result;
313 }
314
315 /*
316  *  CODEC I/O
317  */
318
319 static unsigned char snd_ad1848_get_rate(unsigned int rate)
320 {
321         int i;
322
323         for (i = 0; i < 14; i++)
324                 if (rate == rates[i])
325                         return freq_bits[i];
326         snd_BUG();
327         return freq_bits[13];
328 }
329
330 static int snd_ad1848_ioctl(snd_pcm_substream_t * substream,
331                             unsigned int cmd, void *arg)
332 {
333         return snd_pcm_lib_ioctl(substream, cmd, arg);
334 }
335
336 static unsigned char snd_ad1848_get_format(int format, int channels)
337 {
338         unsigned char rformat;
339
340         rformat = AD1848_LINEAR_8;
341         switch (format) {
342         case SNDRV_PCM_FORMAT_A_LAW:    rformat = AD1848_ALAW_8; break;
343         case SNDRV_PCM_FORMAT_MU_LAW:   rformat = AD1848_ULAW_8; break;
344         case SNDRV_PCM_FORMAT_S16_LE:   rformat = AD1848_LINEAR_16; break;
345         }
346         if (channels > 1)
347                 rformat |= AD1848_STEREO;
348 #if 0
349         snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
350 #endif
351         return rformat;
352 }
353
354 static void snd_ad1848_calibrate_mute(ad1848_t *chip, int mute)
355 {
356         unsigned long flags;
357         
358         mute = mute ? 1 : 0;
359         spin_lock_irqsave(&chip->reg_lock, flags);
360         if (chip->calibrate_mute == mute) {
361                 spin_unlock_irqrestore(&chip->reg_lock, flags);
362                 return;
363         }
364         if (!mute) {
365                 snd_ad1848_dout(chip, AD1848_LEFT_INPUT, chip->image[AD1848_LEFT_INPUT]);
366                 snd_ad1848_dout(chip, AD1848_RIGHT_INPUT, chip->image[AD1848_RIGHT_INPUT]);
367         }
368         snd_ad1848_dout(chip, AD1848_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_LEFT_INPUT]);
369         snd_ad1848_dout(chip, AD1848_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_RIGHT_INPUT]);
370         snd_ad1848_dout(chip, AD1848_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_LEFT_INPUT]);
371         snd_ad1848_dout(chip, AD1848_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_RIGHT_INPUT]);
372         snd_ad1848_dout(chip, AD1848_LEFT_OUTPUT, mute ? 0x80 : chip->image[AD1848_LEFT_OUTPUT]);
373         snd_ad1848_dout(chip, AD1848_RIGHT_OUTPUT, mute ? 0x80 : chip->image[AD1848_RIGHT_OUTPUT]);
374         chip->calibrate_mute = mute;
375         spin_unlock_irqrestore(&chip->reg_lock, flags);
376 }
377
378 static void snd_ad1848_set_data_format(ad1848_t *chip, snd_pcm_hw_params_t *hw_params)
379 {
380         if (hw_params == NULL) {
381                 chip->image[AD1848_DATA_FORMAT] = 0x20;
382         } else {
383                 chip->image[AD1848_DATA_FORMAT] =
384                     snd_ad1848_get_format(params_format(hw_params), params_channels(hw_params)) |
385                     snd_ad1848_get_rate(params_rate(hw_params));
386         }
387         // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]);
388 }
389
390 static int snd_ad1848_open(ad1848_t *chip, unsigned int mode)
391 {
392         unsigned long flags;
393
394         down(&chip->open_mutex);
395         if (chip->mode & AD1848_MODE_OPEN) {
396                 up(&chip->open_mutex);
397                 return -EAGAIN;
398         }
399         snd_ad1848_mce_down(chip);
400
401 #ifdef SNDRV_DEBUG_MCE
402         snd_printk("open: (1)\n");
403 #endif
404         snd_ad1848_mce_up(chip);
405         spin_lock_irqsave(&chip->reg_lock, flags);
406         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
407                              AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO |
408                              AD1848_CALIB_MODE);
409         chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB;
410         snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
411         spin_unlock_irqrestore(&chip->reg_lock, flags);
412         snd_ad1848_mce_down(chip);
413
414 #ifdef SNDRV_DEBUG_MCE
415         snd_printk("open: (2)\n");
416 #endif
417
418         snd_ad1848_set_data_format(chip, NULL);
419
420         snd_ad1848_mce_up(chip);
421         spin_lock_irqsave(&chip->reg_lock, flags);
422         snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
423         spin_unlock_irqrestore(&chip->reg_lock, flags);
424         snd_ad1848_mce_down(chip);
425
426 #ifdef SNDRV_DEBUG_MCE
427         snd_printk("open: (3)\n");
428 #endif
429
430         /* ok. now enable and ack CODEC IRQ */
431         spin_lock_irqsave(&chip->reg_lock, flags);
432         outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
433         outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
434         chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE;
435         snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
436         spin_unlock_irqrestore(&chip->reg_lock, flags);
437
438         chip->mode = mode;
439         up(&chip->open_mutex);
440
441         return 0;
442 }
443
444 static void snd_ad1848_close(ad1848_t *chip)
445 {
446         unsigned long flags;
447
448         down(&chip->open_mutex);
449         if (!chip->mode) {
450                 up(&chip->open_mutex);
451                 return;
452         }
453         /* disable IRQ */
454         spin_lock_irqsave(&chip->reg_lock, flags);
455         outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
456         outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
457         chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE;
458         snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
459         spin_unlock_irqrestore(&chip->reg_lock, flags);
460
461         /* now disable capture & playback */
462
463         snd_ad1848_mce_up(chip);
464         spin_lock_irqsave(&chip->reg_lock, flags);
465         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
466                              AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
467         snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
468         spin_unlock_irqrestore(&chip->reg_lock, flags);
469         snd_ad1848_mce_down(chip);
470
471         /* clear IRQ again */
472         spin_lock_irqsave(&chip->reg_lock, flags);
473         outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
474         outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
475         spin_unlock_irqrestore(&chip->reg_lock, flags);
476
477         chip->mode = 0;
478         up(&chip->open_mutex);
479 }
480
481 /*
482  *  ok.. exported functions..
483  */
484
485 static int snd_ad1848_playback_trigger(snd_pcm_substream_t * substream,
486                                        int cmd)
487 {
488         ad1848_t *chip = snd_pcm_substream_chip(substream);
489         return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd);
490 }
491
492 static int snd_ad1848_capture_trigger(snd_pcm_substream_t * substream,
493                                       int cmd)
494 {
495         ad1848_t *chip = snd_pcm_substream_chip(substream);
496         return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd);
497 }
498
499 static int snd_ad1848_playback_hw_params(snd_pcm_substream_t * substream,
500                                          snd_pcm_hw_params_t * hw_params)
501 {
502         ad1848_t *chip = snd_pcm_substream_chip(substream);
503         unsigned long flags;
504         int err;
505
506         if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
507                 return err;
508         snd_ad1848_calibrate_mute(chip, 1);
509         snd_ad1848_set_data_format(chip, hw_params);
510         snd_ad1848_mce_up(chip);
511         spin_lock_irqsave(&chip->reg_lock, flags);
512         snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
513         spin_unlock_irqrestore(&chip->reg_lock, flags);
514         snd_ad1848_mce_down(chip);
515         snd_ad1848_calibrate_mute(chip, 0);
516         return 0;
517 }
518
519 static int snd_ad1848_playback_hw_free(snd_pcm_substream_t * substream)
520 {
521         return snd_pcm_lib_free_pages(substream);
522 }
523
524 static int snd_ad1848_playback_prepare(snd_pcm_substream_t * substream)
525 {
526         ad1848_t *chip = snd_pcm_substream_chip(substream);
527         snd_pcm_runtime_t *runtime = substream->runtime;
528         unsigned long flags;
529         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
530         unsigned int count = snd_pcm_lib_period_bytes(substream);
531
532         chip->dma_size = size;
533         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO);
534         snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
535         count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
536         spin_lock_irqsave(&chip->reg_lock, flags);
537         snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
538         snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
539         spin_unlock_irqrestore(&chip->reg_lock, flags);
540         return 0;
541 }
542
543 static int snd_ad1848_capture_hw_params(snd_pcm_substream_t * substream,
544                                         snd_pcm_hw_params_t * hw_params)
545 {
546         ad1848_t *chip = snd_pcm_substream_chip(substream);
547         unsigned long flags;
548         int err;
549
550         if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
551                 return err;
552         snd_ad1848_calibrate_mute(chip, 1);
553         snd_ad1848_set_data_format(chip, hw_params);
554         snd_ad1848_mce_up(chip);
555         spin_lock_irqsave(&chip->reg_lock, flags);
556         snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
557         spin_unlock_irqrestore(&chip->reg_lock, flags);
558         snd_ad1848_mce_down(chip);
559         snd_ad1848_calibrate_mute(chip, 0);
560         return 0;
561 }
562
563 static int snd_ad1848_capture_hw_free(snd_pcm_substream_t * substream)
564 {
565         return snd_pcm_lib_free_pages(substream);
566 }
567
568 static int snd_ad1848_capture_prepare(snd_pcm_substream_t * substream)
569 {
570         ad1848_t *chip = snd_pcm_substream_chip(substream);
571         snd_pcm_runtime_t *runtime = substream->runtime;
572         unsigned long flags;
573         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
574         unsigned int count = snd_pcm_lib_period_bytes(substream);
575
576         chip->dma_size = size;
577         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
578         snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
579         count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
580         spin_lock_irqsave(&chip->reg_lock, flags);
581         snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
582         snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
583         spin_unlock_irqrestore(&chip->reg_lock, flags);
584         return 0;
585 }
586
587 irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
588 {
589         ad1848_t *chip = dev_id;
590
591         if ((chip->mode & AD1848_MODE_PLAY) && chip->playback_substream &&
592             (chip->mode & AD1848_MODE_RUNNING))
593                 snd_pcm_period_elapsed(chip->playback_substream);
594         if ((chip->mode & AD1848_MODE_CAPTURE) && chip->capture_substream &&
595             (chip->mode & AD1848_MODE_RUNNING))
596                 snd_pcm_period_elapsed(chip->capture_substream);
597         outb(0, AD1848P(chip, STATUS)); /* clear global interrupt bit */
598         return IRQ_HANDLED;
599 }
600
601 static snd_pcm_uframes_t snd_ad1848_playback_pointer(snd_pcm_substream_t * substream)
602 {
603         ad1848_t *chip = snd_pcm_substream_chip(substream);
604         size_t ptr;
605         
606         if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
607                 return 0;
608         ptr = snd_dma_pointer(chip->dma, chip->dma_size);
609         return bytes_to_frames(substream->runtime, ptr);
610 }
611
612 static snd_pcm_uframes_t snd_ad1848_capture_pointer(snd_pcm_substream_t * substream)
613 {
614         ad1848_t *chip = snd_pcm_substream_chip(substream);
615         size_t ptr;
616
617         if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
618                 return 0;
619         ptr = snd_dma_pointer(chip->dma, chip->dma_size);
620         return bytes_to_frames(substream->runtime, ptr);
621 }
622
623 /*
624
625  */
626
627 static void snd_ad1848_thinkpad_twiddle(ad1848_t *chip, int on) {
628
629         int tmp;
630
631         if (!chip->thinkpad_flag) return;
632
633         outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
634         tmp = inb(AD1848_THINKPAD_CTL_PORT2);
635
636         if (on)
637                 /* turn it on */
638                 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
639         else
640                 /* turn it off */
641                 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
642         
643         outb(tmp, AD1848_THINKPAD_CTL_PORT2);
644
645 }
646
647 #ifdef CONFIG_PM
648 static int snd_ad1848_suspend(snd_card_t *card, unsigned int state)
649 {
650         ad1848_t *chip = card->pm_private_data;
651
652         if (card->power_state == SNDRV_CTL_POWER_D3hot)
653                 return 0;
654
655         snd_pcm_suspend_all(chip->pcm);
656         /* FIXME: save registers? */
657
658         if (chip->thinkpad_flag)
659                 snd_ad1848_thinkpad_twiddle(chip, 0);
660
661         snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
662         return 0;
663 }
664
665 static int snd_ad1848_resume(snd_card_t *card, unsigned int state)
666 {
667         ad1848_t *chip = card->pm_private_data;
668
669         if (card->power_state == SNDRV_CTL_POWER_D0)
670                 return 0;
671
672         if (chip->thinkpad_flag)
673                 snd_ad1848_thinkpad_twiddle(chip, 1);
674
675         /* FIXME: restore registers? */
676
677         snd_power_change_state(card, SNDRV_CTL_POWER_D0);
678         return 0;
679 }
680 #endif /* CONFIG_PM */
681
682 static int snd_ad1848_probe(ad1848_t * chip)
683 {
684         unsigned long flags;
685         int i, id, rev, ad1847;
686         unsigned char *ptr;
687
688 #if 0
689         snd_ad1848_debug(chip);
690 #endif
691         id = ad1847 = 0;
692         for (i = 0; i < 1000; i++) {
693                 mb();
694                 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
695                         udelay(500);
696                 else {
697                         spin_lock_irqsave(&chip->reg_lock, flags);
698                         snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
699                         snd_ad1848_out(chip, AD1848_LEFT_INPUT, 0xaa);
700                         snd_ad1848_out(chip, AD1848_RIGHT_INPUT, 0x45);
701                         rev = snd_ad1848_in(chip, AD1848_RIGHT_INPUT);
702                         if (rev == 0x65) {
703                                 spin_unlock_irqrestore(&chip->reg_lock, flags);
704                                 id = 1;
705                                 ad1847 = 1;
706                                 break;
707                         }
708                         if (snd_ad1848_in(chip, AD1848_LEFT_INPUT) == 0xaa && rev == 0x45) {
709                                 spin_unlock_irqrestore(&chip->reg_lock, flags);
710                                 id = 1;
711                                 break;
712                         }
713                         spin_unlock_irqrestore(&chip->reg_lock, flags);
714                 }
715         }
716         if (id != 1)
717                 return -ENODEV; /* no valid device found */
718         if (chip->hardware == AD1848_HW_DETECT) {
719                 if (ad1847) {
720                         chip->hardware = AD1848_HW_AD1847;
721                 } else {
722                         chip->hardware = AD1848_HW_AD1848;
723                         rev = snd_ad1848_in(chip, AD1848_MISC_INFO);
724                         if (rev & 0x80) {
725                                 chip->hardware = AD1848_HW_CS4248;
726                         } else if ((rev & 0x0f) == 0x0a) {
727                                 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x40);
728                                 for (i = 0; i < 16; ++i) {
729                                         if (snd_ad1848_in(chip, i) != snd_ad1848_in(chip, i + 16)) {
730                                                 chip->hardware = AD1848_HW_CMI8330;
731                                                 break;
732                                         }
733                                 }
734                                 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
735                         }
736                 }
737         }
738         spin_lock_irqsave(&chip->reg_lock, flags);
739         inb(AD1848P(chip, STATUS));     /* clear any pendings IRQ */
740         outb(0, AD1848P(chip, STATUS));
741         mb();
742         spin_unlock_irqrestore(&chip->reg_lock, flags);
743
744         chip->image[AD1848_MISC_INFO] = 0x00;
745         chip->image[AD1848_IFACE_CTRL] =
746             (chip->image[AD1848_IFACE_CTRL] & ~AD1848_SINGLE_DMA) | AD1848_SINGLE_DMA;
747         ptr = (unsigned char *) &chip->image;
748         snd_ad1848_mce_down(chip);
749         spin_lock_irqsave(&chip->reg_lock, flags);
750         for (i = 0; i < 16; i++)        /* ok.. fill all AD1848 registers */
751                 snd_ad1848_out(chip, i, *ptr++);
752         spin_unlock_irqrestore(&chip->reg_lock, flags);
753         snd_ad1848_mce_up(chip);
754         snd_ad1848_mce_down(chip);
755         return 0;               /* all things are ok.. */
756 }
757
758 /*
759
760  */
761
762 static snd_pcm_hardware_t snd_ad1848_playback =
763 {
764         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
765                                  SNDRV_PCM_INFO_MMAP_VALID),
766         .formats =              (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
767                                  SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
768         .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
769         .rate_min =             5510,
770         .rate_max =             48000,
771         .channels_min =         1,
772         .channels_max =         2,
773         .buffer_bytes_max =     (128*1024),
774         .period_bytes_min =     64,
775         .period_bytes_max =     (128*1024),
776         .periods_min =          1,
777         .periods_max =          1024,
778         .fifo_size =            0,
779 };
780
781 static snd_pcm_hardware_t snd_ad1848_capture =
782 {
783         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
784                                  SNDRV_PCM_INFO_MMAP_VALID),
785         .formats =              (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
786                                  SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
787         .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
788         .rate_min =             5510,
789         .rate_max =             48000,
790         .channels_min =         1,
791         .channels_max =         2,
792         .buffer_bytes_max =     (128*1024),
793         .period_bytes_min =     64,
794         .period_bytes_max =     (128*1024),
795         .periods_min =          1,
796         .periods_max =          1024,
797         .fifo_size =            0,
798 };
799
800 /*
801
802  */
803
804 static int snd_ad1848_playback_open(snd_pcm_substream_t * substream)
805 {
806         ad1848_t *chip = snd_pcm_substream_chip(substream);
807         snd_pcm_runtime_t *runtime = substream->runtime;
808         int err;
809
810         if ((err = snd_ad1848_open(chip, AD1848_MODE_PLAY)) < 0)
811                 return err;
812         chip->playback_substream = substream;
813         runtime->hw = snd_ad1848_playback;
814         snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max);
815         snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max);
816         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
817         return 0;
818 }
819
820 static int snd_ad1848_capture_open(snd_pcm_substream_t * substream)
821 {
822         ad1848_t *chip = snd_pcm_substream_chip(substream);
823         snd_pcm_runtime_t *runtime = substream->runtime;
824         int err;
825
826         if ((err = snd_ad1848_open(chip, AD1848_MODE_CAPTURE)) < 0)
827                 return err;
828         chip->capture_substream = substream;
829         runtime->hw = snd_ad1848_capture;
830         snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max);
831         snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max);
832         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
833         return 0;
834 }
835
836 static int snd_ad1848_playback_close(snd_pcm_substream_t * substream)
837 {
838         ad1848_t *chip = snd_pcm_substream_chip(substream);
839
840         chip->mode &= ~AD1848_MODE_PLAY;
841         chip->playback_substream = NULL;
842         snd_ad1848_close(chip);
843         return 0;
844 }
845
846 static int snd_ad1848_capture_close(snd_pcm_substream_t * substream)
847 {
848         ad1848_t *chip = snd_pcm_substream_chip(substream);
849
850         chip->mode &= ~AD1848_MODE_CAPTURE;
851         chip->capture_substream = NULL;
852         snd_ad1848_close(chip);
853         return 0;
854 }
855
856 static int snd_ad1848_free(ad1848_t *chip)
857 {
858         if (chip->res_port) {
859                 release_resource(chip->res_port);
860                 kfree_nocheck(chip->res_port);
861         }
862         if (chip->irq >= 0)
863                 free_irq(chip->irq, (void *) chip);
864         if (chip->dma >= 0) {
865                 snd_dma_disable(chip->dma);
866                 free_dma(chip->dma);
867         }
868         kfree(chip);
869         return 0;
870 }
871
872 static int snd_ad1848_dev_free(snd_device_t *device)
873 {
874         ad1848_t *chip = device->device_data;
875         return snd_ad1848_free(chip);
876 }
877
878 static const char *snd_ad1848_chip_id(ad1848_t *chip)
879 {
880         switch (chip->hardware) {
881         case AD1848_HW_AD1847:  return "AD1847";
882         case AD1848_HW_AD1848:  return "AD1848";
883         case AD1848_HW_CS4248:  return "CS4248";
884         case AD1848_HW_CMI8330: return "CMI8330/C3D";
885         default:                return "???";
886         }
887 }
888
889 int snd_ad1848_create(snd_card_t * card,
890                       unsigned long port,
891                       int irq, int dma,
892                       unsigned short hardware,
893                       ad1848_t ** rchip)
894 {
895         static snd_device_ops_t ops = {
896                 .dev_free =     snd_ad1848_dev_free,
897         };
898         ad1848_t *chip;
899         int err;
900
901         *rchip = NULL;
902         chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
903         if (chip == NULL)
904                 return -ENOMEM;
905         spin_lock_init(&chip->reg_lock);
906         init_MUTEX(&chip->open_mutex);
907         chip->card = card;
908         chip->port = port;
909         chip->irq = -1;
910         chip->dma = -1;
911         chip->hardware = hardware;
912         memcpy(&chip->image, &snd_ad1848_original_image, sizeof(snd_ad1848_original_image));
913         
914         if ((chip->res_port = request_region(port, 4, "AD1848")) == NULL) {
915                 snd_printk(KERN_ERR "ad1848: can't grab port 0x%lx\n", port);
916                 snd_ad1848_free(chip);
917                 return -EBUSY;
918         }
919         if (request_irq(irq, snd_ad1848_interrupt, SA_INTERRUPT, "AD1848", (void *) chip)) {
920                 snd_printk(KERN_ERR "ad1848: can't grab IRQ %d\n", irq);
921                 snd_ad1848_free(chip);
922                 return -EBUSY;
923         }
924         chip->irq = irq;
925         if (request_dma(dma, "AD1848")) {
926                 snd_printk(KERN_ERR "ad1848: can't grab DMA %d\n", dma);
927                 snd_ad1848_free(chip);
928                 return -EBUSY;
929         }
930         chip->dma = dma;
931
932         if (hardware == AD1848_HW_THINKPAD) {
933                 chip->thinkpad_flag = 1;
934                 chip->hardware = AD1848_HW_DETECT; /* reset */
935                 snd_ad1848_thinkpad_twiddle(chip, 1);
936                 snd_card_set_isa_pm_callback(card, snd_ad1848_suspend, snd_ad1848_resume, chip);
937         }
938
939         if (snd_ad1848_probe(chip) < 0) {
940                 snd_ad1848_free(chip);
941                 return -ENODEV;
942         }
943
944         /* Register device */
945         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
946                 snd_ad1848_free(chip);
947                 return err;
948         }
949
950         *rchip = chip;
951         return 0;
952 }
953
954 static snd_pcm_ops_t snd_ad1848_playback_ops = {
955         .open =         snd_ad1848_playback_open,
956         .close =        snd_ad1848_playback_close,
957         .ioctl =        snd_ad1848_ioctl,
958         .hw_params =    snd_ad1848_playback_hw_params,
959         .hw_free =      snd_ad1848_playback_hw_free,
960         .prepare =      snd_ad1848_playback_prepare,
961         .trigger =      snd_ad1848_playback_trigger,
962         .pointer =      snd_ad1848_playback_pointer,
963 };
964
965 static snd_pcm_ops_t snd_ad1848_capture_ops = {
966         .open =         snd_ad1848_capture_open,
967         .close =        snd_ad1848_capture_close,
968         .ioctl =        snd_ad1848_ioctl,
969         .hw_params =    snd_ad1848_capture_hw_params,
970         .hw_free =      snd_ad1848_capture_hw_free,
971         .prepare =      snd_ad1848_capture_prepare,
972         .trigger =      snd_ad1848_capture_trigger,
973         .pointer =      snd_ad1848_capture_pointer,
974 };
975
976 static void snd_ad1848_pcm_free(snd_pcm_t *pcm)
977 {
978         ad1848_t *chip = pcm->private_data;
979         chip->pcm = NULL;
980         snd_pcm_lib_preallocate_free_for_all(pcm);
981 }
982
983 int snd_ad1848_pcm(ad1848_t *chip, int device, snd_pcm_t **rpcm)
984 {
985         snd_pcm_t *pcm;
986         int err;
987
988         if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0)
989                 return err;
990
991         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops);
992         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops);
993
994         pcm->private_free = snd_ad1848_pcm_free;
995         pcm->private_data = chip;
996         pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
997         strcpy(pcm->name, snd_ad1848_chip_id(chip));
998
999         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1000                                               snd_dma_isa_data(),
1001                                               64*1024, chip->dma > 3 ? 128*1024 : 64*1024);
1002
1003         chip->pcm = pcm;
1004         if (rpcm)
1005                 *rpcm = pcm;
1006         return 0;
1007 }
1008
1009 const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction)
1010 {
1011         return direction == SNDRV_PCM_STREAM_PLAYBACK ?
1012                 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
1013 }
1014
1015 /*
1016  *  MIXER part
1017  */
1018
1019 static int snd_ad1848_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1020 {
1021         static char *texts[4] = {
1022                 "Line", "Aux", "Mic", "Mix"
1023         };
1024
1025         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1026         uinfo->count = 2;
1027         uinfo->value.enumerated.items = 4;
1028         if (uinfo->value.enumerated.item > 3)
1029                 uinfo->value.enumerated.item = 3;
1030         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1031         return 0;
1032 }
1033
1034 static int snd_ad1848_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1035 {
1036         ad1848_t *chip = snd_kcontrol_chip(kcontrol);
1037         unsigned long flags;
1038         
1039         spin_lock_irqsave(&chip->reg_lock, flags);
1040         ucontrol->value.enumerated.item[0] = (chip->image[AD1848_LEFT_INPUT] & AD1848_MIXS_ALL) >> 6;
1041         ucontrol->value.enumerated.item[1] = (chip->image[AD1848_RIGHT_INPUT] & AD1848_MIXS_ALL) >> 6;
1042         spin_unlock_irqrestore(&chip->reg_lock, flags);
1043         return 0;
1044 }
1045
1046 static int snd_ad1848_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1047 {
1048         ad1848_t *chip = snd_kcontrol_chip(kcontrol);
1049         unsigned long flags;
1050         unsigned short left, right;
1051         int change;
1052         
1053         if (ucontrol->value.enumerated.item[0] > 3 ||
1054             ucontrol->value.enumerated.item[1] > 3)
1055                 return -EINVAL;
1056         left = ucontrol->value.enumerated.item[0] << 6;
1057         right = ucontrol->value.enumerated.item[1] << 6;
1058         spin_lock_irqsave(&chip->reg_lock, flags);
1059         left = (chip->image[AD1848_LEFT_INPUT] & ~AD1848_MIXS_ALL) | left;
1060         right = (chip->image[AD1848_RIGHT_INPUT] & ~AD1848_MIXS_ALL) | right;
1061         change = left != chip->image[AD1848_LEFT_INPUT] ||
1062                  right != chip->image[AD1848_RIGHT_INPUT];
1063         snd_ad1848_out(chip, AD1848_LEFT_INPUT, left);
1064         snd_ad1848_out(chip, AD1848_RIGHT_INPUT, right);
1065         spin_unlock_irqrestore(&chip->reg_lock, flags);
1066         return change;
1067 }
1068
1069 static int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1070 {
1071         int mask = (kcontrol->private_value >> 16) & 0xff;
1072
1073         uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1074         uinfo->count = 1;
1075         uinfo->value.integer.min = 0;
1076         uinfo->value.integer.max = mask;
1077         return 0;
1078 }
1079
1080 static int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1081 {
1082         ad1848_t *chip = snd_kcontrol_chip(kcontrol);
1083         unsigned long flags;
1084         int reg = kcontrol->private_value & 0xff;
1085         int shift = (kcontrol->private_value >> 8) & 0xff;
1086         int mask = (kcontrol->private_value >> 16) & 0xff;
1087         int invert = (kcontrol->private_value >> 24) & 0xff;
1088         
1089         spin_lock_irqsave(&chip->reg_lock, flags);
1090         ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1091         spin_unlock_irqrestore(&chip->reg_lock, flags);
1092         if (invert)
1093                 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1094         return 0;
1095 }
1096
1097 static int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1098 {
1099         ad1848_t *chip = snd_kcontrol_chip(kcontrol);
1100         unsigned long flags;
1101         int reg = kcontrol->private_value & 0xff;
1102         int shift = (kcontrol->private_value >> 8) & 0xff;
1103         int mask = (kcontrol->private_value >> 16) & 0xff;
1104         int invert = (kcontrol->private_value >> 24) & 0xff;
1105         int change;
1106         unsigned short val;
1107         
1108         val = (ucontrol->value.integer.value[0] & mask);
1109         if (invert)
1110                 val = mask - val;
1111         val <<= shift;
1112         spin_lock_irqsave(&chip->reg_lock, flags);
1113         val = (chip->image[reg] & ~(mask << shift)) | val;
1114         change = val != chip->image[reg];
1115         snd_ad1848_out(chip, reg, val);
1116         spin_unlock_irqrestore(&chip->reg_lock, flags);
1117         return change;
1118 }
1119
1120 static int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1121 {
1122         int mask = (kcontrol->private_value >> 24) & 0xff;
1123
1124         uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1125         uinfo->count = 2;
1126         uinfo->value.integer.min = 0;
1127         uinfo->value.integer.max = mask;
1128         return 0;
1129 }
1130
1131 static int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1132 {
1133         ad1848_t *chip = snd_kcontrol_chip(kcontrol);
1134         unsigned long flags;
1135         int left_reg = kcontrol->private_value & 0xff;
1136         int right_reg = (kcontrol->private_value >> 8) & 0xff;
1137         int shift_left = (kcontrol->private_value >> 16) & 0x07;
1138         int shift_right = (kcontrol->private_value >> 19) & 0x07;
1139         int mask = (kcontrol->private_value >> 24) & 0xff;
1140         int invert = (kcontrol->private_value >> 22) & 1;
1141         
1142         spin_lock_irqsave(&chip->reg_lock, flags);
1143         ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1144         ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1145         spin_unlock_irqrestore(&chip->reg_lock, flags);
1146         if (invert) {
1147                 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1148                 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1149         }
1150         return 0;
1151 }
1152
1153 static int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1154 {
1155         ad1848_t *chip = snd_kcontrol_chip(kcontrol);
1156         unsigned long flags;
1157         int left_reg = kcontrol->private_value & 0xff;
1158         int right_reg = (kcontrol->private_value >> 8) & 0xff;
1159         int shift_left = (kcontrol->private_value >> 16) & 0x07;
1160         int shift_right = (kcontrol->private_value >> 19) & 0x07;
1161         int mask = (kcontrol->private_value >> 24) & 0xff;
1162         int invert = (kcontrol->private_value >> 22) & 1;
1163         int change;
1164         unsigned short val1, val2;
1165         
1166         val1 = ucontrol->value.integer.value[0] & mask;
1167         val2 = ucontrol->value.integer.value[1] & mask;
1168         if (invert) {
1169                 val1 = mask - val1;
1170                 val2 = mask - val2;
1171         }
1172         val1 <<= shift_left;
1173         val2 <<= shift_right;
1174         spin_lock_irqsave(&chip->reg_lock, flags);
1175         if (left_reg != right_reg) {
1176                 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1177                 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1178                 change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1179                 snd_ad1848_out(chip, left_reg, val1);
1180                 snd_ad1848_out(chip, right_reg, val2);
1181         } else {
1182                 val1 = (chip->image[left_reg] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
1183                 change = val1 != chip->image[left_reg];
1184                 snd_ad1848_out(chip, left_reg, val1);           
1185         }
1186         spin_unlock_irqrestore(&chip->reg_lock, flags);
1187         return change;
1188 }
1189
1190 /*
1191  */
1192 int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value)
1193 {
1194         static snd_kcontrol_new_t newctls[] = {
1195                 [AD1848_MIX_SINGLE] = {
1196                         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1197                         .info = snd_ad1848_info_single,
1198                         .get = snd_ad1848_get_single,
1199                         .put = snd_ad1848_put_single,
1200                 },
1201                 [AD1848_MIX_DOUBLE] = {
1202                         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1203                         .info = snd_ad1848_info_double,
1204                         .get = snd_ad1848_get_double,
1205                         .put = snd_ad1848_put_double,
1206                 },
1207                 [AD1848_MIX_CAPTURE] = {
1208                         .info = snd_ad1848_info_mux,
1209                         .get = snd_ad1848_get_mux,
1210                         .put = snd_ad1848_put_mux,
1211                 },
1212         };
1213         snd_kcontrol_t *ctl;
1214         int err;
1215
1216         ctl = snd_ctl_new1(&newctls[type], chip);
1217         if (! ctl)
1218                 return -ENOMEM;
1219         strlcpy(ctl->id.name, name, sizeof(ctl->id.name));
1220         ctl->id.index = index;
1221         ctl->private_value = value;
1222         if ((err = snd_ctl_add(chip->card, ctl)) < 0) {
1223                 snd_ctl_free_one(ctl);
1224                 return err;
1225         }
1226         return 0;
1227 }
1228
1229
1230 static struct ad1848_mix_elem snd_ad1848_controls[] = {
1231 AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
1232 AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1),
1233 AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1234 AD1848_DOUBLE("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
1235 AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1236 AD1848_DOUBLE("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
1237 AD1848_DOUBLE("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0),
1238 {
1239         .name = "Capture Source",
1240         .type = AD1848_MIX_CAPTURE,
1241 },
1242 AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0),
1243 AD1848_SINGLE("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0)
1244 };
1245                                         
1246 int snd_ad1848_mixer(ad1848_t *chip)
1247 {
1248         snd_card_t *card;
1249         snd_pcm_t *pcm;
1250         unsigned int idx;
1251         int err;
1252
1253         snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
1254
1255         pcm = chip->pcm;
1256         card = chip->card;
1257
1258         strcpy(card->mixername, pcm->name);
1259
1260         for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++)
1261                 if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0)
1262                         return err;
1263
1264         return 0;
1265 }
1266
1267 EXPORT_SYMBOL(snd_ad1848_in);
1268 EXPORT_SYMBOL(snd_ad1848_out);
1269 EXPORT_SYMBOL(snd_ad1848_dout);
1270 EXPORT_SYMBOL(snd_ad1848_mce_up);
1271 EXPORT_SYMBOL(snd_ad1848_mce_down);
1272 EXPORT_SYMBOL(snd_ad1848_interrupt);
1273 EXPORT_SYMBOL(snd_ad1848_create);
1274 EXPORT_SYMBOL(snd_ad1848_pcm);
1275 EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
1276 EXPORT_SYMBOL(snd_ad1848_mixer);
1277 EXPORT_SYMBOL(snd_ad1848_add_ctl);
1278
1279 /*
1280  *  INIT part
1281  */
1282
1283 static int __init alsa_ad1848_init(void)
1284 {
1285         return 0;
1286 }
1287
1288 static void __exit alsa_ad1848_exit(void)
1289 {
1290 }
1291
1292 module_init(alsa_ad1848_init)
1293 module_exit(alsa_ad1848_exit)