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