aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJochen Voss <voss@seehuhn.de>2006-08-23 12:35:35 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:44:00 -0400
commit3479307f8ca3cbf4181b8bf7d8c824156a9e63b7 (patch)
tree26c4df6f74358218643f7967507844e872f77686 /sound
parent071c73ad5fce436ee00c9422b7ca0c5d629451fb (diff)
[ALSA] Fix volume control for the AK4358 DAC
Fix volume control for the AK4358 DAC. The attenuation control registers of the AK4358 use only 7bit for the volume, the msb is used to enable attenuation output. Without this patch there are 256 volume levels the lower 128 of which are mute. Signed-off-by: Jochen Voss <voss@seehuhn.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/i2c/other/ak4xxx-adda.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 0aea536a3371..89fc3cbc2356 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -284,11 +284,13 @@ EXPORT_SYMBOL(snd_akm4xxx_init);
284 284
285#define AK_GET_CHIP(val) (((val) >> 8) & 0xff) 285#define AK_GET_CHIP(val) (((val) >> 8) & 0xff)
286#define AK_GET_ADDR(val) ((val) & 0xff) 286#define AK_GET_ADDR(val) ((val) & 0xff)
287#define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) 287#define AK_GET_SHIFT(val) (((val) >> 16) & 0x3f)
288#define AK_GET_NEEDSMSB(val) (((val) >> 22) & 1)
288#define AK_GET_INVERT(val) (((val) >> 23) & 1) 289#define AK_GET_INVERT(val) (((val) >> 23) & 1)
289#define AK_GET_MASK(val) (((val) >> 24) & 0xff) 290#define AK_GET_MASK(val) (((val) >> 24) & 0xff)
290#define AK_COMPOSE(chip,addr,shift,mask) \ 291#define AK_COMPOSE(chip,addr,shift,mask) \
291 (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) 292 (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
293#define AK_NEEDSMSB (1<<22)
292#define AK_INVERT (1<<23) 294#define AK_INVERT (1<<23)
293 295
294static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, 296static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
@@ -309,10 +311,13 @@ static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
309 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 311 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
310 int chip = AK_GET_CHIP(kcontrol->private_value); 312 int chip = AK_GET_CHIP(kcontrol->private_value);
311 int addr = AK_GET_ADDR(kcontrol->private_value); 313 int addr = AK_GET_ADDR(kcontrol->private_value);
314 int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value);
312 int invert = AK_GET_INVERT(kcontrol->private_value); 315 int invert = AK_GET_INVERT(kcontrol->private_value);
313 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 316 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
314 unsigned char val = snd_akm4xxx_get(ak, chip, addr); 317 unsigned char val = snd_akm4xxx_get(ak, chip, addr);
315 318
319 if (needsmsb)
320 val &= 0x7f;
316 ucontrol->value.integer.value[0] = invert ? mask - val : val; 321 ucontrol->value.integer.value[0] = invert ? mask - val : val;
317 return 0; 322 return 0;
318} 323}
@@ -323,6 +328,7 @@ static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
323 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 328 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
324 int chip = AK_GET_CHIP(kcontrol->private_value); 329 int chip = AK_GET_CHIP(kcontrol->private_value);
325 int addr = AK_GET_ADDR(kcontrol->private_value); 330 int addr = AK_GET_ADDR(kcontrol->private_value);
331 int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value);
326 int invert = AK_GET_INVERT(kcontrol->private_value); 332 int invert = AK_GET_INVERT(kcontrol->private_value);
327 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 333 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
328 unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); 334 unsigned char nval = ucontrol->value.integer.value[0] % (mask+1);
@@ -330,6 +336,8 @@ static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
330 336
331 if (invert) 337 if (invert)
332 nval = mask - nval; 338 nval = mask - nval;
339 if (needsmsb)
340 nval |= 0x80;
333 change = snd_akm4xxx_get(ak, chip, addr) != nval; 341 change = snd_akm4xxx_get(ak, chip, addr) != nval;
334 if (change) 342 if (change)
335 snd_akm4xxx_write(ak, chip, addr, nval); 343 snd_akm4xxx_write(ak, chip, addr, nval);
@@ -354,13 +362,19 @@ static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol,
354 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 362 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
355 int chip = AK_GET_CHIP(kcontrol->private_value); 363 int chip = AK_GET_CHIP(kcontrol->private_value);
356 int addr = AK_GET_ADDR(kcontrol->private_value); 364 int addr = AK_GET_ADDR(kcontrol->private_value);
365 int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value);
357 int invert = AK_GET_INVERT(kcontrol->private_value); 366 int invert = AK_GET_INVERT(kcontrol->private_value);
358 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 367 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
359 unsigned char val = snd_akm4xxx_get(ak, chip, addr); 368 unsigned char val;
360 369
370 val = snd_akm4xxx_get(ak, chip, addr);
371 if (needsmsb)
372 val &= 0x7f;
361 ucontrol->value.integer.value[0] = invert ? mask - val : val; 373 ucontrol->value.integer.value[0] = invert ? mask - val : val;
362 374
363 val = snd_akm4xxx_get(ak, chip, addr+1); 375 val = snd_akm4xxx_get(ak, chip, addr+1);
376 if (needsmsb)
377 val &= 0x7f;
364 ucontrol->value.integer.value[1] = invert ? mask - val : val; 378 ucontrol->value.integer.value[1] = invert ? mask - val : val;
365 379
366 return 0; 380 return 0;
@@ -372,6 +386,7 @@ static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
372 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 386 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
373 int chip = AK_GET_CHIP(kcontrol->private_value); 387 int chip = AK_GET_CHIP(kcontrol->private_value);
374 int addr = AK_GET_ADDR(kcontrol->private_value); 388 int addr = AK_GET_ADDR(kcontrol->private_value);
389 int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value);
375 int invert = AK_GET_INVERT(kcontrol->private_value); 390 int invert = AK_GET_INVERT(kcontrol->private_value);
376 unsigned int mask = AK_GET_MASK(kcontrol->private_value); 391 unsigned int mask = AK_GET_MASK(kcontrol->private_value);
377 unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); 392 unsigned char nval = ucontrol->value.integer.value[0] % (mask+1);
@@ -379,6 +394,8 @@ static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
379 394
380 if (invert) 395 if (invert)
381 nval = mask - nval; 396 nval = mask - nval;
397 if (needsmsb)
398 nval |= 0x80;
382 change0 = snd_akm4xxx_get(ak, chip, addr) != nval; 399 change0 = snd_akm4xxx_get(ak, chip, addr) != nval;
383 if (change0) 400 if (change0)
384 snd_akm4xxx_write(ak, chip, addr, nval); 401 snd_akm4xxx_write(ak, chip, addr, nval);
@@ -386,6 +403,8 @@ static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
386 nval = ucontrol->value.integer.value[1] % (mask+1); 403 nval = ucontrol->value.integer.value[1] % (mask+1);
387 if (invert) 404 if (invert)
388 nval = mask - nval; 405 nval = mask - nval;
406 if (needsmsb)
407 nval |= 0x80;
389 change1 = snd_akm4xxx_get(ak, chip, addr+1) != nval; 408 change1 = snd_akm4xxx_get(ak, chip, addr+1) != nval;
390 if (change1) 409 if (change1)
391 snd_akm4xxx_write(ak, chip, addr+1, nval); 410 snd_akm4xxx_write(ak, chip, addr+1, nval);
@@ -585,16 +604,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
585 /* register 4-9, chip #0 only */ 604 /* register 4-9, chip #0 only */
586 ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); 605 ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255);
587 break; 606 break;
588 case SND_AK4358: 607 case SND_AK4358: {
589 if (idx >= 6) 608 /* register 4-9 and 11-12, chip #0 only */
590 /* register 4-9, chip #0 only */ 609 int addr = idx < 6 ? idx + 4 : idx + 5;
591 ctl->private_value = 610 ctl->private_value =
592 AK_COMPOSE(0, idx + 5, 0, 255); 611 AK_COMPOSE(0, addr, 0, 127) | AK_NEEDSMSB;
593 else
594 /* register 4-9, chip #0 only */
595 ctl->private_value =
596 AK_COMPOSE(0, idx + 4, 0, 255);
597 break; 612 break;
613 }
598 case SND_AK4381: 614 case SND_AK4381:
599 /* register 3 & 4 */ 615 /* register 3 & 4 */
600 ctl->private_value = 616 ctl->private_value =