diff options
Diffstat (limited to 'sound/i2c/other/ak4xxx-adda.c')
-rw-r--r-- | sound/i2c/other/ak4xxx-adda.c | 284 |
1 files changed, 217 insertions, 67 deletions
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 045e32a311e0..dc7cc2001b74 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -34,7 +34,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>"); | |||
34 | MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); | 34 | MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
37 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val) | 37 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
38 | unsigned char val) | ||
38 | { | 39 | { |
39 | ak->ops.lock(ak, chip); | 40 | ak->ops.lock(ak, chip); |
40 | ak->ops.write(ak, chip, reg, val); | 41 | ak->ops.write(ak, chip, reg, val); |
@@ -52,6 +53,67 @@ void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsi | |||
52 | ak->ops.unlock(ak, chip); | 53 | ak->ops.unlock(ak, chip); |
53 | } | 54 | } |
54 | 55 | ||
56 | EXPORT_SYMBOL(snd_akm4xxx_write); | ||
57 | |||
58 | /* reset procedure for AK4524 and AK4528 */ | ||
59 | static void ak4524_reset(struct snd_akm4xxx *ak, int state) | ||
60 | { | ||
61 | unsigned int chip; | ||
62 | unsigned char reg, maxreg; | ||
63 | |||
64 | if (ak->type == SND_AK4528) | ||
65 | maxreg = 0x06; | ||
66 | else | ||
67 | maxreg = 0x08; | ||
68 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | ||
69 | snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); | ||
70 | if (state) | ||
71 | continue; | ||
72 | /* DAC volumes */ | ||
73 | for (reg = 0x04; reg < maxreg; reg++) | ||
74 | snd_akm4xxx_write(ak, chip, reg, | ||
75 | snd_akm4xxx_get(ak, chip, reg)); | ||
76 | if (ak->type == SND_AK4528) | ||
77 | continue; | ||
78 | /* IPGA */ | ||
79 | for (reg = 0x04; reg < 0x06; reg++) | ||
80 | snd_akm4xxx_write(ak, chip, reg, | ||
81 | snd_akm4xxx_get_ipga(ak, chip, reg)); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /* reset procedure for AK4355 and AK4358 */ | ||
86 | static void ak4355_reset(struct snd_akm4xxx *ak, int state) | ||
87 | { | ||
88 | unsigned char reg; | ||
89 | |||
90 | if (state) { | ||
91 | snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ | ||
92 | return; | ||
93 | } | ||
94 | for (reg = 0x00; reg < 0x0b; reg++) | ||
95 | if (reg != 0x01) | ||
96 | snd_akm4xxx_write(ak, 0, reg, | ||
97 | snd_akm4xxx_get(ak, 0, reg)); | ||
98 | snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ | ||
99 | } | ||
100 | |||
101 | /* reset procedure for AK4381 */ | ||
102 | static void ak4381_reset(struct snd_akm4xxx *ak, int state) | ||
103 | { | ||
104 | unsigned int chip; | ||
105 | unsigned char reg; | ||
106 | |||
107 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | ||
108 | snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); | ||
109 | if (state) | ||
110 | continue; | ||
111 | for (reg = 0x01; reg < 0x05; reg++) | ||
112 | snd_akm4xxx_write(ak, chip, reg, | ||
113 | snd_akm4xxx_get(ak, chip, reg)); | ||
114 | } | ||
115 | } | ||
116 | |||
55 | /* | 117 | /* |
56 | * reset the AKM codecs | 118 | * reset the AKM codecs |
57 | * @state: 1 = reset codec, 0 = restore the registers | 119 | * @state: 1 = reset codec, 0 = restore the registers |
@@ -60,52 +122,26 @@ void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsi | |||
60 | */ | 122 | */ |
61 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) | 123 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) |
62 | { | 124 | { |
63 | unsigned int chip; | ||
64 | unsigned char reg; | ||
65 | |||
66 | switch (ak->type) { | 125 | switch (ak->type) { |
67 | case SND_AK4524: | 126 | case SND_AK4524: |
68 | case SND_AK4528: | 127 | case SND_AK4528: |
69 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | 128 | ak4524_reset(ak, state); |
70 | snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); | ||
71 | if (state) | ||
72 | continue; | ||
73 | /* DAC volumes */ | ||
74 | for (reg = 0x04; reg < (ak->type == SND_AK4528 ? 0x06 : 0x08); reg++) | ||
75 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); | ||
76 | if (ak->type == SND_AK4528) | ||
77 | continue; | ||
78 | /* IPGA */ | ||
79 | for (reg = 0x04; reg < 0x06; reg++) | ||
80 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get_ipga(ak, chip, reg)); | ||
81 | } | ||
82 | break; | 129 | break; |
83 | case SND_AK4529: | 130 | case SND_AK4529: |
84 | /* FIXME: needed for ak4529? */ | 131 | /* FIXME: needed for ak4529? */ |
85 | break; | 132 | break; |
86 | case SND_AK4355: | 133 | case SND_AK4355: |
87 | case SND_AK4358: | 134 | case SND_AK4358: |
88 | if (state) { | 135 | ak4355_reset(ak, state); |
89 | snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ | ||
90 | return; | ||
91 | } | ||
92 | for (reg = 0x00; reg < 0x0b; reg++) | ||
93 | if (reg != 0x01) | ||
94 | snd_akm4xxx_write(ak, 0, reg, snd_akm4xxx_get(ak, 0, reg)); | ||
95 | snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ | ||
96 | break; | 136 | break; |
97 | case SND_AK4381: | 137 | case SND_AK4381: |
98 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | 138 | ak4381_reset(ak, state); |
99 | snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); | ||
100 | if (state) | ||
101 | continue; | ||
102 | for (reg = 0x01; reg < 0x05; reg++) | ||
103 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); | ||
104 | } | ||
105 | break; | 139 | break; |
106 | } | 140 | } |
107 | } | 141 | } |
108 | 142 | ||
143 | EXPORT_SYMBOL(snd_akm4xxx_reset); | ||
144 | |||
109 | /* | 145 | /* |
110 | * initialize all the ak4xxx chips | 146 | * initialize all the ak4xxx chips |
111 | */ | 147 | */ |
@@ -153,7 +189,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
153 | }; | 189 | }; |
154 | static unsigned char inits_ak4355[] = { | 190 | static unsigned char inits_ak4355[] = { |
155 | 0x01, 0x02, /* 1: reset and soft-mute */ | 191 | 0x01, 0x02, /* 1: reset and soft-mute */ |
156 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ | 192 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, |
193 | * disable DZF, sharp roll-off, RSTN#=0 */ | ||
157 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ | 194 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ |
158 | // 0x02, 0x2e, /* quad speed */ | 195 | // 0x02, 0x2e, /* quad speed */ |
159 | 0x03, 0x01, /* 3: de-emphasis off */ | 196 | 0x03, 0x01, /* 3: de-emphasis off */ |
@@ -169,7 +206,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
169 | }; | 206 | }; |
170 | static unsigned char inits_ak4358[] = { | 207 | static unsigned char inits_ak4358[] = { |
171 | 0x01, 0x02, /* 1: reset and soft-mute */ | 208 | 0x01, 0x02, /* 1: reset and soft-mute */ |
172 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ | 209 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, |
210 | * disable DZF, sharp roll-off, RSTN#=0 */ | ||
173 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ | 211 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ |
174 | // 0x02, 0x2e, /* quad speed */ | 212 | // 0x02, 0x2e, /* quad speed */ |
175 | 0x03, 0x01, /* 3: de-emphasis off */ | 213 | 0x03, 0x01, /* 3: de-emphasis off */ |
@@ -187,7 +225,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
187 | }; | 225 | }; |
188 | static unsigned char inits_ak4381[] = { | 226 | static unsigned char inits_ak4381[] = { |
189 | 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ | 227 | 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ |
190 | 0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */ | 228 | 0x01, 0x02, /* 1: de-emphasis off, normal speed, |
229 | * sharp roll-off, DZF off */ | ||
191 | // 0x01, 0x12, /* quad speed */ | 230 | // 0x01, 0x12, /* quad speed */ |
192 | 0x02, 0x00, /* 2: DZF disabled */ | 231 | 0x02, 0x00, /* 2: DZF disabled */ |
193 | 0x03, 0x00, /* 3: LATT 0 */ | 232 | 0x03, 0x00, /* 3: LATT 0 */ |
@@ -239,12 +278,15 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
239 | } | 278 | } |
240 | } | 279 | } |
241 | 280 | ||
281 | EXPORT_SYMBOL(snd_akm4xxx_init); | ||
282 | |||
242 | #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) | 283 | #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) |
243 | #define AK_GET_ADDR(val) ((val) & 0xff) | 284 | #define AK_GET_ADDR(val) ((val) & 0xff) |
244 | #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) | 285 | #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) |
245 | #define AK_GET_INVERT(val) (((val) >> 23) & 1) | 286 | #define AK_GET_INVERT(val) (((val) >> 23) & 1) |
246 | #define AK_GET_MASK(val) (((val) >> 24) & 0xff) | 287 | #define AK_GET_MASK(val) (((val) >> 24) & 0xff) |
247 | #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) | 288 | #define AK_COMPOSE(chip,addr,shift,mask) \ |
289 | (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) | ||
248 | #define AK_INVERT (1<<23) | 290 | #define AK_INVERT (1<<23) |
249 | 291 | ||
250 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, | 292 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, |
@@ -292,6 +334,64 @@ static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol, | |||
292 | return change; | 334 | return change; |
293 | } | 335 | } |
294 | 336 | ||
337 | static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol, | ||
338 | struct snd_ctl_elem_info *uinfo) | ||
339 | { | ||
340 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | ||
341 | |||
342 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
343 | uinfo->count = 2; | ||
344 | uinfo->value.integer.min = 0; | ||
345 | uinfo->value.integer.max = mask; | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol, | ||
350 | struct snd_ctl_elem_value *ucontrol) | ||
351 | { | ||
352 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | ||
353 | int chip = AK_GET_CHIP(kcontrol->private_value); | ||
354 | int addr = AK_GET_ADDR(kcontrol->private_value); | ||
355 | int invert = AK_GET_INVERT(kcontrol->private_value); | ||
356 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | ||
357 | unsigned char val = snd_akm4xxx_get(ak, chip, addr); | ||
358 | |||
359 | ucontrol->value.integer.value[0] = invert ? mask - val : val; | ||
360 | |||
361 | val = snd_akm4xxx_get(ak, chip, addr+1); | ||
362 | ucontrol->value.integer.value[1] = invert ? mask - val : val; | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol, | ||
368 | struct snd_ctl_elem_value *ucontrol) | ||
369 | { | ||
370 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | ||
371 | int chip = AK_GET_CHIP(kcontrol->private_value); | ||
372 | int addr = AK_GET_ADDR(kcontrol->private_value); | ||
373 | int invert = AK_GET_INVERT(kcontrol->private_value); | ||
374 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | ||
375 | unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); | ||
376 | int change0, change1; | ||
377 | |||
378 | if (invert) | ||
379 | nval = mask - nval; | ||
380 | change0 = snd_akm4xxx_get(ak, chip, addr) != nval; | ||
381 | if (change0) | ||
382 | snd_akm4xxx_write(ak, chip, addr, nval); | ||
383 | |||
384 | nval = ucontrol->value.integer.value[1] % (mask+1); | ||
385 | if (invert) | ||
386 | nval = mask - nval; | ||
387 | change1 = snd_akm4xxx_get(ak, chip, addr+1) != nval; | ||
388 | if (change1) | ||
389 | snd_akm4xxx_write(ak, chip, addr+1, nval); | ||
390 | |||
391 | |||
392 | return change0 || change1; | ||
393 | } | ||
394 | |||
295 | static int snd_akm4xxx_ipga_gain_info(struct snd_kcontrol *kcontrol, | 395 | static int snd_akm4xxx_ipga_gain_info(struct snd_kcontrol *kcontrol, |
296 | struct snd_ctl_elem_info *uinfo) | 396 | struct snd_ctl_elem_info *uinfo) |
297 | { | 397 | { |
@@ -308,7 +408,8 @@ static int snd_akm4xxx_ipga_gain_get(struct snd_kcontrol *kcontrol, | |||
308 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | 408 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); |
309 | int chip = AK_GET_CHIP(kcontrol->private_value); | 409 | int chip = AK_GET_CHIP(kcontrol->private_value); |
310 | int addr = AK_GET_ADDR(kcontrol->private_value); | 410 | int addr = AK_GET_ADDR(kcontrol->private_value); |
311 | ucontrol->value.integer.value[0] = snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; | 411 | ucontrol->value.integer.value[0] = |
412 | snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; | ||
312 | return 0; | 413 | return 0; |
313 | } | 414 | } |
314 | 415 | ||
@@ -336,7 +437,8 @@ static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, | |||
336 | uinfo->value.enumerated.items = 4; | 437 | uinfo->value.enumerated.items = 4; |
337 | if (uinfo->value.enumerated.item >= 4) | 438 | if (uinfo->value.enumerated.item >= 4) |
338 | uinfo->value.enumerated.item = 3; | 439 | uinfo->value.enumerated.item = 3; |
339 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 440 | strcpy(uinfo->value.enumerated.name, |
441 | texts[uinfo->value.enumerated.item]); | ||
340 | return 0; | 442 | return 0; |
341 | } | 443 | } |
342 | 444 | ||
@@ -347,7 +449,8 @@ static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, | |||
347 | int chip = AK_GET_CHIP(kcontrol->private_value); | 449 | int chip = AK_GET_CHIP(kcontrol->private_value); |
348 | int addr = AK_GET_ADDR(kcontrol->private_value); | 450 | int addr = AK_GET_ADDR(kcontrol->private_value); |
349 | int shift = AK_GET_SHIFT(kcontrol->private_value); | 451 | int shift = AK_GET_SHIFT(kcontrol->private_value); |
350 | ucontrol->value.enumerated.item[0] = (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; | 452 | ucontrol->value.enumerated.item[0] = |
453 | (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; | ||
351 | return 0; | 454 | return 0; |
352 | } | 455 | } |
353 | 456 | ||
@@ -361,7 +464,8 @@ static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol, | |||
361 | unsigned char nval = ucontrol->value.enumerated.item[0] & 3; | 464 | unsigned char nval = ucontrol->value.enumerated.item[0] & 3; |
362 | int change; | 465 | int change; |
363 | 466 | ||
364 | nval = (nval << shift) | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); | 467 | nval = (nval << shift) | |
468 | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); | ||
365 | change = snd_akm4xxx_get(ak, chip, addr) != nval; | 469 | change = snd_akm4xxx_get(ak, chip, addr) != nval; |
366 | if (change) | 470 | if (change) |
367 | snd_akm4xxx_write(ak, chip, addr, nval); | 471 | snd_akm4xxx_write(ak, chip, addr, nval); |
@@ -377,51 +481,86 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
377 | unsigned int idx, num_emphs; | 481 | unsigned int idx, num_emphs; |
378 | struct snd_kcontrol *ctl; | 482 | struct snd_kcontrol *ctl; |
379 | int err; | 483 | int err; |
484 | int mixer_ch = 0; | ||
485 | int num_stereo; | ||
380 | 486 | ||
381 | ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); | 487 | ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); |
382 | if (! ctl) | 488 | if (! ctl) |
383 | return -ENOMEM; | 489 | return -ENOMEM; |
384 | 490 | ||
385 | for (idx = 0; idx < ak->num_dacs; ++idx) { | 491 | for (idx = 0; idx < ak->num_dacs; ) { |
386 | memset(ctl, 0, sizeof(*ctl)); | 492 | memset(ctl, 0, sizeof(*ctl)); |
387 | strcpy(ctl->id.name, "DAC Volume"); | 493 | if (ak->channel_names == NULL) { |
388 | ctl->id.index = idx + ak->idx_offset * 2; | 494 | strcpy(ctl->id.name, "DAC Volume"); |
495 | num_stereo = 1; | ||
496 | ctl->id.index = mixer_ch + ak->idx_offset * 2; | ||
497 | } else { | ||
498 | strcpy(ctl->id.name, ak->channel_names[mixer_ch]); | ||
499 | num_stereo = ak->num_stereo[mixer_ch]; | ||
500 | ctl->id.index = 0; | ||
501 | } | ||
389 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 502 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
390 | ctl->count = 1; | 503 | ctl->count = 1; |
391 | ctl->info = snd_akm4xxx_volume_info; | 504 | if (num_stereo == 2) { |
392 | ctl->get = snd_akm4xxx_volume_get; | 505 | ctl->info = snd_akm4xxx_stereo_volume_info; |
393 | ctl->put = snd_akm4xxx_volume_put; | 506 | ctl->get = snd_akm4xxx_stereo_volume_get; |
507 | ctl->put = snd_akm4xxx_stereo_volume_put; | ||
508 | } else { | ||
509 | ctl->info = snd_akm4xxx_volume_info; | ||
510 | ctl->get = snd_akm4xxx_volume_get; | ||
511 | ctl->put = snd_akm4xxx_volume_put; | ||
512 | } | ||
394 | switch (ak->type) { | 513 | switch (ak->type) { |
395 | case SND_AK4524: | 514 | case SND_AK4524: |
396 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */ | 515 | /* register 6 & 7 */ |
516 | ctl->private_value = | ||
517 | AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); | ||
397 | break; | 518 | break; |
398 | case SND_AK4528: | 519 | case SND_AK4528: |
399 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ | 520 | /* register 4 & 5 */ |
521 | ctl->private_value = | ||
522 | AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); | ||
400 | break; | 523 | break; |
401 | case SND_AK4529: { | 524 | case SND_AK4529: { |
402 | int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */ | 525 | /* registers 2-7 and b,c */ |
403 | ctl->private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT; | 526 | int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; |
527 | ctl->private_value = | ||
528 | AK_COMPOSE(0, val, 0, 255) | AK_INVERT; | ||
404 | break; | 529 | break; |
405 | } | 530 | } |
406 | case SND_AK4355: | 531 | case SND_AK4355: |
407 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ | 532 | /* register 4-9, chip #0 only */ |
533 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); | ||
408 | break; | 534 | break; |
409 | case SND_AK4358: | 535 | case SND_AK4358: |
410 | if (idx >= 6) | 536 | if (idx >= 6) |
411 | ctl->private_value = AK_COMPOSE(0, idx + 5, 0, 255); /* register 4-9, chip #0 only */ | 537 | /* register 4-9, chip #0 only */ |
538 | ctl->private_value = | ||
539 | AK_COMPOSE(0, idx + 5, 0, 255); | ||
412 | else | 540 | else |
413 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ | 541 | /* register 4-9, chip #0 only */ |
542 | ctl->private_value = | ||
543 | AK_COMPOSE(0, idx + 4, 0, 255); | ||
414 | break; | 544 | break; |
415 | case SND_AK4381: | 545 | case SND_AK4381: |
416 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */ | 546 | /* register 3 & 4 */ |
547 | ctl->private_value = | ||
548 | AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); | ||
417 | break; | 549 | break; |
418 | default: | 550 | default: |
419 | err = -EINVAL; | 551 | err = -EINVAL; |
420 | goto __error; | 552 | goto __error; |
421 | } | 553 | } |
554 | |||
422 | ctl->private_data = ak; | 555 | ctl->private_data = ak; |
423 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 556 | err = snd_ctl_add(ak->card, |
557 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
558 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
559 | if (err < 0) | ||
424 | goto __error; | 560 | goto __error; |
561 | |||
562 | idx += num_stereo; | ||
563 | mixer_ch++; | ||
425 | } | 564 | } |
426 | for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) { | 565 | for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) { |
427 | memset(ctl, 0, sizeof(*ctl)); | 566 | memset(ctl, 0, sizeof(*ctl)); |
@@ -432,9 +571,14 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
432 | ctl->info = snd_akm4xxx_volume_info; | 571 | ctl->info = snd_akm4xxx_volume_info; |
433 | ctl->get = snd_akm4xxx_volume_get; | 572 | ctl->get = snd_akm4xxx_volume_get; |
434 | ctl->put = snd_akm4xxx_volume_put; | 573 | ctl->put = snd_akm4xxx_volume_put; |
435 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ | 574 | /* register 4 & 5 */ |
575 | ctl->private_value = | ||
576 | AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); | ||
436 | ctl->private_data = ak; | 577 | ctl->private_data = ak; |
437 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 578 | err = snd_ctl_add(ak->card, |
579 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
580 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
581 | if (err < 0) | ||
438 | goto __error; | 582 | goto __error; |
439 | 583 | ||
440 | memset(ctl, 0, sizeof(*ctl)); | 584 | memset(ctl, 0, sizeof(*ctl)); |
@@ -445,9 +589,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
445 | ctl->info = snd_akm4xxx_ipga_gain_info; | 589 | ctl->info = snd_akm4xxx_ipga_gain_info; |
446 | ctl->get = snd_akm4xxx_ipga_gain_get; | 590 | ctl->get = snd_akm4xxx_ipga_gain_get; |
447 | ctl->put = snd_akm4xxx_ipga_gain_put; | 591 | ctl->put = snd_akm4xxx_ipga_gain_put; |
448 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */ | 592 | /* register 4 & 5 */ |
593 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); | ||
449 | ctl->private_data = ak; | 594 | ctl->private_data = ak; |
450 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 595 | err = snd_ctl_add(ak->card, |
596 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
597 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
598 | if (err < 0) | ||
451 | goto __error; | 599 | goto __error; |
452 | } | 600 | } |
453 | if (ak->type == SND_AK4355 || ak->type == SND_AK4358) | 601 | if (ak->type == SND_AK4355 || ak->type == SND_AK4358) |
@@ -466,11 +614,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
466 | switch (ak->type) { | 614 | switch (ak->type) { |
467 | case SND_AK4524: | 615 | case SND_AK4524: |
468 | case SND_AK4528: | 616 | case SND_AK4528: |
469 | ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */ | 617 | /* register 3 */ |
618 | ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); | ||
470 | break; | 619 | break; |
471 | case SND_AK4529: { | 620 | case SND_AK4529: { |
472 | int shift = idx == 3 ? 6 : (2 - idx) * 2; | 621 | int shift = idx == 3 ? 6 : (2 - idx) * 2; |
473 | ctl->private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */ | 622 | /* register 8 with shift */ |
623 | ctl->private_value = AK_COMPOSE(0, 8, shift, 0); | ||
474 | break; | 624 | break; |
475 | } | 625 | } |
476 | case SND_AK4355: | 626 | case SND_AK4355: |
@@ -482,7 +632,10 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
482 | break; | 632 | break; |
483 | } | 633 | } |
484 | ctl->private_data = ak; | 634 | ctl->private_data = ak; |
485 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 635 | err = snd_ctl_add(ak->card, |
636 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
637 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
638 | if (err < 0) | ||
486 | goto __error; | 639 | goto __error; |
487 | } | 640 | } |
488 | err = 0; | 641 | err = 0; |
@@ -492,6 +645,8 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
492 | return err; | 645 | return err; |
493 | } | 646 | } |
494 | 647 | ||
648 | EXPORT_SYMBOL(snd_akm4xxx_build_controls); | ||
649 | |||
495 | static int __init alsa_akm4xxx_module_init(void) | 650 | static int __init alsa_akm4xxx_module_init(void) |
496 | { | 651 | { |
497 | return 0; | 652 | return 0; |
@@ -503,8 +658,3 @@ static void __exit alsa_akm4xxx_module_exit(void) | |||
503 | 658 | ||
504 | module_init(alsa_akm4xxx_module_init) | 659 | module_init(alsa_akm4xxx_module_init) |
505 | module_exit(alsa_akm4xxx_module_exit) | 660 | module_exit(alsa_akm4xxx_module_exit) |
506 | |||
507 | EXPORT_SYMBOL(snd_akm4xxx_write); | ||
508 | EXPORT_SYMBOL(snd_akm4xxx_reset); | ||
509 | EXPORT_SYMBOL(snd_akm4xxx_init); | ||
510 | EXPORT_SYMBOL(snd_akm4xxx_build_controls); | ||