]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/i2c/other/ak4xxx-adda.c
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[net-next-2.6.git] / sound / i2c / other / ak4xxx-adda.c
CommitLineData
1da177e4
LT
1/*
2 * ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4358 / AK4381
3 * AD and DA converters
4 *
c1017a4c 5 * Copyright (c) 2000-2004 Jaroslav Kysela <perex@perex.cz>,
1da177e4
LT
6 * Takashi Iwai <tiwai@suse.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
8f34692f 22 */
1da177e4 23
1da177e4
LT
24#include <asm/io.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/init.h>
28#include <sound/core.h>
29#include <sound/control.h>
723b2b0d 30#include <sound/tlv.h>
1da177e4 31#include <sound/ak4xxx-adda.h>
8f34692f 32#include <sound/info.h>
1da177e4 33
c1017a4c 34MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
1da177e4
LT
35MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters");
36MODULE_LICENSE("GPL");
37
723b2b0d 38/* write the given register and save the data to the cache */
cb9d24e4
TI
39void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg,
40 unsigned char val)
1da177e4
LT
41{
42 ak->ops.lock(ak, chip);
43 ak->ops.write(ak, chip, reg, val);
44
45 /* save the data */
854b66e4 46 snd_akm4xxx_set(ak, chip, reg, val);
1da177e4
LT
47 ak->ops.unlock(ak, chip);
48}
49
cb9d24e4
TI
50EXPORT_SYMBOL(snd_akm4xxx_write);
51
52/* reset procedure for AK4524 and AK4528 */
53static void ak4524_reset(struct snd_akm4xxx *ak, int state)
54{
55 unsigned int chip;
8f34692f 56 unsigned char reg;
cb9d24e4 57
cb9d24e4
TI
58 for (chip = 0; chip < ak->num_dacs/2; chip++) {
59 snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);
60 if (state)
61 continue;
62 /* DAC volumes */
8f34692f 63 for (reg = 0x04; reg < ak->total_regs; reg++)
cb9d24e4
TI
64 snd_akm4xxx_write(ak, chip, reg,
65 snd_akm4xxx_get(ak, chip, reg));
cb9d24e4
TI
66 }
67}
68
69/* reset procedure for AK4355 and AK4358 */
8f34692f 70static void ak435X_reset(struct snd_akm4xxx *ak, int state)
cb9d24e4
TI
71{
72 unsigned char reg;
73
74 if (state) {
75 snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */
76 return;
77 }
8f34692f 78 for (reg = 0x00; reg < ak->total_regs; reg++)
cb9d24e4
TI
79 if (reg != 0x01)
80 snd_akm4xxx_write(ak, 0, reg,
81 snd_akm4xxx_get(ak, 0, reg));
82 snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */
83}
84
85/* reset procedure for AK4381 */
86static void ak4381_reset(struct snd_akm4xxx *ak, int state)
87{
88 unsigned int chip;
89 unsigned char reg;
cb9d24e4
TI
90 for (chip = 0; chip < ak->num_dacs/2; chip++) {
91 snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);
92 if (state)
93 continue;
8f34692f 94 for (reg = 0x01; reg < ak->total_regs; reg++)
cb9d24e4
TI
95 snd_akm4xxx_write(ak, chip, reg,
96 snd_akm4xxx_get(ak, chip, reg));
97 }
98}
99
1da177e4
LT
100/*
101 * reset the AKM codecs
102 * @state: 1 = reset codec, 0 = restore the registers
103 *
104 * assert the reset operation and restores the register values to the chips.
105 */
97f02e05 106void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
1da177e4 107{
1da177e4
LT
108 switch (ak->type) {
109 case SND_AK4524:
110 case SND_AK4528:
8f34692f 111 case SND_AK4620:
cb9d24e4 112 ak4524_reset(ak, state);
1da177e4
LT
113 break;
114 case SND_AK4529:
115 /* FIXME: needed for ak4529? */
116 break;
117 case SND_AK4355:
8f34692f 118 ak435X_reset(ak, state);
841b23d4 119 break;
1da177e4 120 case SND_AK4358:
8f34692f 121 ak435X_reset(ak, state);
1da177e4
LT
122 break;
123 case SND_AK4381:
cb9d24e4 124 ak4381_reset(ak, state);
1da177e4 125 break;
cf93907b
TI
126 default:
127 break;
1da177e4
LT
128 }
129}
130
cb9d24e4
TI
131EXPORT_SYMBOL(snd_akm4xxx_reset);
132
723b2b0d
TI
133
134/*
135 * Volume conversion table for non-linear volumes
136 * from -63.5dB (mute) to 0dB step 0.5dB
137 *
8f34692f 138 * Used for AK4524/AK4620 input/ouput attenuation, AK4528, and
723b2b0d
TI
139 * AK5365 input attenuation
140 */
517400cb 141static const unsigned char vol_cvt_datt[128] = {
723b2b0d
TI
142 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04,
143 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06,
144 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a,
145 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f,
146 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14,
147 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1c,
148 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x23,
149 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2d,
150 0x2e, 0x30, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
151 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3e, 0x3f, 0x40,
152 0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4a,
153 0x4b, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54,
154 0x55, 0x56, 0x58, 0x59, 0x5b, 0x5c, 0x5e, 0x5f,
155 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x69,
156 0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x73,
157 0x75, 0x76, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7f,
158};
159
160/*
161 * dB tables
162 */
0cb29ea0
TI
163static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1);
164static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1);
165static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1);
166static const DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0);
723b2b0d 167
1da177e4
LT
168/*
169 * initialize all the ak4xxx chips
170 */
97f02e05 171void snd_akm4xxx_init(struct snd_akm4xxx *ak)
1da177e4 172{
0cb29ea0 173 static const unsigned char inits_ak4524[] = {
1da177e4
LT
174 0x00, 0x07, /* 0: all power up */
175 0x01, 0x00, /* 1: ADC/DAC reset */
176 0x02, 0x60, /* 2: 24bit I2S */
177 0x03, 0x19, /* 3: deemphasis off */
178 0x01, 0x03, /* 1: ADC/DAC enable */
179 0x04, 0x00, /* 4: ADC left muted */
180 0x05, 0x00, /* 5: ADC right muted */
1da177e4
LT
181 0x06, 0x00, /* 6: DAC left muted */
182 0x07, 0x00, /* 7: DAC right muted */
183 0xff, 0xff
184 };
517400cb 185 static const unsigned char inits_ak4528[] = {
1da177e4
LT
186 0x00, 0x07, /* 0: all power up */
187 0x01, 0x00, /* 1: ADC/DAC reset */
188 0x02, 0x60, /* 2: 24bit I2S */
189 0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */
190 0x01, 0x03, /* 1: ADC/DAC enable */
191 0x04, 0x00, /* 4: ADC left muted */
192 0x05, 0x00, /* 5: ADC right muted */
193 0xff, 0xff
194 };
517400cb 195 static const unsigned char inits_ak4529[] = {
1da177e4
LT
196 0x09, 0x01, /* 9: ATS=0, RSTN=1 */
197 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
198 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
199 0x01, 0x00, /* 1: ACKS=0, ADC, loop off */
200 0x02, 0xff, /* 2: LOUT1 muted */
201 0x03, 0xff, /* 3: ROUT1 muted */
202 0x04, 0xff, /* 4: LOUT2 muted */
203 0x05, 0xff, /* 5: ROUT2 muted */
204 0x06, 0xff, /* 6: LOUT3 muted */
205 0x07, 0xff, /* 7: ROUT3 muted */
206 0x0b, 0xff, /* B: LOUT4 muted */
207 0x0c, 0xff, /* C: ROUT4 muted */
208 0x08, 0x55, /* 8: deemphasis all off */
209 0xff, 0xff
210 };
517400cb 211 static const unsigned char inits_ak4355[] = {
1da177e4 212 0x01, 0x02, /* 1: reset and soft-mute */
cb9d24e4
TI
213 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
214 * disable DZF, sharp roll-off, RSTN#=0 */
1da177e4
LT
215 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
216 // 0x02, 0x2e, /* quad speed */
217 0x03, 0x01, /* 3: de-emphasis off */
218 0x04, 0x00, /* 4: LOUT1 volume muted */
219 0x05, 0x00, /* 5: ROUT1 volume muted */
220 0x06, 0x00, /* 6: LOUT2 volume muted */
221 0x07, 0x00, /* 7: ROUT2 volume muted */
222 0x08, 0x00, /* 8: LOUT3 volume muted */
223 0x09, 0x00, /* 9: ROUT3 volume muted */
224 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
225 0x01, 0x01, /* 1: un-reset, unmute */
226 0xff, 0xff
227 };
517400cb 228 static const unsigned char inits_ak4358[] = {
1da177e4 229 0x01, 0x02, /* 1: reset and soft-mute */
cb9d24e4
TI
230 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
231 * disable DZF, sharp roll-off, RSTN#=0 */
46480b3a
AB
232 0x02, 0x4e, /* 2: DA's power up, normal speed, RSTN#=0 */
233 /* 0x02, 0x6e,*/ /* quad speed */
1da177e4
LT
234 0x03, 0x01, /* 3: de-emphasis off */
235 0x04, 0x00, /* 4: LOUT1 volume muted */
236 0x05, 0x00, /* 5: ROUT1 volume muted */
237 0x06, 0x00, /* 6: LOUT2 volume muted */
238 0x07, 0x00, /* 7: ROUT2 volume muted */
239 0x08, 0x00, /* 8: LOUT3 volume muted */
240 0x09, 0x00, /* 9: ROUT3 volume muted */
241 0x0b, 0x00, /* b: LOUT4 volume muted */
242 0x0c, 0x00, /* c: ROUT4 volume muted */
243 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
244 0x01, 0x01, /* 1: un-reset, unmute */
245 0xff, 0xff
246 };
517400cb 247 static const unsigned char inits_ak4381[] = {
1da177e4 248 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
cb9d24e4
TI
249 0x01, 0x02, /* 1: de-emphasis off, normal speed,
250 * sharp roll-off, DZF off */
1da177e4
LT
251 // 0x01, 0x12, /* quad speed */
252 0x02, 0x00, /* 2: DZF disabled */
253 0x03, 0x00, /* 3: LATT 0 */
254 0x04, 0x00, /* 4: RATT 0 */
255 0x00, 0x0f, /* 0: power-up, un-reset */
256 0xff, 0xff
257 };
8f34692f
PH
258 static const unsigned char inits_ak4620[] = {
259 0x00, 0x07, /* 0: normal */
260 0x01, 0x00, /* 0: reset */
261 0x01, 0x02, /* 1: RSTAD */
262 0x01, 0x03, /* 1: RSTDA */
263 0x01, 0x0f, /* 1: normal */
264 0x02, 0x60, /* 2: 24bit I2S */
265 0x03, 0x01, /* 3: deemphasis off */
266 0x04, 0x00, /* 4: LIN muted */
267 0x05, 0x00, /* 5: RIN muted */
268 0x06, 0x00, /* 6: LOUT muted */
269 0x07, 0x00, /* 7: ROUT muted */
270 0xff, 0xff
271 };
1da177e4 272
8f34692f 273 int chip;
517400cb
TI
274 const unsigned char *ptr, *inits;
275 unsigned char reg, data;
1da177e4 276
723b2b0d
TI
277 memset(ak->images, 0, sizeof(ak->images));
278 memset(ak->volumes, 0, sizeof(ak->volumes));
279
1da177e4
LT
280 switch (ak->type) {
281 case SND_AK4524:
282 inits = inits_ak4524;
8f34692f
PH
283 ak->num_chips = ak->num_dacs / 2;
284 ak->name = "ak4524";
285 ak->total_regs = 0x08;
1da177e4
LT
286 break;
287 case SND_AK4528:
288 inits = inits_ak4528;
8f34692f
PH
289 ak->num_chips = ak->num_dacs / 2;
290 ak->name = "ak4528";
291 ak->total_regs = 0x06;
1da177e4
LT
292 break;
293 case SND_AK4529:
294 inits = inits_ak4529;
8f34692f
PH
295 ak->num_chips = 1;
296 ak->name = "ak4529";
297 ak->total_regs = 0x0d;
1da177e4
LT
298 break;
299 case SND_AK4355:
300 inits = inits_ak4355;
8f34692f
PH
301 ak->num_chips = 1;
302 ak->name = "ak4355";
303 ak->total_regs = 0x0b;
1da177e4
LT
304 break;
305 case SND_AK4358:
306 inits = inits_ak4358;
8f34692f
PH
307 ak->num_chips = 1;
308 ak->name = "ak4358";
309 ak->total_regs = 0x10;
1da177e4
LT
310 break;
311 case SND_AK4381:
312 inits = inits_ak4381;
8f34692f
PH
313 ak->num_chips = ak->num_dacs / 2;
314 ak->name = "ak4381";
315 ak->total_regs = 0x05;
1da177e4 316 break;
723b2b0d
TI
317 case SND_AK5365:
318 /* FIXME: any init sequence? */
8f34692f
PH
319 ak->num_chips = 1;
320 ak->name = "ak5365";
321 ak->total_regs = 0x08;
723b2b0d 322 return;
8f34692f
PH
323 case SND_AK4620:
324 inits = inits_ak4620;
325 ak->num_chips = ak->num_dacs / 2;
326 ak->name = "ak4620";
327 ak->total_regs = 0x08;
328 break;
1da177e4
LT
329 default:
330 snd_BUG();
331 return;
332 }
333
8f34692f 334 for (chip = 0; chip < ak->num_chips; chip++) {
1da177e4
LT
335 ptr = inits;
336 while (*ptr != 0xff) {
337 reg = *ptr++;
338 data = *ptr++;
339 snd_akm4xxx_write(ak, chip, reg, data);
8f34692f 340 udelay(10);
1da177e4
LT
341 }
342 }
343}
344
cb9d24e4
TI
345EXPORT_SYMBOL(snd_akm4xxx_init);
346
723b2b0d
TI
347/*
348 * Mixer callbacks
349 */
854b66e4 350#define AK_IPGA (1<<20) /* including IPGA */
723b2b0d
TI
351#define AK_VOL_CVT (1<<21) /* need dB conversion */
352#define AK_NEEDSMSB (1<<22) /* need MSB update bit */
353#define AK_INVERT (1<<23) /* data is inverted */
1da177e4
LT
354#define AK_GET_CHIP(val) (((val) >> 8) & 0xff)
355#define AK_GET_ADDR(val) ((val) & 0xff)
854b66e4 356#define AK_GET_SHIFT(val) (((val) >> 16) & 0x0f)
723b2b0d 357#define AK_GET_VOL_CVT(val) (((val) >> 21) & 1)
854b66e4 358#define AK_GET_IPGA(val) (((val) >> 20) & 1)
3479307f 359#define AK_GET_NEEDSMSB(val) (((val) >> 22) & 1)
1da177e4
LT
360#define AK_GET_INVERT(val) (((val) >> 23) & 1)
361#define AK_GET_MASK(val) (((val) >> 24) & 0xff)
cb9d24e4
TI
362#define AK_COMPOSE(chip,addr,shift,mask) \
363 (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
1da177e4 364
97f02e05
TI
365static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
367{
368 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
369
370 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
371 uinfo->count = 1;
372 uinfo->value.integer.min = 0;
373 uinfo->value.integer.max = mask;
374 return 0;
375}
376
97f02e05
TI
377static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
378 struct snd_ctl_elem_value *ucontrol)
1da177e4 379{
97f02e05 380 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
1da177e4
LT
381 int chip = AK_GET_CHIP(kcontrol->private_value);
382 int addr = AK_GET_ADDR(kcontrol->private_value);
3479307f 383
723b2b0d 384 ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
1da177e4
LT
385 return 0;
386}
387
723b2b0d
TI
388static int put_ak_reg(struct snd_kcontrol *kcontrol, int addr,
389 unsigned char nval)
1da177e4 390{
97f02e05 391 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
1da177e4 392 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
723b2b0d 393 int chip = AK_GET_CHIP(kcontrol->private_value);
1da177e4 394
723b2b0d
TI
395 if (snd_akm4xxx_get_vol(ak, chip, addr) == nval)
396 return 0;
397
398 snd_akm4xxx_set_vol(ak, chip, addr, nval);
854b66e4 399 if (AK_GET_VOL_CVT(kcontrol->private_value) && nval < 128)
723b2b0d 400 nval = vol_cvt_datt[nval];
854b66e4
TI
401 if (AK_GET_IPGA(kcontrol->private_value) && nval >= 128)
402 nval++; /* need to correct + 1 since both 127 and 128 are 0dB */
723b2b0d 403 if (AK_GET_INVERT(kcontrol->private_value))
1da177e4 404 nval = mask - nval;
723b2b0d 405 if (AK_GET_NEEDSMSB(kcontrol->private_value))
3479307f 406 nval |= 0x80;
841b23d4
PH
407 /* printk(KERN_DEBUG "DEBUG - AK writing reg: chip %x addr %x,
408 nval %x\n", chip, addr, nval); */
723b2b0d
TI
409 snd_akm4xxx_write(ak, chip, addr, nval);
410 return 1;
411}
412
413static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
414 struct snd_ctl_elem_value *ucontrol)
415{
02ff1324
TI
416 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
417 unsigned int val = ucontrol->value.integer.value[0];
418 if (val > mask)
419 return -EINVAL;
420 return put_ak_reg(kcontrol, AK_GET_ADDR(kcontrol->private_value), val);
1da177e4
LT
421}
422
c83c0c47 423static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol,
cb9d24e4 424 struct snd_ctl_elem_info *uinfo)
c83c0c47
JA
425{
426 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
427
428 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
429 uinfo->count = 2;
430 uinfo->value.integer.min = 0;
431 uinfo->value.integer.max = mask;
432 return 0;
433}
434
435static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol,
cb9d24e4 436 struct snd_ctl_elem_value *ucontrol)
c83c0c47
JA
437{
438 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
439 int chip = AK_GET_CHIP(kcontrol->private_value);
440 int addr = AK_GET_ADDR(kcontrol->private_value);
c83c0c47 441
723b2b0d
TI
442 ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
443 ucontrol->value.integer.value[1] = snd_akm4xxx_get_vol(ak, chip, addr+1);
c83c0c47
JA
444 return 0;
445}
446
447static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
cb9d24e4 448 struct snd_ctl_elem_value *ucontrol)
c83c0c47 449{
c83c0c47 450 int addr = AK_GET_ADDR(kcontrol->private_value);
02ff1324
TI
451 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
452 unsigned int val[2];
723b2b0d 453 int change;
c83c0c47 454
02ff1324
TI
455 val[0] = ucontrol->value.integer.value[0];
456 val[1] = ucontrol->value.integer.value[1];
457 if (val[0] > mask || val[1] > mask)
458 return -EINVAL;
459 change = put_ak_reg(kcontrol, addr, val[0]);
460 change |= put_ak_reg(kcontrol, addr + 1, val[1]);
723b2b0d 461 return change;
c83c0c47
JA
462}
463
97f02e05
TI
464static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol,
465 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
466{
467 static char *texts[4] = {
468 "44.1kHz", "Off", "48kHz", "32kHz",
469 };
470 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
471 uinfo->count = 1;
472 uinfo->value.enumerated.items = 4;
473 if (uinfo->value.enumerated.item >= 4)
474 uinfo->value.enumerated.item = 3;
cb9d24e4
TI
475 strcpy(uinfo->value.enumerated.name,
476 texts[uinfo->value.enumerated.item]);
1da177e4
LT
477 return 0;
478}
479
97f02e05
TI
480static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol,
481 struct snd_ctl_elem_value *ucontrol)
1da177e4 482{
97f02e05 483 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
1da177e4
LT
484 int chip = AK_GET_CHIP(kcontrol->private_value);
485 int addr = AK_GET_ADDR(kcontrol->private_value);
486 int shift = AK_GET_SHIFT(kcontrol->private_value);
cb9d24e4
TI
487 ucontrol->value.enumerated.item[0] =
488 (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3;
1da177e4
LT
489 return 0;
490}
491
97f02e05
TI
492static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
493 struct snd_ctl_elem_value *ucontrol)
1da177e4 494{
97f02e05 495 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
1da177e4
LT
496 int chip = AK_GET_CHIP(kcontrol->private_value);
497 int addr = AK_GET_ADDR(kcontrol->private_value);
498 int shift = AK_GET_SHIFT(kcontrol->private_value);
499 unsigned char nval = ucontrol->value.enumerated.item[0] & 3;
500 int change;
501
cb9d24e4
TI
502 nval = (nval << shift) |
503 (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift));
1da177e4
LT
504 change = snd_akm4xxx_get(ak, chip, addr) != nval;
505 if (change)
506 snd_akm4xxx_write(ak, chip, addr, nval);
507 return change;
508}
509
a5ce8890 510#define ak4xxx_switch_info snd_ctl_boolean_mono_info
30ba6e20
JV
511
512static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
513 struct snd_ctl_elem_value *ucontrol)
514{
515 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
516 int chip = AK_GET_CHIP(kcontrol->private_value);
517 int addr = AK_GET_ADDR(kcontrol->private_value);
518 int shift = AK_GET_SHIFT(kcontrol->private_value);
519 int invert = AK_GET_INVERT(kcontrol->private_value);
ea7cfcdf
PH
520 /* we observe the (1<<shift) bit only */
521 unsigned char val = snd_akm4xxx_get(ak, chip, addr) & (1<<shift);
30ba6e20
JV
522 if (invert)
523 val = ! val;
524 ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0;
525 return 0;
526}
527
528static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol)
530{
531 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
532 int chip = AK_GET_CHIP(kcontrol->private_value);
533 int addr = AK_GET_ADDR(kcontrol->private_value);
534 int shift = AK_GET_SHIFT(kcontrol->private_value);
535 int invert = AK_GET_INVERT(kcontrol->private_value);
536 long flag = ucontrol->value.integer.value[0];
537 unsigned char val, oval;
538 int change;
539
540 if (invert)
541 flag = ! flag;
542 oval = snd_akm4xxx_get(ak, chip, addr);
543 if (flag)
544 val = oval | (1<<shift);
545 else
546 val = oval & ~(1<<shift);
547 change = (oval != val);
548 if (change)
549 snd_akm4xxx_write(ak, chip, addr, val);
550 return change;
551}
552
a58e7cb1
JV
553#define AK5365_NUM_INPUTS 5
554
02ff1324
TI
555static int ak4xxx_capture_num_inputs(struct snd_akm4xxx *ak, int mixer_ch)
556{
557 int num_names;
558 const char **input_names;
559
560 input_names = ak->adc_info[mixer_ch].input_names;
561 num_names = 0;
562 while (num_names < AK5365_NUM_INPUTS && input_names[num_names])
563 ++num_names;
564 return num_names;
565}
566
a58e7cb1
JV
567static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_info *uinfo)
569{
570 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
571 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
572 const char **input_names;
573 int num_names, idx;
574
02ff1324
TI
575 num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
576 if (!num_names)
577 return -EINVAL;
a58e7cb1
JV
578 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
579 uinfo->count = 1;
580 uinfo->value.enumerated.items = num_names;
581 idx = uinfo->value.enumerated.item;
582 if (idx >= num_names)
583 return -EINVAL;
02ff1324 584 input_names = ak->adc_info[mixer_ch].input_names;
a58e7cb1
JV
585 strncpy(uinfo->value.enumerated.name, input_names[idx],
586 sizeof(uinfo->value.enumerated.name));
587 return 0;
588}
589
590static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol,
591 struct snd_ctl_elem_value *ucontrol)
592{
593 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
594 int chip = AK_GET_CHIP(kcontrol->private_value);
595 int addr = AK_GET_ADDR(kcontrol->private_value);
596 int mask = AK_GET_MASK(kcontrol->private_value);
597 unsigned char val;
598
599 val = snd_akm4xxx_get(ak, chip, addr) & mask;
600 ucontrol->value.enumerated.item[0] = val;
601 return 0;
602}
603
604static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol,
605 struct snd_ctl_elem_value *ucontrol)
606{
607 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
02ff1324 608 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
a58e7cb1
JV
609 int chip = AK_GET_CHIP(kcontrol->private_value);
610 int addr = AK_GET_ADDR(kcontrol->private_value);
611 int mask = AK_GET_MASK(kcontrol->private_value);
612 unsigned char oval, val;
02ff1324
TI
613 int num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
614
615 if (ucontrol->value.enumerated.item[0] >= num_names)
616 return -EINVAL;
a58e7cb1
JV
617
618 oval = snd_akm4xxx_get(ak, chip, addr);
619 val = oval & ~mask;
620 val |= ucontrol->value.enumerated.item[0] & mask;
621 if (val != oval) {
622 snd_akm4xxx_write(ak, chip, addr, val);
623 return 1;
624 }
625 return 0;
626}
627
1da177e4
LT
628/*
629 * build AK4xxx controls
630 */
631
723b2b0d 632static int build_dac_controls(struct snd_akm4xxx *ak)
1da177e4 633{
723b2b0d
TI
634 int idx, err, mixer_ch, num_stereo;
635 struct snd_kcontrol_new knew;
1da177e4 636
723b2b0d 637 mixer_ch = 0;
c83c0c47 638 for (idx = 0; idx < ak->num_dacs; ) {
ea7cfcdf
PH
639 /* mute control for Revolution 7.1 - AK4381 */
640 if (ak->type == SND_AK4381
641 && ak->dac_info[mixer_ch].switch_name) {
642 memset(&knew, 0, sizeof(knew));
643 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
644 knew.count = 1;
645 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
646 knew.name = ak->dac_info[mixer_ch].switch_name;
647 knew.info = ak4xxx_switch_info;
648 knew.get = ak4xxx_switch_get;
649 knew.put = ak4xxx_switch_put;
650 knew.access = 0;
651 /* register 1, bit 0 (SMUTE): 0 = normal operation,
652 1 = mute */
653 knew.private_value =
654 AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT;
655 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
656 if (err < 0)
657 return err;
658 }
723b2b0d
TI
659 memset(&knew, 0, sizeof(knew));
660 if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) {
661 knew.name = "DAC Volume";
662 knew.index = mixer_ch + ak->idx_offset * 2;
c83c0c47 663 num_stereo = 1;
c83c0c47 664 } else {
723b2b0d
TI
665 knew.name = ak->dac_info[mixer_ch].name;
666 num_stereo = ak->dac_info[mixer_ch].num_channels;
c83c0c47 667 }
723b2b0d
TI
668 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
669 knew.count = 1;
670 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
671 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
c83c0c47 672 if (num_stereo == 2) {
723b2b0d
TI
673 knew.info = snd_akm4xxx_stereo_volume_info;
674 knew.get = snd_akm4xxx_stereo_volume_get;
675 knew.put = snd_akm4xxx_stereo_volume_put;
c83c0c47 676 } else {
723b2b0d
TI
677 knew.info = snd_akm4xxx_volume_info;
678 knew.get = snd_akm4xxx_volume_get;
679 knew.put = snd_akm4xxx_volume_put;
c83c0c47 680 }
1da177e4
LT
681 switch (ak->type) {
682 case SND_AK4524:
cb9d24e4 683 /* register 6 & 7 */
723b2b0d
TI
684 knew.private_value =
685 AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127) |
686 AK_VOL_CVT;
687 knew.tlv.p = db_scale_vol_datt;
1da177e4
LT
688 break;
689 case SND_AK4528:
cb9d24e4 690 /* register 4 & 5 */
723b2b0d
TI
691 knew.private_value =
692 AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127) |
693 AK_VOL_CVT;
694 knew.tlv.p = db_scale_vol_datt;
1da177e4
LT
695 break;
696 case SND_AK4529: {
cb9d24e4
TI
697 /* registers 2-7 and b,c */
698 int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb;
723b2b0d 699 knew.private_value =
cb9d24e4 700 AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
723b2b0d 701 knew.tlv.p = db_scale_8bit;
1da177e4
LT
702 break;
703 }
704 case SND_AK4355:
cb9d24e4 705 /* register 4-9, chip #0 only */
723b2b0d
TI
706 knew.private_value = AK_COMPOSE(0, idx + 4, 0, 255);
707 knew.tlv.p = db_scale_8bit;
1da177e4 708 break;
3479307f
JV
709 case SND_AK4358: {
710 /* register 4-9 and 11-12, chip #0 only */
711 int addr = idx < 6 ? idx + 4 : idx + 5;
723b2b0d 712 knew.private_value =
3479307f 713 AK_COMPOSE(0, addr, 0, 127) | AK_NEEDSMSB;
723b2b0d 714 knew.tlv.p = db_scale_7bit;
1da177e4 715 break;
3479307f 716 }
1da177e4 717 case SND_AK4381:
cb9d24e4 718 /* register 3 & 4 */
723b2b0d 719 knew.private_value =
cb9d24e4 720 AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255);
723b2b0d 721 knew.tlv.p = db_scale_linear;
1da177e4 722 break;
8f34692f
PH
723 case SND_AK4620:
724 /* register 6 & 7 */
725 knew.private_value =
726 AK_COMPOSE(idx/2, (idx%2) + 6, 0, 255);
727 knew.tlv.p = db_scale_linear;
728 break;
1da177e4 729 default:
723b2b0d 730 return -EINVAL;
1da177e4 731 }
c83c0c47 732
723b2b0d 733 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
cb9d24e4 734 if (err < 0)
723b2b0d 735 return err;
c83c0c47
JA
736
737 idx += num_stereo;
738 mixer_ch++;
1da177e4 739 }
723b2b0d
TI
740 return 0;
741}
742
743static int build_adc_controls(struct snd_akm4xxx *ak)
744{
8f34692f 745 int idx, err, mixer_ch, num_stereo, max_steps;
723b2b0d
TI
746 struct snd_kcontrol_new knew;
747
748 mixer_ch = 0;
8f34692f
PH
749 if (ak->type == SND_AK4528)
750 return 0; /* no controls */
723b2b0d
TI
751 for (idx = 0; idx < ak->num_adcs;) {
752 memset(&knew, 0, sizeof(knew));
753 if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) {
754 knew.name = "ADC Volume";
755 knew.index = mixer_ch + ak->idx_offset * 2;
756 num_stereo = 1;
757 } else {
758 knew.name = ak->adc_info[mixer_ch].name;
759 num_stereo = ak->adc_info[mixer_ch].num_channels;
760 }
761 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
762 knew.count = 1;
763 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
764 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
765 if (num_stereo == 2) {
766 knew.info = snd_akm4xxx_stereo_volume_info;
767 knew.get = snd_akm4xxx_stereo_volume_get;
768 knew.put = snd_akm4xxx_stereo_volume_put;
769 } else {
770 knew.info = snd_akm4xxx_volume_info;
771 knew.get = snd_akm4xxx_volume_get;
772 knew.put = snd_akm4xxx_volume_put;
773 }
cb9d24e4 774 /* register 4 & 5 */
854b66e4 775 if (ak->type == SND_AK5365)
8f34692f 776 max_steps = 152;
683fe153 777 else
8f34692f
PH
778 max_steps = 164;
779 knew.private_value =
780 AK_COMPOSE(idx/2, (idx%2) + 4, 0, max_steps) |
781 AK_VOL_CVT | AK_IPGA;
854b66e4 782 knew.tlv.p = db_scale_vol_datt;
723b2b0d 783 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
683fe153 784 if (err < 0)
723b2b0d
TI
785 return err;
786
787 if (ak->type == SND_AK5365 && (idx % 2) == 0) {
788 if (! ak->adc_info ||
a58e7cb1 789 ! ak->adc_info[mixer_ch].switch_name) {
723b2b0d 790 knew.name = "Capture Switch";
a58e7cb1
JV
791 knew.index = mixer_ch + ak->idx_offset * 2;
792 } else
723b2b0d
TI
793 knew.name = ak->adc_info[mixer_ch].switch_name;
794 knew.info = ak4xxx_switch_info;
795 knew.get = ak4xxx_switch_get;
796 knew.put = ak4xxx_switch_put;
797 knew.access = 0;
798 /* register 2, bit 0 (SMUTE): 0 = normal operation,
799 1 = mute */
800 knew.private_value =
801 AK_COMPOSE(idx/2, 2, 0, 0) | AK_INVERT;
802 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
803 if (err < 0)
804 return err;
a58e7cb1
JV
805
806 memset(&knew, 0, sizeof(knew));
807 knew.name = ak->adc_info[mixer_ch].selector_name;
808 if (!knew.name) {
809 knew.name = "Capture Channel";
810 knew.index = mixer_ch + ak->idx_offset * 2;
811 }
812
813 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
814 knew.info = ak4xxx_capture_source_info;
815 knew.get = ak4xxx_capture_source_get;
816 knew.put = ak4xxx_capture_source_put;
817 knew.access = 0;
818 /* input selector control: reg. 1, bits 0-2.
819 * mis-use 'shift' to pass mixer_ch */
820 knew.private_value
821 = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07);
822 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
823 if (err < 0)
824 return err;
723b2b0d 825 }
30ba6e20 826
723b2b0d
TI
827 idx += num_stereo;
828 mixer_ch++;
683fe153 829 }
723b2b0d
TI
830 return 0;
831}
832
833static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
834{
835 int idx, err;
836 struct snd_kcontrol_new knew;
683fe153 837
1da177e4 838 for (idx = 0; idx < num_emphs; idx++) {
723b2b0d
TI
839 memset(&knew, 0, sizeof(knew));
840 knew.name = "Deemphasis";
841 knew.index = idx + ak->idx_offset;
842 knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
843 knew.count = 1;
844 knew.info = snd_akm4xxx_deemphasis_info;
845 knew.get = snd_akm4xxx_deemphasis_get;
846 knew.put = snd_akm4xxx_deemphasis_put;
1da177e4
LT
847 switch (ak->type) {
848 case SND_AK4524:
849 case SND_AK4528:
8f34692f 850 case SND_AK4620:
cb9d24e4 851 /* register 3 */
723b2b0d 852 knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
1da177e4
LT
853 break;
854 case SND_AK4529: {
855 int shift = idx == 3 ? 6 : (2 - idx) * 2;
cb9d24e4 856 /* register 8 with shift */
723b2b0d 857 knew.private_value = AK_COMPOSE(0, 8, shift, 0);
1da177e4
LT
858 break;
859 }
860 case SND_AK4355:
861 case SND_AK4358:
723b2b0d 862 knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
1da177e4
LT
863 break;
864 case SND_AK4381:
723b2b0d 865 knew.private_value = AK_COMPOSE(idx, 1, 1, 0);
1da177e4 866 break;
cf93907b 867 default:
723b2b0d 868 return -EINVAL;
1da177e4 869 }
723b2b0d 870 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
cb9d24e4 871 if (err < 0)
723b2b0d 872 return err;
1da177e4 873 }
723b2b0d 874 return 0;
1da177e4
LT
875}
876
8f34692f
PH
877#ifdef CONFIG_PROC_FS
878static void proc_regs_read(struct snd_info_entry *entry,
879 struct snd_info_buffer *buffer)
880{
881 struct snd_akm4xxx *ak = (struct snd_akm4xxx *)entry->private_data;
882 int reg, val, chip;
883 for (chip = 0; chip < ak->num_chips; chip++) {
884 for (reg = 0; reg < ak->total_regs; reg++) {
885 val = snd_akm4xxx_get(ak, chip, reg);
886 snd_iprintf(buffer, "chip %d: 0x%02x = 0x%02x\n", chip,
887 reg, val);
888 }
889 }
890}
891
892static int proc_init(struct snd_akm4xxx *ak)
893{
894 struct snd_info_entry *entry;
895 int err;
896 err = snd_card_proc_new(ak->card, ak->name, &entry);
897 if (err < 0)
898 return err;
899 snd_info_set_text_ops(entry, ak, proc_regs_read);
900 return 0;
901}
902#else /* !CONFIG_PROC_FS */
e913b146 903static int proc_init(struct snd_akm4xxx *ak) { return 0; }
8f34692f
PH
904#endif
905
723b2b0d
TI
906int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
907{
908 int err, num_emphs;
909
910 err = build_dac_controls(ak);
911 if (err < 0)
912 return err;
913
854b66e4
TI
914 err = build_adc_controls(ak);
915 if (err < 0)
916 return err;
723b2b0d
TI
917 if (ak->type == SND_AK4355 || ak->type == SND_AK4358)
918 num_emphs = 1;
8f34692f
PH
919 else if (ak->type == SND_AK4620)
920 num_emphs = 0;
723b2b0d
TI
921 else
922 num_emphs = ak->num_dacs / 2;
923 err = build_deemphasis(ak, num_emphs);
8f34692f
PH
924 if (err < 0)
925 return err;
926 err = proc_init(ak);
723b2b0d
TI
927 if (err < 0)
928 return err;
929
930 return 0;
931}
cb9d24e4
TI
932EXPORT_SYMBOL(snd_akm4xxx_build_controls);
933
1da177e4
LT
934static int __init alsa_akm4xxx_module_init(void)
935{
936 return 0;
937}
938
939static void __exit alsa_akm4xxx_module_exit(void)
940{
941}
942
943module_init(alsa_akm4xxx_module_init)
944module_exit(alsa_akm4xxx_module_exit)