diff options
Diffstat (limited to 'sound/i2c/other/ak4xxx-adda.c')
-rw-r--r-- | sound/i2c/other/ak4xxx-adda.c | 42 |
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 | ||
294 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, | 296 | static 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 = |