ALSA: wss_lib: use wss mixer code instead of ad1848 one
[linux-2.6.git] / sound / isa / ad1848 / ad1848_lib.c
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@perex.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 <linux/delay.h>
24 #include <linux/init.h>
25 #include <linux/interrupt.h>
26 #include <linux/slab.h>
27 #include <linux/ioport.h>
28 #include <sound/core.h>
29 #include <sound/ad1848.h>
30 #include <sound/control.h>
31 #include <sound/tlv.h>
32 #include <sound/pcm_params.h>
33
34 #include <asm/io.h>
35 #include <asm/dma.h>
36
37 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
38 MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248");
39 MODULE_LICENSE("GPL");
40
41 #if 0
42 #define SNDRV_DEBUG_MCE
43 #endif
44
45 /*
46  *  Some variables
47  */
48
49 static unsigned char freq_bits[14] = {
50         /* 5510 */      0x00 | AD1848_XTAL2,
51         /* 6620 */      0x0E | AD1848_XTAL2,
52         /* 8000 */      0x00 | AD1848_XTAL1,
53         /* 9600 */      0x0E | AD1848_XTAL1,
54         /* 11025 */     0x02 | AD1848_XTAL2,
55         /* 16000 */     0x02 | AD1848_XTAL1,
56         /* 18900 */     0x04 | AD1848_XTAL2,
57         /* 22050 */     0x06 | AD1848_XTAL2,
58         /* 27042 */     0x04 | AD1848_XTAL1,
59         /* 32000 */     0x06 | AD1848_XTAL1,
60         /* 33075 */     0x0C | AD1848_XTAL2,
61         /* 37800 */     0x08 | AD1848_XTAL2,
62         /* 44100 */     0x0A | AD1848_XTAL2,
63         /* 48000 */     0x0C | AD1848_XTAL1
64 };
65
66 static unsigned int rates[14] = {
67         5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
68         27042, 32000, 33075, 37800, 44100, 48000
69 };
70
71 static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
72         .count = ARRAY_SIZE(rates),
73         .list = rates,
74         .mask = 0,
75 };
76
77 static unsigned char snd_ad1848_original_image[16] =
78 {
79         0x00,                   /* 00 - lic */
80         0x00,                   /* 01 - ric */
81         0x9f,                   /* 02 - la1ic */
82         0x9f,                   /* 03 - ra1ic */
83         0x9f,                   /* 04 - la2ic */
84         0x9f,                   /* 05 - ra2ic */
85         0xbf,                   /* 06 - loc */
86         0xbf,                   /* 07 - roc */
87         0x20,                   /* 08 - dfr */
88         AD1848_AUTOCALIB,       /* 09 - ic */
89         0x00,                   /* 0a - pc */
90         0x00,                   /* 0b - ti */
91         0x00,                   /* 0c - mi */
92         0x00,                   /* 0d - lbc */
93         0x00,                   /* 0e - dru */
94         0x00,                   /* 0f - drl */
95 };
96
97 /*
98  *  Basic I/O functions
99  */
100
101 static void snd_ad1848_wait(struct snd_wss *chip)
102 {
103         int timeout;
104
105         for (timeout = 250; timeout > 0; timeout--) {
106                 if ((inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT) == 0)
107                         break;
108                 udelay(100);
109         }
110 }
111
112 void snd_ad1848_out(struct snd_wss *chip,
113                            unsigned char reg,
114                            unsigned char value)
115 {
116         snd_ad1848_wait(chip);
117 #ifdef CONFIG_SND_DEBUG
118         if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT)
119                 snd_printk(KERN_WARNING "auto calibration time out - "
120                            "reg = 0x%x, value = 0x%x\n", reg, value);
121 #endif
122         outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL));
123         outb(chip->image[reg] = value, chip->port + CS4231P(REG));
124         mb();
125         snd_printdd("codec out - reg 0x%x = 0x%x\n",
126                         chip->mce_bit | reg, value);
127 }
128
129 EXPORT_SYMBOL(snd_ad1848_out);
130
131 static void snd_ad1848_dout(struct snd_wss *chip,
132                             unsigned char reg, unsigned char value)
133 {
134         snd_ad1848_wait(chip);
135         outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL));
136         outb(value, chip->port + CS4231P(REG));
137         mb();
138 }
139
140 static unsigned char snd_ad1848_in(struct snd_wss *chip, unsigned char reg)
141 {
142         snd_ad1848_wait(chip);
143 #ifdef CONFIG_SND_DEBUG
144         if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT)
145                 snd_printk(KERN_WARNING "auto calibration time out - "
146                            "reg = 0x%x\n", reg);
147 #endif
148         outb(chip->mce_bit | reg, chip->port + CS4231P(REGSEL));
149         mb();
150         return inb(chip->port + CS4231P(REG));
151 }
152
153 #if 0
154
155 static void snd_ad1848_debug(struct snd_wss *chip)
156 {
157         printk(KERN_DEBUG "AD1848 REGS:      INDEX = 0x%02x  ", inb(chip->port + CS4231P(REGSEL)));
158         printk(KERN_DEBUG "                 STATUS = 0x%02x\n", inb(chip->port + CS4231P(STATUS)));
159         printk(KERN_DEBUG "  0x00: left input      = 0x%02x  ", snd_ad1848_in(chip, 0x00));
160         printk(KERN_DEBUG "  0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08));
161         printk(KERN_DEBUG "  0x01: right input     = 0x%02x  ", snd_ad1848_in(chip, 0x01));
162         printk(KERN_DEBUG "  0x09: iface (CFIG 1)  = 0x%02x\n", snd_ad1848_in(chip, 0x09));
163         printk(KERN_DEBUG "  0x02: AUXA left       = 0x%02x  ", snd_ad1848_in(chip, 0x02));
164         printk(KERN_DEBUG "  0x0a: pin control     = 0x%02x\n", snd_ad1848_in(chip, 0x0a));
165         printk(KERN_DEBUG "  0x03: AUXA right      = 0x%02x  ", snd_ad1848_in(chip, 0x03));
166         printk(KERN_DEBUG "  0x0b: init & status   = 0x%02x\n", snd_ad1848_in(chip, 0x0b));
167         printk(KERN_DEBUG "  0x04: AUXB left       = 0x%02x  ", snd_ad1848_in(chip, 0x04));
168         printk(KERN_DEBUG "  0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c));
169         printk(KERN_DEBUG "  0x05: AUXB right      = 0x%02x  ", snd_ad1848_in(chip, 0x05));
170         printk(KERN_DEBUG "  0x0d: loopback        = 0x%02x\n", snd_ad1848_in(chip, 0x0d));
171         printk(KERN_DEBUG "  0x06: left output     = 0x%02x  ", snd_ad1848_in(chip, 0x06));
172         printk(KERN_DEBUG "  0x0e: data upr count  = 0x%02x\n", snd_ad1848_in(chip, 0x0e));
173         printk(KERN_DEBUG "  0x07: right output    = 0x%02x  ", snd_ad1848_in(chip, 0x07));
174         printk(KERN_DEBUG "  0x0f: data lwr count  = 0x%02x\n", snd_ad1848_in(chip, 0x0f));
175 }
176
177 #endif
178
179 /*
180  *  AD1848 detection / MCE routines
181  */
182
183 static void snd_ad1848_mce_up(struct snd_wss *chip)
184 {
185         unsigned long flags;
186         int timeout;
187
188         snd_ad1848_wait(chip);
189 #ifdef CONFIG_SND_DEBUG
190         if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT)
191                 snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
192 #endif
193         spin_lock_irqsave(&chip->reg_lock, flags);
194         chip->mce_bit |= AD1848_MCE;
195         timeout = inb(chip->port + CS4231P(REGSEL));
196         if (timeout == 0x80)
197                 snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
198         if (!(timeout & AD1848_MCE))
199                 outb(chip->mce_bit | (timeout & 0x1f),
200                      chip->port + CS4231P(REGSEL));
201         spin_unlock_irqrestore(&chip->reg_lock, flags);
202 }
203
204 static void snd_ad1848_mce_down(struct snd_wss *chip)
205 {
206         unsigned long flags, timeout;
207         int reg;
208
209         spin_lock_irqsave(&chip->reg_lock, flags);
210         for (timeout = 5; timeout > 0; timeout--)
211                 inb(chip->port + CS4231P(REGSEL));
212         /* end of cleanup sequence */
213         for (timeout = 12000;
214              timeout > 0 && (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT);
215              timeout--)
216                 udelay(100);
217
218         snd_printdd("(1) timeout = %ld\n", timeout);
219
220 #ifdef CONFIG_SND_DEBUG
221         if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT)
222                 snd_printk(KERN_WARNING
223                            "mce_down [0x%lx] - auto calibration time out (0)\n",
224                            chip->port + CS4231P(REGSEL));
225 #endif
226
227         chip->mce_bit &= ~AD1848_MCE;
228         reg = inb(chip->port + CS4231P(REGSEL));
229         outb(chip->mce_bit | (reg & 0x1f), chip->port + CS4231P(REGSEL));
230         if (reg == 0x80)
231                 snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
232         if ((reg & AD1848_MCE) == 0) {
233                 spin_unlock_irqrestore(&chip->reg_lock, flags);
234                 return;
235         }
236
237         /*
238          * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low.
239          * It may take up to 5 sample periods (at most 907 us @ 5.5125 kHz) for
240          * the process to _start_, so it is important to wait at least that long
241          * before checking.  Otherwise we might think AC has finished when it
242          * has in fact not begun.  It could take 128 (no AC) or 384 (AC) cycles
243          * for ACI to drop.  This gives a wait of at most 70 ms with a more
244          * typical value of 3-9 ms.
245          */
246         timeout = jiffies + msecs_to_jiffies(250);
247         do {
248                 spin_unlock_irqrestore(&chip->reg_lock, flags);
249                 msleep(1);
250                 spin_lock_irqsave(&chip->reg_lock, flags);
251                 reg = snd_ad1848_in(chip, AD1848_TEST_INIT) &
252                       AD1848_CALIB_IN_PROGRESS;
253         } while (reg && time_before(jiffies, timeout));
254         spin_unlock_irqrestore(&chip->reg_lock, flags);
255         if (reg)
256                 snd_printk(KERN_ERR
257                            "mce_down - auto calibration time out (2)\n");
258
259         snd_printdd("(4) jiffies = %lu\n", jiffies);
260         snd_printd("mce_down - exit = 0x%x\n",
261                    inb(chip->port + CS4231P(REGSEL)));
262 }
263
264 static unsigned int snd_ad1848_get_count(unsigned char format,
265                                          unsigned int size)
266 {
267         switch (format & 0xe0) {
268         case AD1848_LINEAR_16:
269                 size >>= 1;
270                 break;
271         }
272         if (format & AD1848_STEREO)
273                 size >>= 1;
274         return size;
275 }
276
277 static int snd_ad1848_trigger(struct snd_wss *chip, unsigned char what,
278                               int channel, int cmd)
279 {
280         int result = 0;
281
282 #if 0
283         printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(AD1848P(card, STATUS)));
284 #endif
285         spin_lock(&chip->reg_lock);
286         if (cmd == SNDRV_PCM_TRIGGER_START) {
287                 if (chip->image[AD1848_IFACE_CTRL] & what) {
288                         spin_unlock(&chip->reg_lock);
289                         return 0;
290                 }
291                 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what);
292         } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
293                 if (!(chip->image[AD1848_IFACE_CTRL] & what)) {
294                         spin_unlock(&chip->reg_lock);
295                         return 0;
296                 }
297                 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what);
298         } else {
299                 result = -EINVAL;
300         }
301         spin_unlock(&chip->reg_lock);
302         return result;
303 }
304
305 /*
306  *  CODEC I/O
307  */
308
309 static unsigned char snd_ad1848_get_rate(unsigned int rate)
310 {
311         int i;
312
313         for (i = 0; i < ARRAY_SIZE(rates); i++)
314                 if (rate == rates[i])
315                         return freq_bits[i];
316         snd_BUG();
317         return freq_bits[ARRAY_SIZE(rates) - 1];
318 }
319
320 static int snd_ad1848_ioctl(struct snd_pcm_substream *substream,
321                             unsigned int cmd, void *arg)
322 {
323         return snd_pcm_lib_ioctl(substream, cmd, arg);
324 }
325
326 static unsigned char snd_ad1848_get_format(int format, int channels)
327 {
328         unsigned char rformat;
329
330         rformat = AD1848_LINEAR_8;
331         switch (format) {
332         case SNDRV_PCM_FORMAT_A_LAW:    rformat = AD1848_ALAW_8; break;
333         case SNDRV_PCM_FORMAT_MU_LAW:   rformat = AD1848_ULAW_8; break;
334         case SNDRV_PCM_FORMAT_S16_LE:   rformat = AD1848_LINEAR_16; break;
335         }
336         if (channels > 1)
337                 rformat |= AD1848_STEREO;
338 #if 0
339         snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
340 #endif
341         return rformat;
342 }
343
344 static void snd_ad1848_calibrate_mute(struct snd_wss *chip, int mute)
345 {
346         unsigned long flags;
347         
348         mute = mute ? 1 : 0;
349         spin_lock_irqsave(&chip->reg_lock, flags);
350         if (chip->calibrate_mute == mute) {
351                 spin_unlock_irqrestore(&chip->reg_lock, flags);
352                 return;
353         }
354         if (!mute) {
355                 snd_ad1848_dout(chip, AD1848_LEFT_INPUT, chip->image[AD1848_LEFT_INPUT]);
356                 snd_ad1848_dout(chip, AD1848_RIGHT_INPUT, chip->image[AD1848_RIGHT_INPUT]);
357         }
358         snd_ad1848_dout(chip, AD1848_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_LEFT_INPUT]);
359         snd_ad1848_dout(chip, AD1848_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_RIGHT_INPUT]);
360         snd_ad1848_dout(chip, AD1848_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_LEFT_INPUT]);
361         snd_ad1848_dout(chip, AD1848_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_RIGHT_INPUT]);
362         snd_ad1848_dout(chip, AD1848_LEFT_OUTPUT, mute ? 0x80 : chip->image[AD1848_LEFT_OUTPUT]);
363         snd_ad1848_dout(chip, AD1848_RIGHT_OUTPUT, mute ? 0x80 : chip->image[AD1848_RIGHT_OUTPUT]);
364         chip->calibrate_mute = mute;
365         spin_unlock_irqrestore(&chip->reg_lock, flags);
366 }
367
368 static void snd_ad1848_set_data_format(struct snd_wss *chip,
369                                        struct snd_pcm_hw_params *hw_params)
370 {
371         if (hw_params == NULL) {
372                 chip->image[AD1848_DATA_FORMAT] = 0x20;
373         } else {
374                 chip->image[AD1848_DATA_FORMAT] =
375                     snd_ad1848_get_format(params_format(hw_params), params_channels(hw_params)) |
376                     snd_ad1848_get_rate(params_rate(hw_params));
377         }
378         // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]);
379 }
380
381 static int snd_ad1848_open(struct snd_wss *chip, unsigned int mode)
382 {
383         unsigned long flags;
384
385         if (chip->mode & WSS_MODE_OPEN)
386                 return -EAGAIN;
387
388         snd_ad1848_mce_down(chip);
389
390 #ifdef SNDRV_DEBUG_MCE
391         snd_printk("open: (1)\n");
392 #endif
393         snd_ad1848_mce_up(chip);
394         spin_lock_irqsave(&chip->reg_lock, flags);
395         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
396                              AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO |
397                              AD1848_CALIB_MODE);
398         chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB;
399         snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
400         spin_unlock_irqrestore(&chip->reg_lock, flags);
401         snd_ad1848_mce_down(chip);
402
403 #ifdef SNDRV_DEBUG_MCE
404         snd_printk("open: (2)\n");
405 #endif
406
407         snd_ad1848_set_data_format(chip, NULL);
408
409         snd_ad1848_mce_up(chip);
410         spin_lock_irqsave(&chip->reg_lock, flags);
411         snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
412         spin_unlock_irqrestore(&chip->reg_lock, flags);
413         snd_ad1848_mce_down(chip);
414
415 #ifdef SNDRV_DEBUG_MCE
416         snd_printk("open: (3)\n");
417 #endif
418
419         /* ok. now enable and ack CODEC IRQ */
420         spin_lock_irqsave(&chip->reg_lock, flags);
421         outb(0, chip->port + CS4231P(STATUS));  /* clear IRQ */
422         outb(0, chip->port + CS4231P(STATUS));  /* clear IRQ */
423         chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE;
424         snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
425         spin_unlock_irqrestore(&chip->reg_lock, flags);
426
427         chip->mode = mode;
428
429         return 0;
430 }
431
432 static void snd_ad1848_close(struct snd_wss *chip)
433 {
434         unsigned long flags;
435
436         if (!chip->mode)
437                 return;
438         /* disable IRQ */
439         spin_lock_irqsave(&chip->reg_lock, flags);
440         outb(0, chip->port + CS4231P(STATUS));  /* clear IRQ */
441         outb(0, chip->port + CS4231P(STATUS));  /* clear IRQ */
442         chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE;
443         snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
444         spin_unlock_irqrestore(&chip->reg_lock, flags);
445
446         /* now disable capture & playback */
447
448         snd_ad1848_mce_up(chip);
449         spin_lock_irqsave(&chip->reg_lock, flags);
450         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
451                              AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
452         snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
453         spin_unlock_irqrestore(&chip->reg_lock, flags);
454         snd_ad1848_mce_down(chip);
455
456         /* clear IRQ again */
457         spin_lock_irqsave(&chip->reg_lock, flags);
458         outb(0, chip->port + CS4231P(STATUS));  /* clear IRQ */
459         outb(0, chip->port + CS4231P(STATUS));  /* clear IRQ */
460         spin_unlock_irqrestore(&chip->reg_lock, flags);
461
462         chip->mode = 0;
463 }
464
465 /*
466  *  ok.. exported functions..
467  */
468
469 static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream,
470                                        int cmd)
471 {
472         struct snd_wss *chip = snd_pcm_substream_chip(substream);
473         return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd);
474 }
475
476 static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream,
477                                       int cmd)
478 {
479         struct snd_wss *chip = snd_pcm_substream_chip(substream);
480         return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd);
481 }
482
483 static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream,
484                                          struct snd_pcm_hw_params *hw_params)
485 {
486         struct snd_wss *chip = snd_pcm_substream_chip(substream);
487         unsigned long flags;
488         int err;
489
490         if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
491                 return err;
492         snd_ad1848_calibrate_mute(chip, 1);
493         snd_ad1848_set_data_format(chip, hw_params);
494         snd_ad1848_mce_up(chip);
495         spin_lock_irqsave(&chip->reg_lock, flags);
496         snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
497         spin_unlock_irqrestore(&chip->reg_lock, flags);
498         snd_ad1848_mce_down(chip);
499         snd_ad1848_calibrate_mute(chip, 0);
500         return 0;
501 }
502
503 static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream)
504 {
505         return snd_pcm_lib_free_pages(substream);
506 }
507
508 static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream)
509 {
510         struct snd_wss *chip = snd_pcm_substream_chip(substream);
511         struct snd_pcm_runtime *runtime = substream->runtime;
512         unsigned long flags;
513         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
514         unsigned int count = snd_pcm_lib_period_bytes(substream);
515
516         chip->p_dma_size = size;
517         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO);
518         snd_dma_program(chip->dma1, runtime->dma_addr, size,
519                         DMA_MODE_WRITE | DMA_AUTOINIT);
520         count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
521         spin_lock_irqsave(&chip->reg_lock, flags);
522         snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
523         snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
524         spin_unlock_irqrestore(&chip->reg_lock, flags);
525         return 0;
526 }
527
528 static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream,
529                                         struct snd_pcm_hw_params *hw_params)
530 {
531         struct snd_wss *chip = snd_pcm_substream_chip(substream);
532         unsigned long flags;
533         int err;
534
535         if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
536                 return err;
537         snd_ad1848_calibrate_mute(chip, 1);
538         snd_ad1848_set_data_format(chip, hw_params);
539         snd_ad1848_mce_up(chip);
540         spin_lock_irqsave(&chip->reg_lock, flags);
541         snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
542         spin_unlock_irqrestore(&chip->reg_lock, flags);
543         snd_ad1848_mce_down(chip);
544         snd_ad1848_calibrate_mute(chip, 0);
545         return 0;
546 }
547
548 static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream)
549 {
550         return snd_pcm_lib_free_pages(substream);
551 }
552
553 static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream)
554 {
555         struct snd_wss *chip = snd_pcm_substream_chip(substream);
556         struct snd_pcm_runtime *runtime = substream->runtime;
557         unsigned long flags;
558         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
559         unsigned int count = snd_pcm_lib_period_bytes(substream);
560
561         chip->c_dma_size = size;
562         chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
563         snd_dma_program(chip->dma2, runtime->dma_addr, size,
564                         DMA_MODE_READ | DMA_AUTOINIT);
565         count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
566         spin_lock_irqsave(&chip->reg_lock, flags);
567         snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
568         snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
569         spin_unlock_irqrestore(&chip->reg_lock, flags);
570         return 0;
571 }
572
573 static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id)
574 {
575         struct snd_wss *chip = dev_id;
576
577         if ((chip->mode & WSS_MODE_PLAY) && chip->playback_substream)
578                 snd_pcm_period_elapsed(chip->playback_substream);
579         if ((chip->mode & WSS_MODE_RECORD) && chip->capture_substream)
580                 snd_pcm_period_elapsed(chip->capture_substream);
581         outb(0, chip->port + CS4231P(STATUS));  /* clear global interrupt bit */
582         return IRQ_HANDLED;
583 }
584
585 static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream)
586 {
587         struct snd_wss *chip = snd_pcm_substream_chip(substream);
588         size_t ptr;
589         
590         if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
591                 return 0;
592         ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
593         return bytes_to_frames(substream->runtime, ptr);
594 }
595
596 static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream)
597 {
598         struct snd_wss *chip = snd_pcm_substream_chip(substream);
599         size_t ptr;
600
601         if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
602                 return 0;
603         ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
604         return bytes_to_frames(substream->runtime, ptr);
605 }
606
607 /*
608
609  */
610
611 static void snd_ad1848_thinkpad_twiddle(struct snd_wss *chip, int on)
612 {
613         int tmp;
614
615         if (!chip->thinkpad_flag) return;
616
617         outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
618         tmp = inb(AD1848_THINKPAD_CTL_PORT2);
619
620         if (on)
621                 /* turn it on */
622                 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
623         else
624                 /* turn it off */
625                 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
626         
627         outb(tmp, AD1848_THINKPAD_CTL_PORT2);
628
629 }
630
631 #ifdef CONFIG_PM
632 static void snd_ad1848_suspend(struct snd_wss *chip)
633 {
634         snd_pcm_suspend_all(chip->pcm);
635         if (chip->thinkpad_flag)
636                 snd_ad1848_thinkpad_twiddle(chip, 0);
637 }
638
639 static void snd_ad1848_resume(struct snd_wss *chip)
640 {
641         int i;
642
643         if (chip->thinkpad_flag)
644                 snd_ad1848_thinkpad_twiddle(chip, 1);
645
646         /* clear any pendings IRQ */
647         inb(chip->port + CS4231P(STATUS));
648         outb(0, chip->port + CS4231P(STATUS));
649         mb();
650
651         snd_ad1848_mce_down(chip);
652         for (i = 0; i < 16; i++)
653                 snd_ad1848_out(chip, i, chip->image[i]);
654         snd_ad1848_mce_up(chip);
655         snd_ad1848_mce_down(chip);
656 }
657 #endif /* CONFIG_PM */
658
659 static int snd_ad1848_probe(struct snd_wss *chip)
660 {
661         unsigned long flags;
662         int i, id, rev, ad1847;
663         unsigned char *ptr;
664
665 #if 0
666         snd_ad1848_debug(chip);
667 #endif
668         id = ad1847 = 0;
669         for (i = 0; i < 1000; i++) {
670                 mb();
671                 if (inb(chip->port + CS4231P(REGSEL)) & AD1848_INIT)
672                         udelay(500);
673                 else {
674                         spin_lock_irqsave(&chip->reg_lock, flags);
675                         snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
676                         snd_ad1848_out(chip, AD1848_LEFT_INPUT, 0xaa);
677                         snd_ad1848_out(chip, AD1848_RIGHT_INPUT, 0x45);
678                         rev = snd_ad1848_in(chip, AD1848_RIGHT_INPUT);
679                         if (rev == 0x65) {
680                                 spin_unlock_irqrestore(&chip->reg_lock, flags);
681                                 id = 1;
682                                 ad1847 = 1;
683                                 break;
684                         }
685                         if (snd_ad1848_in(chip, AD1848_LEFT_INPUT) == 0xaa && rev == 0x45) {
686                                 spin_unlock_irqrestore(&chip->reg_lock, flags);
687                                 id = 1;
688                                 break;
689                         }
690                         spin_unlock_irqrestore(&chip->reg_lock, flags);
691                 }
692         }
693         if (id != 1)
694                 return -ENODEV; /* no valid device found */
695         if (chip->hardware == WSS_HW_DETECT) {
696                 if (ad1847) {
697                         chip->hardware = WSS_HW_AD1847;
698                 } else {
699                         chip->hardware = WSS_HW_AD1848;
700                         rev = snd_ad1848_in(chip, AD1848_MISC_INFO);
701                         if (rev & 0x80) {
702                                 chip->hardware = WSS_HW_CS4248;
703                         } else if ((rev & 0x0f) == 0x0a) {
704                                 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x40);
705                                 for (i = 0; i < 16; ++i) {
706                                         if (snd_ad1848_in(chip, i) != snd_ad1848_in(chip, i + 16)) {
707                                                 chip->hardware = WSS_HW_CMI8330;
708                                                 break;
709                                         }
710                                 }
711                                 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
712                         }
713                 }
714         }
715         spin_lock_irqsave(&chip->reg_lock, flags);
716         inb(chip->port + CS4231P(STATUS));      /* clear any pendings IRQ */
717         outb(0, chip->port + CS4231P(STATUS));
718         mb();
719         spin_unlock_irqrestore(&chip->reg_lock, flags);
720
721         chip->image[AD1848_MISC_INFO] = 0x00;
722         chip->image[AD1848_IFACE_CTRL] =
723             (chip->image[AD1848_IFACE_CTRL] & ~AD1848_SINGLE_DMA) | AD1848_SINGLE_DMA;
724         ptr = (unsigned char *) &chip->image;
725         snd_ad1848_mce_down(chip);
726         spin_lock_irqsave(&chip->reg_lock, flags);
727         for (i = 0; i < 16; i++)        /* ok.. fill all AD1848 registers */
728                 snd_ad1848_out(chip, i, *ptr++);
729         spin_unlock_irqrestore(&chip->reg_lock, flags);
730         snd_ad1848_mce_up(chip);
731         snd_ad1848_mce_down(chip);
732         return 0;               /* all things are ok.. */
733 }
734
735 /*
736
737  */
738
739 static struct snd_pcm_hardware snd_ad1848_playback =
740 {
741         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
742                                  SNDRV_PCM_INFO_MMAP_VALID),
743         .formats =              (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
744                                  SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
745         .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
746         .rate_min =             5510,
747         .rate_max =             48000,
748         .channels_min =         1,
749         .channels_max =         2,
750         .buffer_bytes_max =     (128*1024),
751         .period_bytes_min =     64,
752         .period_bytes_max =     (128*1024),
753         .periods_min =          1,
754         .periods_max =          1024,
755         .fifo_size =            0,
756 };
757
758 static struct snd_pcm_hardware snd_ad1848_capture =
759 {
760         .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
761                                  SNDRV_PCM_INFO_MMAP_VALID),
762         .formats =              (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
763                                  SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
764         .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
765         .rate_min =             5510,
766         .rate_max =             48000,
767         .channels_min =         1,
768         .channels_max =         2,
769         .buffer_bytes_max =     (128*1024),
770         .period_bytes_min =     64,
771         .period_bytes_max =     (128*1024),
772         .periods_min =          1,
773         .periods_max =          1024,
774         .fifo_size =            0,
775 };
776
777 /*
778
779  */
780
781 static int snd_ad1848_playback_open(struct snd_pcm_substream *substream)
782 {
783         struct snd_wss *chip = snd_pcm_substream_chip(substream);
784         struct snd_pcm_runtime *runtime = substream->runtime;
785         int err;
786
787         err = snd_ad1848_open(chip, WSS_MODE_PLAY);
788         if (err < 0)
789                 return err;
790         chip->playback_substream = substream;
791         runtime->hw = snd_ad1848_playback;
792         snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
793         snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
794         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
795         return 0;
796 }
797
798 static int snd_ad1848_capture_open(struct snd_pcm_substream *substream)
799 {
800         struct snd_wss *chip = snd_pcm_substream_chip(substream);
801         struct snd_pcm_runtime *runtime = substream->runtime;
802         int err;
803
804         err = snd_ad1848_open(chip, WSS_MODE_RECORD);
805         if (err < 0)
806                 return err;
807         chip->capture_substream = substream;
808         runtime->hw = snd_ad1848_capture;
809         snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
810         snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
811         snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
812         return 0;
813 }
814
815 static int snd_ad1848_playback_close(struct snd_pcm_substream *substream)
816 {
817         struct snd_wss *chip = snd_pcm_substream_chip(substream);
818
819         chip->mode &= ~WSS_MODE_PLAY;
820         chip->playback_substream = NULL;
821         snd_ad1848_close(chip);
822         return 0;
823 }
824
825 static int snd_ad1848_capture_close(struct snd_pcm_substream *substream)
826 {
827         struct snd_wss *chip = snd_pcm_substream_chip(substream);
828
829         chip->mode &= ~WSS_MODE_RECORD;
830         chip->capture_substream = NULL;
831         snd_ad1848_close(chip);
832         return 0;
833 }
834
835 static int snd_ad1848_free(struct snd_wss *chip)
836 {
837         release_and_free_resource(chip->res_port);
838         if (chip->irq >= 0)
839                 free_irq(chip->irq, (void *) chip);
840         if (chip->dma1 >= 0) {
841                 snd_dma_disable(chip->dma1);
842                 free_dma(chip->dma1);
843         }
844         kfree(chip);
845         return 0;
846 }
847
848 static int snd_ad1848_dev_free(struct snd_device *device)
849 {
850         struct snd_wss *chip = device->device_data;
851         return snd_ad1848_free(chip);
852 }
853
854 static const char *snd_ad1848_chip_id(struct snd_wss *chip)
855 {
856         switch (chip->hardware) {
857         case AD1848_HW_AD1847:  return "AD1847";
858         case AD1848_HW_AD1848:  return "AD1848";
859         case AD1848_HW_CS4248:  return "CS4248";
860         case AD1848_HW_CMI8330: return "CMI8330/C3D";
861         default:                return "???";
862         }
863 }
864
865 int snd_ad1848_create(struct snd_card *card,
866                       unsigned long port,
867                       int irq, int dma,
868                       unsigned short hardware,
869                       struct snd_wss **rchip)
870 {
871         static struct snd_device_ops ops = {
872                 .dev_free =     snd_ad1848_dev_free,
873         };
874         struct snd_wss *chip;
875         int err;
876
877         *rchip = NULL;
878         chip = kzalloc(sizeof(*chip), GFP_KERNEL);
879         if (chip == NULL)
880                 return -ENOMEM;
881         spin_lock_init(&chip->reg_lock);
882         chip->card = card;
883         chip->port = port;
884         chip->irq = -1;
885         chip->dma1 = -1;
886         chip->dma2 = -1;
887         chip->single_dma = 1;
888         chip->hardware = hardware;
889         memcpy(&chip->image, &snd_ad1848_original_image, sizeof(snd_ad1848_original_image));
890         
891         if ((chip->res_port = request_region(port, 4, "AD1848")) == NULL) {
892                 snd_printk(KERN_ERR "ad1848: can't grab port 0x%lx\n", port);
893                 snd_ad1848_free(chip);
894                 return -EBUSY;
895         }
896         if (request_irq(irq, snd_ad1848_interrupt, IRQF_DISABLED, "AD1848", (void *) chip)) {
897                 snd_printk(KERN_ERR "ad1848: can't grab IRQ %d\n", irq);
898                 snd_ad1848_free(chip);
899                 return -EBUSY;
900         }
901         chip->irq = irq;
902         if (request_dma(dma, "AD1848")) {
903                 snd_printk(KERN_ERR "ad1848: can't grab DMA %d\n", dma);
904                 snd_ad1848_free(chip);
905                 return -EBUSY;
906         }
907         chip->dma1 = dma;
908         chip->dma2 = dma;
909
910         if (hardware == WSS_HW_THINKPAD) {
911                 chip->thinkpad_flag = 1;
912                 chip->hardware = WSS_HW_DETECT; /* reset */
913                 snd_ad1848_thinkpad_twiddle(chip, 1);
914         }
915
916         if (snd_ad1848_probe(chip) < 0) {
917                 snd_ad1848_free(chip);
918                 return -ENODEV;
919         }
920
921         /* Register device */
922         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
923                 snd_ad1848_free(chip);
924                 return err;
925         }
926
927 #ifdef CONFIG_PM
928         chip->suspend = snd_ad1848_suspend;
929         chip->resume = snd_ad1848_resume;
930 #endif
931
932         *rchip = chip;
933         return 0;
934 }
935
936 EXPORT_SYMBOL(snd_ad1848_create);
937
938 static struct snd_pcm_ops snd_ad1848_playback_ops = {
939         .open =         snd_ad1848_playback_open,
940         .close =        snd_ad1848_playback_close,
941         .ioctl =        snd_ad1848_ioctl,
942         .hw_params =    snd_ad1848_playback_hw_params,
943         .hw_free =      snd_ad1848_playback_hw_free,
944         .prepare =      snd_ad1848_playback_prepare,
945         .trigger =      snd_ad1848_playback_trigger,
946         .pointer =      snd_ad1848_playback_pointer,
947 };
948
949 static struct snd_pcm_ops snd_ad1848_capture_ops = {
950         .open =         snd_ad1848_capture_open,
951         .close =        snd_ad1848_capture_close,
952         .ioctl =        snd_ad1848_ioctl,
953         .hw_params =    snd_ad1848_capture_hw_params,
954         .hw_free =      snd_ad1848_capture_hw_free,
955         .prepare =      snd_ad1848_capture_prepare,
956         .trigger =      snd_ad1848_capture_trigger,
957         .pointer =      snd_ad1848_capture_pointer,
958 };
959
960 int snd_ad1848_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
961 {
962         struct snd_pcm *pcm;
963         int err;
964
965         if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0)
966                 return err;
967
968         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops);
969         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops);
970
971         pcm->private_data = chip;
972         pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
973         strcpy(pcm->name, snd_ad1848_chip_id(chip));
974
975         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
976                                               snd_dma_isa_data(),
977                                               64 * 1024,
978                                               chip->dma1 > 3 ?
979                                                         128 * 1024 : 64 * 1024);
980
981         chip->pcm = pcm;
982         if (rpcm)
983                 *rpcm = pcm;
984         return 0;
985 }
986
987 EXPORT_SYMBOL(snd_ad1848_pcm);
988
989 const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction)
990 {
991         return direction == SNDRV_PCM_STREAM_PLAYBACK ?
992                 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
993 }
994
995 EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
996
997 /*
998  *  INIT part
999  */
1000
1001 static int __init alsa_ad1848_init(void)
1002 {
1003         return 0;
1004 }
1005
1006 static void __exit alsa_ad1848_exit(void)
1007 {
1008 }
1009
1010 module_init(alsa_ad1848_init)
1011 module_exit(alsa_ad1848_exit)