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