Revert "[PATCH] paravirt: Add startup infrastructure for paravirtualization"
[pv_ops_mirror.git] / sound / isa / ad1848 / ad1848_lib.c
blob8094282c2ae1992d76f588018b28ad2390d44e3e
1 /*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of AD1848/AD1847/CS4248
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.
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.
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
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/slab.h>
28 #include <linux/ioport.h>
29 #include <sound/core.h>
30 #include <sound/ad1848.h>
31 #include <sound/control.h>
32 #include <sound/tlv.h>
33 #include <sound/pcm_params.h>
35 #include <asm/io.h>
36 #include <asm/dma.h>
38 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
39 MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248");
40 MODULE_LICENSE("GPL");
42 #if 0
43 #define SNDRV_DEBUG_MCE
44 #endif
47 * Some variables
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
67 static unsigned int rates[14] = {
68 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
69 27042, 32000, 33075, 37800, 44100, 48000
72 static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
73 .count = 14,
74 .list = rates,
75 .mask = 0,
78 static unsigned char snd_ad1848_original_image[16] =
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 */
99 * Basic I/O functions
102 void snd_ad1848_out(struct snd_ad1848 *chip,
103 unsigned char reg,
104 unsigned char value)
106 int timeout;
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(KERN_WARNING "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
122 EXPORT_SYMBOL(snd_ad1848_out);
124 static void snd_ad1848_dout(struct snd_ad1848 *chip,
125 unsigned char reg, unsigned char value)
127 int timeout;
129 for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
130 udelay(100);
131 outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
132 outb(value, AD1848P(chip, REG));
133 mb();
136 static unsigned char snd_ad1848_in(struct snd_ad1848 *chip, unsigned char reg)
138 int timeout;
140 for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
141 udelay(100);
142 #ifdef CONFIG_SND_DEBUG
143 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
144 snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x\n", reg);
145 #endif
146 outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
147 mb();
148 return inb(AD1848P(chip, REG));
151 #if 0
153 static void snd_ad1848_debug(struct snd_ad1848 *chip)
155 printk("AD1848 REGS: INDEX = 0x%02x ", inb(AD1848P(chip, REGSEL)));
156 printk(" STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS)));
157 printk(" 0x00: left input = 0x%02x ", snd_ad1848_in(chip, 0x00));
158 printk(" 0x08: playback format = 0x%02x\n", snd_ad1848_in(chip, 0x08));
159 printk(" 0x01: right input = 0x%02x ", snd_ad1848_in(chip, 0x01));
160 printk(" 0x09: iface (CFIG 1) = 0x%02x\n", snd_ad1848_in(chip, 0x09));
161 printk(" 0x02: AUXA left = 0x%02x ", snd_ad1848_in(chip, 0x02));
162 printk(" 0x0a: pin control = 0x%02x\n", snd_ad1848_in(chip, 0x0a));
163 printk(" 0x03: AUXA right = 0x%02x ", snd_ad1848_in(chip, 0x03));
164 printk(" 0x0b: init & status = 0x%02x\n", snd_ad1848_in(chip, 0x0b));
165 printk(" 0x04: AUXB left = 0x%02x ", snd_ad1848_in(chip, 0x04));
166 printk(" 0x0c: revision & mode = 0x%02x\n", snd_ad1848_in(chip, 0x0c));
167 printk(" 0x05: AUXB right = 0x%02x ", snd_ad1848_in(chip, 0x05));
168 printk(" 0x0d: loopback = 0x%02x\n", snd_ad1848_in(chip, 0x0d));
169 printk(" 0x06: left output = 0x%02x ", snd_ad1848_in(chip, 0x06));
170 printk(" 0x0e: data upr count = 0x%02x\n", snd_ad1848_in(chip, 0x0e));
171 printk(" 0x07: right output = 0x%02x ", snd_ad1848_in(chip, 0x07));
172 printk(" 0x0f: data lwr count = 0x%02x\n", snd_ad1848_in(chip, 0x0f));
175 #endif
178 * AD1848 detection / MCE routines
181 static void snd_ad1848_mce_up(struct snd_ad1848 *chip)
183 unsigned long flags;
184 int timeout;
186 for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
187 udelay(100);
188 #ifdef CONFIG_SND_DEBUG
189 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
190 snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
191 #endif
192 spin_lock_irqsave(&chip->reg_lock, flags);
193 chip->mce_bit |= AD1848_MCE;
194 timeout = inb(AD1848P(chip, REGSEL));
195 if (timeout == 0x80)
196 snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
197 if (!(timeout & AD1848_MCE))
198 outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
199 spin_unlock_irqrestore(&chip->reg_lock, flags);
202 static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
204 unsigned long flags;
205 int timeout;
206 signed long time;
208 spin_lock_irqsave(&chip->reg_lock, flags);
209 for (timeout = 5; timeout > 0; timeout--)
210 inb(AD1848P(chip, REGSEL));
211 /* end of cleanup sequence */
212 for (timeout = 12000; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
213 udelay(100);
214 #if 0
215 printk("(1) timeout = %i\n", timeout);
216 #endif
217 #ifdef CONFIG_SND_DEBUG
218 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
219 snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
220 #endif
221 chip->mce_bit &= ~AD1848_MCE;
222 timeout = inb(AD1848P(chip, REGSEL));
223 outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
224 if (timeout == 0x80)
225 snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
226 if ((timeout & AD1848_MCE) == 0) {
227 spin_unlock_irqrestore(&chip->reg_lock, flags);
228 return;
230 /* calibration process */
232 for (timeout = 500; timeout > 0 && (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) == 0; timeout--);
233 if ((snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) == 0) {
234 snd_printd("mce_down - auto calibration time out (1)\n");
235 spin_unlock_irqrestore(&chip->reg_lock, flags);
236 return;
238 #if 0
239 printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
240 #endif
241 time = HZ / 4;
242 while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
243 spin_unlock_irqrestore(&chip->reg_lock, flags);
244 if (time <= 0) {
245 snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
246 return;
248 time = schedule_timeout_interruptible(time);
249 spin_lock_irqsave(&chip->reg_lock, flags);
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(KERN_ERR "mce_down - auto calibration time out (3)\n");
259 return;
261 time = schedule_timeout_interruptible(time);
262 spin_lock_irqsave(&chip->reg_lock, flags);
264 spin_unlock_irqrestore(&chip->reg_lock, flags);
265 #if 0
266 printk("(4) jiffies = %li\n", jiffies);
267 snd_printk("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL)));
268 #endif
271 static unsigned int snd_ad1848_get_count(unsigned char format,
272 unsigned int size)
274 switch (format & 0xe0) {
275 case AD1848_LINEAR_16:
276 size >>= 1;
277 break;
279 if (format & AD1848_STEREO)
280 size >>= 1;
281 return size;
284 static int snd_ad1848_trigger(struct snd_ad1848 *chip, unsigned char what,
285 int channel, int cmd)
287 int result = 0;
289 #if 0
290 printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(AD1848P(card, STATUS)));
291 #endif
292 spin_lock(&chip->reg_lock);
293 if (cmd == SNDRV_PCM_TRIGGER_START) {
294 if (chip->image[AD1848_IFACE_CTRL] & what) {
295 spin_unlock(&chip->reg_lock);
296 return 0;
298 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] |= what);
299 chip->mode |= AD1848_MODE_RUNNING;
300 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
301 if (!(chip->image[AD1848_IFACE_CTRL] & what)) {
302 spin_unlock(&chip->reg_lock);
303 return 0;
305 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL] &= ~what);
306 chip->mode &= ~AD1848_MODE_RUNNING;
307 } else {
308 result = -EINVAL;
310 spin_unlock(&chip->reg_lock);
311 return result;
315 * CODEC I/O
318 static unsigned char snd_ad1848_get_rate(unsigned int rate)
320 int i;
322 for (i = 0; i < 14; i++)
323 if (rate == rates[i])
324 return freq_bits[i];
325 snd_BUG();
326 return freq_bits[13];
329 static int snd_ad1848_ioctl(struct snd_pcm_substream *substream,
330 unsigned int cmd, void *arg)
332 return snd_pcm_lib_ioctl(substream, cmd, arg);
335 static unsigned char snd_ad1848_get_format(int format, int channels)
337 unsigned char rformat;
339 rformat = AD1848_LINEAR_8;
340 switch (format) {
341 case SNDRV_PCM_FORMAT_A_LAW: rformat = AD1848_ALAW_8; break;
342 case SNDRV_PCM_FORMAT_MU_LAW: rformat = AD1848_ULAW_8; break;
343 case SNDRV_PCM_FORMAT_S16_LE: rformat = AD1848_LINEAR_16; break;
345 if (channels > 1)
346 rformat |= AD1848_STEREO;
347 #if 0
348 snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
349 #endif
350 return rformat;
353 static void snd_ad1848_calibrate_mute(struct snd_ad1848 *chip, int mute)
355 unsigned long flags;
357 mute = mute ? 1 : 0;
358 spin_lock_irqsave(&chip->reg_lock, flags);
359 if (chip->calibrate_mute == mute) {
360 spin_unlock_irqrestore(&chip->reg_lock, flags);
361 return;
363 if (!mute) {
364 snd_ad1848_dout(chip, AD1848_LEFT_INPUT, chip->image[AD1848_LEFT_INPUT]);
365 snd_ad1848_dout(chip, AD1848_RIGHT_INPUT, chip->image[AD1848_RIGHT_INPUT]);
367 snd_ad1848_dout(chip, AD1848_AUX1_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_LEFT_INPUT]);
368 snd_ad1848_dout(chip, AD1848_AUX1_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX1_RIGHT_INPUT]);
369 snd_ad1848_dout(chip, AD1848_AUX2_LEFT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_LEFT_INPUT]);
370 snd_ad1848_dout(chip, AD1848_AUX2_RIGHT_INPUT, mute ? 0x80 : chip->image[AD1848_AUX2_RIGHT_INPUT]);
371 snd_ad1848_dout(chip, AD1848_LEFT_OUTPUT, mute ? 0x80 : chip->image[AD1848_LEFT_OUTPUT]);
372 snd_ad1848_dout(chip, AD1848_RIGHT_OUTPUT, mute ? 0x80 : chip->image[AD1848_RIGHT_OUTPUT]);
373 chip->calibrate_mute = mute;
374 spin_unlock_irqrestore(&chip->reg_lock, flags);
377 static void snd_ad1848_set_data_format(struct snd_ad1848 *chip, struct snd_pcm_hw_params *hw_params)
379 if (hw_params == NULL) {
380 chip->image[AD1848_DATA_FORMAT] = 0x20;
381 } else {
382 chip->image[AD1848_DATA_FORMAT] =
383 snd_ad1848_get_format(params_format(hw_params), params_channels(hw_params)) |
384 snd_ad1848_get_rate(params_rate(hw_params));
386 // snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]);
389 static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
391 unsigned long flags;
393 mutex_lock(&chip->open_mutex);
394 if (chip->mode & AD1848_MODE_OPEN) {
395 mutex_unlock(&chip->open_mutex);
396 return -EAGAIN;
398 snd_ad1848_mce_down(chip);
400 #ifdef SNDRV_DEBUG_MCE
401 snd_printk("open: (1)\n");
402 #endif
403 snd_ad1848_mce_up(chip);
404 spin_lock_irqsave(&chip->reg_lock, flags);
405 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
406 AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO |
407 AD1848_CALIB_MODE);
408 chip->image[AD1848_IFACE_CTRL] |= AD1848_AUTOCALIB;
409 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
410 spin_unlock_irqrestore(&chip->reg_lock, flags);
411 snd_ad1848_mce_down(chip);
413 #ifdef SNDRV_DEBUG_MCE
414 snd_printk("open: (2)\n");
415 #endif
417 snd_ad1848_set_data_format(chip, NULL);
419 snd_ad1848_mce_up(chip);
420 spin_lock_irqsave(&chip->reg_lock, flags);
421 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
422 spin_unlock_irqrestore(&chip->reg_lock, flags);
423 snd_ad1848_mce_down(chip);
425 #ifdef SNDRV_DEBUG_MCE
426 snd_printk("open: (3)\n");
427 #endif
429 /* ok. now enable and ack CODEC IRQ */
430 spin_lock_irqsave(&chip->reg_lock, flags);
431 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
432 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
433 chip->image[AD1848_PIN_CTRL] |= AD1848_IRQ_ENABLE;
434 snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
435 spin_unlock_irqrestore(&chip->reg_lock, flags);
437 chip->mode = mode;
438 mutex_unlock(&chip->open_mutex);
440 return 0;
443 static void snd_ad1848_close(struct snd_ad1848 *chip)
445 unsigned long flags;
447 mutex_lock(&chip->open_mutex);
448 if (!chip->mode) {
449 mutex_unlock(&chip->open_mutex);
450 return;
452 /* disable IRQ */
453 spin_lock_irqsave(&chip->reg_lock, flags);
454 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
455 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
456 chip->image[AD1848_PIN_CTRL] &= ~AD1848_IRQ_ENABLE;
457 snd_ad1848_out(chip, AD1848_PIN_CTRL, chip->image[AD1848_PIN_CTRL]);
458 spin_unlock_irqrestore(&chip->reg_lock, flags);
460 /* now disable capture & playback */
462 snd_ad1848_mce_up(chip);
463 spin_lock_irqsave(&chip->reg_lock, flags);
464 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO |
465 AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
466 snd_ad1848_out(chip, AD1848_IFACE_CTRL, chip->image[AD1848_IFACE_CTRL]);
467 spin_unlock_irqrestore(&chip->reg_lock, flags);
468 snd_ad1848_mce_down(chip);
470 /* clear IRQ again */
471 spin_lock_irqsave(&chip->reg_lock, flags);
472 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
473 outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
474 spin_unlock_irqrestore(&chip->reg_lock, flags);
476 chip->mode = 0;
477 mutex_unlock(&chip->open_mutex);
481 * ok.. exported functions..
484 static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream,
485 int cmd)
487 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
488 return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd);
491 static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream,
492 int cmd)
494 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
495 return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd);
498 static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream,
499 struct snd_pcm_hw_params *hw_params)
501 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
502 unsigned long flags;
503 int err;
505 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
506 return err;
507 snd_ad1848_calibrate_mute(chip, 1);
508 snd_ad1848_set_data_format(chip, hw_params);
509 snd_ad1848_mce_up(chip);
510 spin_lock_irqsave(&chip->reg_lock, flags);
511 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
512 spin_unlock_irqrestore(&chip->reg_lock, flags);
513 snd_ad1848_mce_down(chip);
514 snd_ad1848_calibrate_mute(chip, 0);
515 return 0;
518 static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream)
520 return snd_pcm_lib_free_pages(substream);
523 static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream)
525 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
526 struct snd_pcm_runtime *runtime = substream->runtime;
527 unsigned long flags;
528 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
529 unsigned int count = snd_pcm_lib_period_bytes(substream);
531 chip->dma_size = size;
532 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_PLAYBACK_ENABLE | AD1848_PLAYBACK_PIO);
533 snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
534 count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
535 spin_lock_irqsave(&chip->reg_lock, flags);
536 snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
537 snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
538 spin_unlock_irqrestore(&chip->reg_lock, flags);
539 return 0;
542 static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream,
543 struct snd_pcm_hw_params *hw_params)
545 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
546 unsigned long flags;
547 int err;
549 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
550 return err;
551 snd_ad1848_calibrate_mute(chip, 1);
552 snd_ad1848_set_data_format(chip, hw_params);
553 snd_ad1848_mce_up(chip);
554 spin_lock_irqsave(&chip->reg_lock, flags);
555 snd_ad1848_out(chip, AD1848_DATA_FORMAT, chip->image[AD1848_DATA_FORMAT]);
556 spin_unlock_irqrestore(&chip->reg_lock, flags);
557 snd_ad1848_mce_down(chip);
558 snd_ad1848_calibrate_mute(chip, 0);
559 return 0;
562 static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream)
564 return snd_pcm_lib_free_pages(substream);
567 static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream)
569 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
570 struct snd_pcm_runtime *runtime = substream->runtime;
571 unsigned long flags;
572 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
573 unsigned int count = snd_pcm_lib_period_bytes(substream);
575 chip->dma_size = size;
576 chip->image[AD1848_IFACE_CTRL] &= ~(AD1848_CAPTURE_ENABLE | AD1848_CAPTURE_PIO);
577 snd_dma_program(chip->dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
578 count = snd_ad1848_get_count(chip->image[AD1848_DATA_FORMAT], count) - 1;
579 spin_lock_irqsave(&chip->reg_lock, flags);
580 snd_ad1848_out(chip, AD1848_DATA_LWR_CNT, (unsigned char) count);
581 snd_ad1848_out(chip, AD1848_DATA_UPR_CNT, (unsigned char) (count >> 8));
582 spin_unlock_irqrestore(&chip->reg_lock, flags);
583 return 0;
586 static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id)
588 struct snd_ad1848 *chip = dev_id;
590 if ((chip->mode & AD1848_MODE_PLAY) && chip->playback_substream &&
591 (chip->mode & AD1848_MODE_RUNNING))
592 snd_pcm_period_elapsed(chip->playback_substream);
593 if ((chip->mode & AD1848_MODE_CAPTURE) && chip->capture_substream &&
594 (chip->mode & AD1848_MODE_RUNNING))
595 snd_pcm_period_elapsed(chip->capture_substream);
596 outb(0, AD1848P(chip, STATUS)); /* clear global interrupt bit */
597 return IRQ_HANDLED;
600 static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream)
602 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
603 size_t ptr;
605 if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
606 return 0;
607 ptr = snd_dma_pointer(chip->dma, chip->dma_size);
608 return bytes_to_frames(substream->runtime, ptr);
611 static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream)
613 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
614 size_t ptr;
616 if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
617 return 0;
618 ptr = snd_dma_pointer(chip->dma, chip->dma_size);
619 return bytes_to_frames(substream->runtime, ptr);
626 static void snd_ad1848_thinkpad_twiddle(struct snd_ad1848 *chip, int on) {
628 int tmp;
630 if (!chip->thinkpad_flag) return;
632 outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
633 tmp = inb(AD1848_THINKPAD_CTL_PORT2);
635 if (on)
636 /* turn it on */
637 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
638 else
639 /* turn it off */
640 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
642 outb(tmp, AD1848_THINKPAD_CTL_PORT2);
646 #ifdef CONFIG_PM
647 static void snd_ad1848_suspend(struct snd_ad1848 *chip)
649 snd_pcm_suspend_all(chip->pcm);
650 if (chip->thinkpad_flag)
651 snd_ad1848_thinkpad_twiddle(chip, 0);
654 static void snd_ad1848_resume(struct snd_ad1848 *chip)
656 int i;
658 if (chip->thinkpad_flag)
659 snd_ad1848_thinkpad_twiddle(chip, 1);
661 /* clear any pendings IRQ */
662 inb(AD1848P(chip, STATUS));
663 outb(0, AD1848P(chip, STATUS));
664 mb();
666 snd_ad1848_mce_down(chip);
667 for (i = 0; i < 16; i++)
668 snd_ad1848_out(chip, i, chip->image[i]);
669 snd_ad1848_mce_up(chip);
670 snd_ad1848_mce_down(chip);
672 #endif /* CONFIG_PM */
674 static int snd_ad1848_probe(struct snd_ad1848 * chip)
676 unsigned long flags;
677 int i, id, rev, ad1847;
678 unsigned char *ptr;
680 #if 0
681 snd_ad1848_debug(chip);
682 #endif
683 id = ad1847 = 0;
684 for (i = 0; i < 1000; i++) {
685 mb();
686 if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
687 udelay(500);
688 else {
689 spin_lock_irqsave(&chip->reg_lock, flags);
690 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
691 snd_ad1848_out(chip, AD1848_LEFT_INPUT, 0xaa);
692 snd_ad1848_out(chip, AD1848_RIGHT_INPUT, 0x45);
693 rev = snd_ad1848_in(chip, AD1848_RIGHT_INPUT);
694 if (rev == 0x65) {
695 spin_unlock_irqrestore(&chip->reg_lock, flags);
696 id = 1;
697 ad1847 = 1;
698 break;
700 if (snd_ad1848_in(chip, AD1848_LEFT_INPUT) == 0xaa && rev == 0x45) {
701 spin_unlock_irqrestore(&chip->reg_lock, flags);
702 id = 1;
703 break;
705 spin_unlock_irqrestore(&chip->reg_lock, flags);
708 if (id != 1)
709 return -ENODEV; /* no valid device found */
710 if (chip->hardware == AD1848_HW_DETECT) {
711 if (ad1847) {
712 chip->hardware = AD1848_HW_AD1847;
713 } else {
714 chip->hardware = AD1848_HW_AD1848;
715 rev = snd_ad1848_in(chip, AD1848_MISC_INFO);
716 if (rev & 0x80) {
717 chip->hardware = AD1848_HW_CS4248;
718 } else if ((rev & 0x0f) == 0x0a) {
719 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x40);
720 for (i = 0; i < 16; ++i) {
721 if (snd_ad1848_in(chip, i) != snd_ad1848_in(chip, i + 16)) {
722 chip->hardware = AD1848_HW_CMI8330;
723 break;
726 snd_ad1848_out(chip, AD1848_MISC_INFO, 0x00);
730 spin_lock_irqsave(&chip->reg_lock, flags);
731 inb(AD1848P(chip, STATUS)); /* clear any pendings IRQ */
732 outb(0, AD1848P(chip, STATUS));
733 mb();
734 spin_unlock_irqrestore(&chip->reg_lock, flags);
736 chip->image[AD1848_MISC_INFO] = 0x00;
737 chip->image[AD1848_IFACE_CTRL] =
738 (chip->image[AD1848_IFACE_CTRL] & ~AD1848_SINGLE_DMA) | AD1848_SINGLE_DMA;
739 ptr = (unsigned char *) &chip->image;
740 snd_ad1848_mce_down(chip);
741 spin_lock_irqsave(&chip->reg_lock, flags);
742 for (i = 0; i < 16; i++) /* ok.. fill all AD1848 registers */
743 snd_ad1848_out(chip, i, *ptr++);
744 spin_unlock_irqrestore(&chip->reg_lock, flags);
745 snd_ad1848_mce_up(chip);
746 snd_ad1848_mce_down(chip);
747 return 0; /* all things are ok.. */
754 static struct snd_pcm_hardware snd_ad1848_playback =
756 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
757 SNDRV_PCM_INFO_MMAP_VALID),
758 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
759 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
760 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
761 .rate_min = 5510,
762 .rate_max = 48000,
763 .channels_min = 1,
764 .channels_max = 2,
765 .buffer_bytes_max = (128*1024),
766 .period_bytes_min = 64,
767 .period_bytes_max = (128*1024),
768 .periods_min = 1,
769 .periods_max = 1024,
770 .fifo_size = 0,
773 static struct snd_pcm_hardware snd_ad1848_capture =
775 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
776 SNDRV_PCM_INFO_MMAP_VALID),
777 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
778 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE),
779 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
780 .rate_min = 5510,
781 .rate_max = 48000,
782 .channels_min = 1,
783 .channels_max = 2,
784 .buffer_bytes_max = (128*1024),
785 .period_bytes_min = 64,
786 .period_bytes_max = (128*1024),
787 .periods_min = 1,
788 .periods_max = 1024,
789 .fifo_size = 0,
796 static int snd_ad1848_playback_open(struct snd_pcm_substream *substream)
798 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
799 struct snd_pcm_runtime *runtime = substream->runtime;
800 int err;
802 if ((err = snd_ad1848_open(chip, AD1848_MODE_PLAY)) < 0)
803 return err;
804 chip->playback_substream = substream;
805 runtime->hw = snd_ad1848_playback;
806 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max);
807 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max);
808 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
809 return 0;
812 static int snd_ad1848_capture_open(struct snd_pcm_substream *substream)
814 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
815 struct snd_pcm_runtime *runtime = substream->runtime;
816 int err;
818 if ((err = snd_ad1848_open(chip, AD1848_MODE_CAPTURE)) < 0)
819 return err;
820 chip->capture_substream = substream;
821 runtime->hw = snd_ad1848_capture;
822 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.buffer_bytes_max);
823 snd_pcm_limit_isa_dma_size(chip->dma, &runtime->hw.period_bytes_max);
824 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
825 return 0;
828 static int snd_ad1848_playback_close(struct snd_pcm_substream *substream)
830 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
832 chip->mode &= ~AD1848_MODE_PLAY;
833 chip->playback_substream = NULL;
834 snd_ad1848_close(chip);
835 return 0;
838 static int snd_ad1848_capture_close(struct snd_pcm_substream *substream)
840 struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
842 chip->mode &= ~AD1848_MODE_CAPTURE;
843 chip->capture_substream = NULL;
844 snd_ad1848_close(chip);
845 return 0;
848 static int snd_ad1848_free(struct snd_ad1848 *chip)
850 release_and_free_resource(chip->res_port);
851 if (chip->irq >= 0)
852 free_irq(chip->irq, (void *) chip);
853 if (chip->dma >= 0) {
854 snd_dma_disable(chip->dma);
855 free_dma(chip->dma);
857 kfree(chip);
858 return 0;
861 static int snd_ad1848_dev_free(struct snd_device *device)
863 struct snd_ad1848 *chip = device->device_data;
864 return snd_ad1848_free(chip);
867 static const char *snd_ad1848_chip_id(struct snd_ad1848 *chip)
869 switch (chip->hardware) {
870 case AD1848_HW_AD1847: return "AD1847";
871 case AD1848_HW_AD1848: return "AD1848";
872 case AD1848_HW_CS4248: return "CS4248";
873 case AD1848_HW_CMI8330: return "CMI8330/C3D";
874 default: return "???";
878 int snd_ad1848_create(struct snd_card *card,
879 unsigned long port,
880 int irq, int dma,
881 unsigned short hardware,
882 struct snd_ad1848 ** rchip)
884 static struct snd_device_ops ops = {
885 .dev_free = snd_ad1848_dev_free,
887 struct snd_ad1848 *chip;
888 int err;
890 *rchip = NULL;
891 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
892 if (chip == NULL)
893 return -ENOMEM;
894 spin_lock_init(&chip->reg_lock);
895 mutex_init(&chip->open_mutex);
896 chip->card = card;
897 chip->port = port;
898 chip->irq = -1;
899 chip->dma = -1;
900 chip->hardware = hardware;
901 memcpy(&chip->image, &snd_ad1848_original_image, sizeof(snd_ad1848_original_image));
903 if ((chip->res_port = request_region(port, 4, "AD1848")) == NULL) {
904 snd_printk(KERN_ERR "ad1848: can't grab port 0x%lx\n", port);
905 snd_ad1848_free(chip);
906 return -EBUSY;
908 if (request_irq(irq, snd_ad1848_interrupt, IRQF_DISABLED, "AD1848", (void *) chip)) {
909 snd_printk(KERN_ERR "ad1848: can't grab IRQ %d\n", irq);
910 snd_ad1848_free(chip);
911 return -EBUSY;
913 chip->irq = irq;
914 if (request_dma(dma, "AD1848")) {
915 snd_printk(KERN_ERR "ad1848: can't grab DMA %d\n", dma);
916 snd_ad1848_free(chip);
917 return -EBUSY;
919 chip->dma = dma;
921 if (hardware == AD1848_HW_THINKPAD) {
922 chip->thinkpad_flag = 1;
923 chip->hardware = AD1848_HW_DETECT; /* reset */
924 snd_ad1848_thinkpad_twiddle(chip, 1);
927 if (snd_ad1848_probe(chip) < 0) {
928 snd_ad1848_free(chip);
929 return -ENODEV;
932 /* Register device */
933 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
934 snd_ad1848_free(chip);
935 return err;
938 #ifdef CONFIG_PM
939 chip->suspend = snd_ad1848_suspend;
940 chip->resume = snd_ad1848_resume;
941 #endif
943 *rchip = chip;
944 return 0;
947 EXPORT_SYMBOL(snd_ad1848_create);
949 static struct snd_pcm_ops snd_ad1848_playback_ops = {
950 .open = snd_ad1848_playback_open,
951 .close = snd_ad1848_playback_close,
952 .ioctl = snd_ad1848_ioctl,
953 .hw_params = snd_ad1848_playback_hw_params,
954 .hw_free = snd_ad1848_playback_hw_free,
955 .prepare = snd_ad1848_playback_prepare,
956 .trigger = snd_ad1848_playback_trigger,
957 .pointer = snd_ad1848_playback_pointer,
960 static struct snd_pcm_ops snd_ad1848_capture_ops = {
961 .open = snd_ad1848_capture_open,
962 .close = snd_ad1848_capture_close,
963 .ioctl = snd_ad1848_ioctl,
964 .hw_params = snd_ad1848_capture_hw_params,
965 .hw_free = snd_ad1848_capture_hw_free,
966 .prepare = snd_ad1848_capture_prepare,
967 .trigger = snd_ad1848_capture_trigger,
968 .pointer = snd_ad1848_capture_pointer,
971 int snd_ad1848_pcm(struct snd_ad1848 *chip, int device, struct snd_pcm **rpcm)
973 struct snd_pcm *pcm;
974 int err;
976 if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0)
977 return err;
979 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops);
980 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops);
982 pcm->private_data = chip;
983 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
984 strcpy(pcm->name, snd_ad1848_chip_id(chip));
986 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
987 snd_dma_isa_data(),
988 64*1024, chip->dma > 3 ? 128*1024 : 64*1024);
990 chip->pcm = pcm;
991 if (rpcm)
992 *rpcm = pcm;
993 return 0;
996 EXPORT_SYMBOL(snd_ad1848_pcm);
998 const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction)
1000 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
1001 &snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
1004 EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
1007 * MIXER part
1010 static int snd_ad1848_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1012 static char *texts[4] = {
1013 "Line", "Aux", "Mic", "Mix"
1016 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1017 uinfo->count = 2;
1018 uinfo->value.enumerated.items = 4;
1019 if (uinfo->value.enumerated.item > 3)
1020 uinfo->value.enumerated.item = 3;
1021 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1022 return 0;
1025 static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1027 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1028 unsigned long flags;
1030 spin_lock_irqsave(&chip->reg_lock, flags);
1031 ucontrol->value.enumerated.item[0] = (chip->image[AD1848_LEFT_INPUT] & AD1848_MIXS_ALL) >> 6;
1032 ucontrol->value.enumerated.item[1] = (chip->image[AD1848_RIGHT_INPUT] & AD1848_MIXS_ALL) >> 6;
1033 spin_unlock_irqrestore(&chip->reg_lock, flags);
1034 return 0;
1037 static int snd_ad1848_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1039 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1040 unsigned long flags;
1041 unsigned short left, right;
1042 int change;
1044 if (ucontrol->value.enumerated.item[0] > 3 ||
1045 ucontrol->value.enumerated.item[1] > 3)
1046 return -EINVAL;
1047 left = ucontrol->value.enumerated.item[0] << 6;
1048 right = ucontrol->value.enumerated.item[1] << 6;
1049 spin_lock_irqsave(&chip->reg_lock, flags);
1050 left = (chip->image[AD1848_LEFT_INPUT] & ~AD1848_MIXS_ALL) | left;
1051 right = (chip->image[AD1848_RIGHT_INPUT] & ~AD1848_MIXS_ALL) | right;
1052 change = left != chip->image[AD1848_LEFT_INPUT] ||
1053 right != chip->image[AD1848_RIGHT_INPUT];
1054 snd_ad1848_out(chip, AD1848_LEFT_INPUT, left);
1055 snd_ad1848_out(chip, AD1848_RIGHT_INPUT, right);
1056 spin_unlock_irqrestore(&chip->reg_lock, flags);
1057 return change;
1060 static int snd_ad1848_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1062 int mask = (kcontrol->private_value >> 16) & 0xff;
1064 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1065 uinfo->count = 1;
1066 uinfo->value.integer.min = 0;
1067 uinfo->value.integer.max = mask;
1068 return 0;
1071 static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1073 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1074 unsigned long flags;
1075 int reg = kcontrol->private_value & 0xff;
1076 int shift = (kcontrol->private_value >> 8) & 0xff;
1077 int mask = (kcontrol->private_value >> 16) & 0xff;
1078 int invert = (kcontrol->private_value >> 24) & 0xff;
1080 spin_lock_irqsave(&chip->reg_lock, flags);
1081 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1082 spin_unlock_irqrestore(&chip->reg_lock, flags);
1083 if (invert)
1084 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1085 return 0;
1088 static int snd_ad1848_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1090 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1091 unsigned long flags;
1092 int reg = kcontrol->private_value & 0xff;
1093 int shift = (kcontrol->private_value >> 8) & 0xff;
1094 int mask = (kcontrol->private_value >> 16) & 0xff;
1095 int invert = (kcontrol->private_value >> 24) & 0xff;
1096 int change;
1097 unsigned short val;
1099 val = (ucontrol->value.integer.value[0] & mask);
1100 if (invert)
1101 val = mask - val;
1102 val <<= shift;
1103 spin_lock_irqsave(&chip->reg_lock, flags);
1104 val = (chip->image[reg] & ~(mask << shift)) | val;
1105 change = val != chip->image[reg];
1106 snd_ad1848_out(chip, reg, val);
1107 spin_unlock_irqrestore(&chip->reg_lock, flags);
1108 return change;
1111 static int snd_ad1848_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1113 int mask = (kcontrol->private_value >> 24) & 0xff;
1115 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1116 uinfo->count = 2;
1117 uinfo->value.integer.min = 0;
1118 uinfo->value.integer.max = mask;
1119 return 0;
1122 static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1124 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1125 unsigned long flags;
1126 int left_reg = kcontrol->private_value & 0xff;
1127 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1128 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1129 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1130 int mask = (kcontrol->private_value >> 24) & 0xff;
1131 int invert = (kcontrol->private_value >> 22) & 1;
1133 spin_lock_irqsave(&chip->reg_lock, flags);
1134 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1135 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1136 spin_unlock_irqrestore(&chip->reg_lock, flags);
1137 if (invert) {
1138 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1139 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1141 return 0;
1144 static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1146 struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
1147 unsigned long flags;
1148 int left_reg = kcontrol->private_value & 0xff;
1149 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1150 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1151 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1152 int mask = (kcontrol->private_value >> 24) & 0xff;
1153 int invert = (kcontrol->private_value >> 22) & 1;
1154 int change;
1155 unsigned short val1, val2;
1157 val1 = ucontrol->value.integer.value[0] & mask;
1158 val2 = ucontrol->value.integer.value[1] & mask;
1159 if (invert) {
1160 val1 = mask - val1;
1161 val2 = mask - val2;
1163 val1 <<= shift_left;
1164 val2 <<= shift_right;
1165 spin_lock_irqsave(&chip->reg_lock, flags);
1166 if (left_reg != right_reg) {
1167 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1168 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1169 change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1170 snd_ad1848_out(chip, left_reg, val1);
1171 snd_ad1848_out(chip, right_reg, val2);
1172 } else {
1173 val1 = (chip->image[left_reg] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
1174 change = val1 != chip->image[left_reg];
1175 snd_ad1848_out(chip, left_reg, val1);
1177 spin_unlock_irqrestore(&chip->reg_lock, flags);
1178 return change;
1183 int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip,
1184 const struct ad1848_mix_elem *c)
1186 static struct snd_kcontrol_new newctls[] = {
1187 [AD1848_MIX_SINGLE] = {
1188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1189 .info = snd_ad1848_info_single,
1190 .get = snd_ad1848_get_single,
1191 .put = snd_ad1848_put_single,
1193 [AD1848_MIX_DOUBLE] = {
1194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1195 .info = snd_ad1848_info_double,
1196 .get = snd_ad1848_get_double,
1197 .put = snd_ad1848_put_double,
1199 [AD1848_MIX_CAPTURE] = {
1200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1201 .info = snd_ad1848_info_mux,
1202 .get = snd_ad1848_get_mux,
1203 .put = snd_ad1848_put_mux,
1206 struct snd_kcontrol *ctl;
1207 int err;
1209 ctl = snd_ctl_new1(&newctls[c->type], chip);
1210 if (! ctl)
1211 return -ENOMEM;
1212 strlcpy(ctl->id.name, c->name, sizeof(ctl->id.name));
1213 ctl->id.index = c->index;
1214 ctl->private_value = c->private_value;
1215 if (c->tlv) {
1216 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1217 ctl->tlv.p = c->tlv;
1219 if ((err = snd_ctl_add(chip->card, ctl)) < 0)
1220 return err;
1221 return 0;
1224 EXPORT_SYMBOL(snd_ad1848_add_ctl_elem);
1226 static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
1227 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
1228 static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
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_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1,
1233 db_scale_6bit),
1234 AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1235 AD1848_DOUBLE_TLV("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
1236 db_scale_5bit_12db_max),
1237 AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1238 AD1848_DOUBLE_TLV("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
1239 db_scale_5bit_12db_max),
1240 AD1848_DOUBLE_TLV("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0,
1241 db_scale_rec_gain),
1243 .name = "Capture Source",
1244 .type = AD1848_MIX_CAPTURE,
1246 AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0),
1247 AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0,
1248 db_scale_6bit),
1251 int snd_ad1848_mixer(struct snd_ad1848 *chip)
1253 struct snd_card *card;
1254 struct snd_pcm *pcm;
1255 unsigned int idx;
1256 int err;
1258 snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
1260 pcm = chip->pcm;
1261 card = chip->card;
1263 strcpy(card->mixername, pcm->name);
1265 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++)
1266 if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0)
1267 return err;
1269 return 0;
1272 EXPORT_SYMBOL(snd_ad1848_mixer);
1275 * INIT part
1278 static int __init alsa_ad1848_init(void)
1280 return 0;
1283 static void __exit alsa_ad1848_exit(void)
1287 module_init(alsa_ad1848_init)
1288 module_exit(alsa_ad1848_exit)