2 * AD1843 low level driver
4 * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
5 * Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
7 * inspired from vwsnd.c (SGI VW audio driver)
8 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/sched.h>
28 #include <linux/errno.h>
29 #include <sound/core.h>
30 #include <sound/pcm.h>
31 #include <sound/ad1843.h>
34 * AD1843 bitfield definitions. All are named as in the AD1843 data
35 * sheet, with ad1843_ prepended and individual bit numbers removed.
37 * E.g., bits LSS0 through LSS2 become ad1843_LSS.
39 * Only the bitfields we need are defined.
42 struct ad1843_bitfield
{
48 static const struct ad1843_bitfield
49 ad1843_PDNO
= { 0, 14, 1 }, /* Converter Power-Down Flag */
50 ad1843_INIT
= { 0, 15, 1 }, /* Clock Initialization Flag */
51 ad1843_RIG
= { 2, 0, 4 }, /* Right ADC Input Gain */
52 ad1843_RMGE
= { 2, 4, 1 }, /* Right ADC Mic Gain Enable */
53 ad1843_RSS
= { 2, 5, 3 }, /* Right ADC Source Select */
54 ad1843_LIG
= { 2, 8, 4 }, /* Left ADC Input Gain */
55 ad1843_LMGE
= { 2, 12, 1 }, /* Left ADC Mic Gain Enable */
56 ad1843_LSS
= { 2, 13, 3 }, /* Left ADC Source Select */
57 ad1843_RD2M
= { 3, 0, 5 }, /* Right DAC 2 Mix Gain/Atten */
58 ad1843_RD2MM
= { 3, 7, 1 }, /* Right DAC 2 Mix Mute */
59 ad1843_LD2M
= { 3, 8, 5 }, /* Left DAC 2 Mix Gain/Atten */
60 ad1843_LD2MM
= { 3, 15, 1 }, /* Left DAC 2 Mix Mute */
61 ad1843_RX1M
= { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */
62 ad1843_RX1MM
= { 4, 7, 1 }, /* Right Aux 1 Mix Mute */
63 ad1843_LX1M
= { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */
64 ad1843_LX1MM
= { 4, 15, 1 }, /* Left Aux 1 Mix Mute */
65 ad1843_RX2M
= { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */
66 ad1843_RX2MM
= { 5, 7, 1 }, /* Right Aux 2 Mix Mute */
67 ad1843_LX2M
= { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */
68 ad1843_LX2MM
= { 5, 15, 1 }, /* Left Aux 2 Mix Mute */
69 ad1843_RMCM
= { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */
70 ad1843_RMCMM
= { 7, 7, 1 }, /* Right Mic Mix Mute */
71 ad1843_LMCM
= { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */
72 ad1843_LMCMM
= { 7, 15, 1 }, /* Left Mic Mix Mute */
73 ad1843_HPOS
= { 8, 4, 1 }, /* Headphone Output Voltage Swing */
74 ad1843_HPOM
= { 8, 5, 1 }, /* Headphone Output Mute */
75 ad1843_MPOM
= { 8, 6, 1 }, /* Mono Output Mute */
76 ad1843_RDA1G
= { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */
77 ad1843_RDA1GM
= { 9, 7, 1 }, /* Right DAC1 Analog Mute */
78 ad1843_LDA1G
= { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */
79 ad1843_LDA1GM
= { 9, 15, 1 }, /* Left DAC1 Analog Mute */
80 ad1843_RDA2G
= { 10, 0, 6 }, /* Right DAC2 Analog/Digital Gain */
81 ad1843_RDA2GM
= { 10, 7, 1 }, /* Right DAC2 Analog Mute */
82 ad1843_LDA2G
= { 10, 8, 6 }, /* Left DAC2 Analog/Digital Gain */
83 ad1843_LDA2GM
= { 10, 15, 1 }, /* Left DAC2 Analog Mute */
84 ad1843_RDA1AM
= { 11, 7, 1 }, /* Right DAC1 Digital Mute */
85 ad1843_LDA1AM
= { 11, 15, 1 }, /* Left DAC1 Digital Mute */
86 ad1843_RDA2AM
= { 12, 7, 1 }, /* Right DAC2 Digital Mute */
87 ad1843_LDA2AM
= { 12, 15, 1 }, /* Left DAC2 Digital Mute */
88 ad1843_ADLC
= { 15, 0, 2 }, /* ADC Left Sample Rate Source */
89 ad1843_ADRC
= { 15, 2, 2 }, /* ADC Right Sample Rate Source */
90 ad1843_DA1C
= { 15, 8, 2 }, /* DAC1 Sample Rate Source */
91 ad1843_DA2C
= { 15, 10, 2 }, /* DAC2 Sample Rate Source */
92 ad1843_C1C
= { 17, 0, 16 }, /* Clock 1 Sample Rate Select */
93 ad1843_C2C
= { 20, 0, 16 }, /* Clock 2 Sample Rate Select */
94 ad1843_C3C
= { 23, 0, 16 }, /* Clock 3 Sample Rate Select */
95 ad1843_DAADL
= { 25, 4, 2 }, /* Digital ADC Left Source Select */
96 ad1843_DAADR
= { 25, 6, 2 }, /* Digital ADC Right Source Select */
97 ad1843_DAMIX
= { 25, 14, 1 }, /* DAC Digital Mix Enable */
98 ad1843_DRSFLT
= { 25, 15, 1 }, /* Digital Reampler Filter Mode */
99 ad1843_ADLF
= { 26, 0, 2 }, /* ADC Left Channel Data Format */
100 ad1843_ADRF
= { 26, 2, 2 }, /* ADC Right Channel Data Format */
101 ad1843_ADTLK
= { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */
102 ad1843_SCF
= { 26, 7, 1 }, /* SCLK Frequency Select */
103 ad1843_DA1F
= { 26, 8, 2 }, /* DAC1 Data Format Select */
104 ad1843_DA2F
= { 26, 10, 2 }, /* DAC2 Data Format Select */
105 ad1843_DA1SM
= { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */
106 ad1843_DA2SM
= { 26, 15, 1 }, /* DAC2 Stereo/Mono Mode Select */
107 ad1843_ADLEN
= { 27, 0, 1 }, /* ADC Left Channel Enable */
108 ad1843_ADREN
= { 27, 1, 1 }, /* ADC Right Channel Enable */
109 ad1843_AAMEN
= { 27, 4, 1 }, /* Analog to Analog Mix Enable */
110 ad1843_ANAEN
= { 27, 7, 1 }, /* Analog Channel Enable */
111 ad1843_DA1EN
= { 27, 8, 1 }, /* DAC1 Enable */
112 ad1843_DA2EN
= { 27, 9, 1 }, /* DAC2 Enable */
113 ad1843_DDMEN
= { 27, 12, 1 }, /* DAC2 to DAC1 Mix Enable */
114 ad1843_C1EN
= { 28, 11, 1 }, /* Clock Generator 1 Enable */
115 ad1843_C2EN
= { 28, 12, 1 }, /* Clock Generator 2 Enable */
116 ad1843_C3EN
= { 28, 13, 1 }, /* Clock Generator 3 Enable */
117 ad1843_PDNI
= { 28, 15, 1 }; /* Converter Power Down */
120 * The various registers of the AD1843 use three different formats for
121 * specifying gain. The ad1843_gain structure parameterizes the
126 int negative
; /* nonzero if gain is negative. */
127 const struct ad1843_bitfield
*lfield
;
128 const struct ad1843_bitfield
*rfield
;
129 const struct ad1843_bitfield
*lmute
;
130 const struct ad1843_bitfield
*rmute
;
133 static const struct ad1843_gain ad1843_gain_RECLEV
= {
135 .lfield
= &ad1843_LIG
,
136 .rfield
= &ad1843_RIG
138 static const struct ad1843_gain ad1843_gain_LINE
= {
140 .lfield
= &ad1843_LX1M
,
141 .rfield
= &ad1843_RX1M
,
142 .lmute
= &ad1843_LX1MM
,
143 .rmute
= &ad1843_RX1MM
145 static const struct ad1843_gain ad1843_gain_LINE_2
= {
147 .lfield
= &ad1843_LDA2G
,
148 .rfield
= &ad1843_RDA2G
,
149 .lmute
= &ad1843_LDA2GM
,
150 .rmute
= &ad1843_RDA2GM
152 static const struct ad1843_gain ad1843_gain_MIC
= {
154 .lfield
= &ad1843_LMCM
,
155 .rfield
= &ad1843_RMCM
,
156 .lmute
= &ad1843_LMCMM
,
157 .rmute
= &ad1843_RMCMM
159 static const struct ad1843_gain ad1843_gain_PCM_0
= {
161 .lfield
= &ad1843_LDA1G
,
162 .rfield
= &ad1843_RDA1G
,
163 .lmute
= &ad1843_LDA1GM
,
164 .rmute
= &ad1843_RDA1GM
166 static const struct ad1843_gain ad1843_gain_PCM_1
= {
168 .lfield
= &ad1843_LD2M
,
169 .rfield
= &ad1843_RD2M
,
170 .lmute
= &ad1843_LD2MM
,
171 .rmute
= &ad1843_RD2MM
174 static const struct ad1843_gain
*ad1843_gain
[AD1843_GAIN_SIZE
] =
184 /* read the current value of an AD1843 bitfield. */
186 static int ad1843_read_bits(struct snd_ad1843
*ad1843
,
187 const struct ad1843_bitfield
*field
)
191 w
= ad1843
->read(ad1843
->chip
, field
->reg
);
192 return w
>> field
->lo_bit
& ((1 << field
->nbits
) - 1);
196 * write a new value to an AD1843 bitfield and return the old value.
199 static int ad1843_write_bits(struct snd_ad1843
*ad1843
,
200 const struct ad1843_bitfield
*field
,
203 int w
, mask
, oldval
, newbits
;
205 w
= ad1843
->read(ad1843
->chip
, field
->reg
);
206 mask
= ((1 << field
->nbits
) - 1) << field
->lo_bit
;
207 oldval
= (w
& mask
) >> field
->lo_bit
;
208 newbits
= (newval
<< field
->lo_bit
) & mask
;
209 w
= (w
& ~mask
) | newbits
;
210 ad1843
->write(ad1843
->chip
, field
->reg
, w
);
216 * ad1843_read_multi reads multiple bitfields from the same AD1843
217 * register. It uses a single read cycle to do it. (Reading the
218 * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20
223 * ad1843_read_multi(ad1843, nfields,
224 * &ad1843_FIELD1, &val1,
225 * &ad1843_FIELD2, &val2, ...);
228 static void ad1843_read_multi(struct snd_ad1843
*ad1843
, int argcount
, ...)
231 const struct ad1843_bitfield
*fp
;
232 int w
= 0, mask
, *value
, reg
= -1;
234 va_start(ap
, argcount
);
235 while (--argcount
>= 0) {
236 fp
= va_arg(ap
, const struct ad1843_bitfield
*);
237 value
= va_arg(ap
, int *);
240 w
= ad1843
->read(ad1843
->chip
, reg
);
243 mask
= (1 << fp
->nbits
) - 1;
244 *value
= w
>> fp
->lo_bit
& mask
;
250 * ad1843_write_multi stores multiple bitfields into the same AD1843
251 * register. It uses one read and one write cycle to do it.
255 * ad1843_write_multi(ad1843, nfields,
256 * &ad1843_FIELD1, val1,
257 * &ad1843_FIELF2, val2, ...);
260 static void ad1843_write_multi(struct snd_ad1843
*ad1843
, int argcount
, ...)
264 const struct ad1843_bitfield
*fp
;
266 int w
, m
, mask
, bits
;
272 va_start(ap
, argcount
);
273 while (--argcount
>= 0) {
274 fp
= va_arg(ap
, const struct ad1843_bitfield
*);
275 value
= va_arg(ap
, int);
279 BUG_ON(reg
!= fp
->reg
);
280 m
= ((1 << fp
->nbits
) - 1) << fp
->lo_bit
;
282 bits
|= (value
<< fp
->lo_bit
) & m
;
287 w
= ad1843
->read(ad1843
->chip
, reg
);
290 w
= (w
& ~mask
) | bits
;
291 ad1843
->write(ad1843
->chip
, reg
, w
);
294 int ad1843_get_gain_max(struct snd_ad1843
*ad1843
, int id
)
296 const struct ad1843_gain
*gp
= ad1843_gain
[id
];
299 ret
= (1 << gp
->lfield
->nbits
);
306 * ad1843_get_gain reads the specified register and extracts the gain value
307 * using the supplied gain type.
310 int ad1843_get_gain(struct snd_ad1843
*ad1843
, int id
)
313 const struct ad1843_gain
*gp
= ad1843_gain
[id
];
314 unsigned short mask
= (1 << gp
->lfield
->nbits
) - 1;
316 ad1843_read_multi(ad1843
, 2, gp
->lfield
, &lg
, gp
->rfield
, &rg
);
322 ad1843_read_multi(ad1843
, 2, gp
->lmute
, &lm
, gp
->rmute
, &rm
);
328 return lg
<< 0 | rg
<< 8;
332 * Set an audio channel's gain.
334 * Returns the new gain, which may be lower than the old gain.
337 int ad1843_set_gain(struct snd_ad1843
*ad1843
, int id
, int newval
)
339 const struct ad1843_gain
*gp
= ad1843_gain
[id
];
340 unsigned short mask
= (1 << gp
->lfield
->nbits
) - 1;
342 int lg
= (newval
>> 0) & mask
;
343 int rg
= (newval
>> 8) & mask
;
344 int lm
= (lg
== 0) ? 1 : 0;
345 int rm
= (rg
== 0) ? 1 : 0;
352 ad1843_write_multi(ad1843
, 2, gp
->lmute
, lm
, gp
->rmute
, rm
);
353 ad1843_write_multi(ad1843
, 2, gp
->lfield
, lg
, gp
->rfield
, rg
);
354 return ad1843_get_gain(ad1843
, id
);
357 /* Returns the current recording source */
359 int ad1843_get_recsrc(struct snd_ad1843
*ad1843
)
361 int val
= ad1843_read_bits(ad1843
, &ad1843_LSS
);
363 if (val
< 0 || val
> 2) {
365 ad1843_write_multi(ad1843
, 2,
366 &ad1843_LSS
, val
, &ad1843_RSS
, val
);
372 * Set recording source.
374 * Returns newsrc on success, -errno on failure.
377 int ad1843_set_recsrc(struct snd_ad1843
*ad1843
, int newsrc
)
379 if (newsrc
< 0 || newsrc
> 2)
382 ad1843_write_multi(ad1843
, 2, &ad1843_LSS
, newsrc
, &ad1843_RSS
, newsrc
);
386 /* Setup ad1843 for D/A conversion. */
388 void ad1843_setup_dac(struct snd_ad1843
*ad1843
,
390 unsigned int framerate
,
391 snd_pcm_format_t fmt
,
392 unsigned int channels
)
394 int ad_fmt
= 0, ad_mode
= 0;
397 case SNDRV_PCM_FORMAT_S8
:
400 case SNDRV_PCM_FORMAT_U8
:
403 case SNDRV_PCM_FORMAT_S16_LE
:
406 case SNDRV_PCM_FORMAT_MU_LAW
:
409 case SNDRV_PCM_FORMAT_A_LAW
:
428 ad1843_write_bits(ad1843
, &ad1843_C2C
, framerate
);
429 ad1843_write_multi(ad1843
, 2,
430 &ad1843_DA2SM
, ad_mode
,
431 &ad1843_DA2F
, ad_fmt
);
433 ad1843_write_bits(ad1843
, &ad1843_C1C
, framerate
);
434 ad1843_write_multi(ad1843
, 2,
435 &ad1843_DA1SM
, ad_mode
,
436 &ad1843_DA1F
, ad_fmt
);
440 void ad1843_shutdown_dac(struct snd_ad1843
*ad1843
, unsigned int id
)
443 ad1843_write_bits(ad1843
, &ad1843_DA2F
, 1);
445 ad1843_write_bits(ad1843
, &ad1843_DA1F
, 1);
448 void ad1843_setup_adc(struct snd_ad1843
*ad1843
,
449 unsigned int framerate
,
450 snd_pcm_format_t fmt
,
451 unsigned int channels
)
456 case SNDRV_PCM_FORMAT_S8
: da_fmt
= 0; break;
457 case SNDRV_PCM_FORMAT_U8
: da_fmt
= 0; break;
458 case SNDRV_PCM_FORMAT_S16_LE
: da_fmt
= 1; break;
459 case SNDRV_PCM_FORMAT_MU_LAW
: da_fmt
= 2; break;
460 case SNDRV_PCM_FORMAT_A_LAW
: da_fmt
= 3; break;
464 ad1843_write_bits(ad1843
, &ad1843_C3C
, framerate
);
465 ad1843_write_multi(ad1843
, 2,
466 &ad1843_ADLF
, da_fmt
, &ad1843_ADRF
, da_fmt
);
469 void ad1843_shutdown_adc(struct snd_ad1843
*ad1843
)
475 * Fully initialize the ad1843. As described in the AD1843 data
476 * sheet, section "START-UP SEQUENCE". The numbered comments are
477 * subsection headings from the data sheet. See the data sheet, pages
478 * 52-54, for more info.
480 * return 0 on success, -errno on failure. */
482 int ad1843_init(struct snd_ad1843
*ad1843
)
486 if (ad1843_read_bits(ad1843
, &ad1843_INIT
) != 0) {
487 printk(KERN_ERR
"ad1843: AD1843 won't initialize\n");
491 ad1843_write_bits(ad1843
, &ad1843_SCF
, 1);
493 /* 4. Put the conversion resources into standby. */
494 ad1843_write_bits(ad1843
, &ad1843_PDNI
, 0);
495 later
= jiffies
+ msecs_to_jiffies(500);
497 while (ad1843_read_bits(ad1843
, &ad1843_PDNO
)) {
498 if (time_after(jiffies
, later
)) {
500 "ad1843: AD1843 won't power up\n");
503 schedule_timeout_interruptible(5);
506 /* 5. Power up the clock generators and enable clock output pins. */
507 ad1843_write_multi(ad1843
, 3,
512 /* 6. Configure conversion resources while they are in standby. */
514 /* DAC1/2 use clock 1/2 as source, ADC uses clock 3. Always. */
515 ad1843_write_multi(ad1843
, 4,
521 /* 7. Enable conversion resources. */
522 ad1843_write_bits(ad1843
, &ad1843_ADTLK
, 1);
523 ad1843_write_multi(ad1843
, 7,
532 /* 8. Configure conversion resources while they are enabled. */
534 /* set gain to 0 for all channels */
535 ad1843_set_gain(ad1843
, AD1843_GAIN_RECLEV
, 0);
536 ad1843_set_gain(ad1843
, AD1843_GAIN_LINE
, 0);
537 ad1843_set_gain(ad1843
, AD1843_GAIN_LINE_2
, 0);
538 ad1843_set_gain(ad1843
, AD1843_GAIN_MIC
, 0);
539 ad1843_set_gain(ad1843
, AD1843_GAIN_PCM_0
, 0);
540 ad1843_set_gain(ad1843
, AD1843_GAIN_PCM_1
, 0);
542 /* Unmute all channels. */
544 ad1843_write_multi(ad1843
, 2, &ad1843_LDA1GM
, 0, &ad1843_RDA1GM
, 0);
546 ad1843_write_multi(ad1843
, 2, &ad1843_LDA2GM
, 0, &ad1843_RDA2GM
, 0);
548 /* Set default recording source to Line In and set
549 * mic gain to +20 dB.
551 ad1843_set_recsrc(ad1843
, 2);
552 ad1843_write_multi(ad1843
, 2, &ad1843_LMGE
, 1, &ad1843_RMGE
, 1);
554 /* Set Speaker Out level to +/- 4V and unmute it. */
555 ad1843_write_multi(ad1843
, 3,