aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 =