Commit db502b6126a66b8a6cbb7bf6294e5b6bd361aa55
1 parent
683efdcb
Update volume for WM8750 input voices.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4322 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
41 additions
and
12 deletions
hw/wm8750.c
... | ... | @@ -42,14 +42,15 @@ struct wm8750_s { |
42 | 42 | const struct wm_rate_s *rate; |
43 | 43 | }; |
44 | 44 | |
45 | -/* pow(10.0, -i / 20.0), i = 0..42 */ | |
45 | +/* pow(10.0, -i / 20.0) * 255, i = 0..42 */ | |
46 | 46 | static const uint8_t wm8750_vol_db_table[] = { |
47 | 47 | 255, 227, 203, 181, 161, 143, 128, 114, 102, 90, 81, 72, 64, 57, 51, 45, |
48 | 48 | 40, 36, 32, 29, 26, 23, 20, 18, 16, 14, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, |
49 | 49 | 4, 4, 3, 3, 3, 2, 2 |
50 | 50 | }; |
51 | 51 | |
52 | -#define WM8750_VOL_TRANSFORM(x) wm8750_vol_db_table[(0x7f - x) / 3] | |
52 | +#define WM8750_OUTVOL_TRANSFORM(x) wm8750_vol_db_table[(0x7f - x) / 3] | |
53 | +#define WM8750_INVOL_TRANSFORM(x) (x << 2) | |
53 | 54 | |
54 | 55 | static inline void wm8750_in_load(struct wm8750_s *s) |
55 | 56 | { |
... | ... | @@ -137,26 +138,32 @@ static void wm8750_vol_update(struct wm8750_s *s) |
137 | 138 | { |
138 | 139 | /* FIXME: multiply all volumes by s->invol[2], s->invol[3] */ |
139 | 140 | |
140 | - AUD_set_volume_in(*s->in[0], s->mute, | |
141 | - s->inmute[0] ? 0 : 0xff, | |
142 | - s->inmute[1] ? 0 : 0xff); | |
141 | + AUD_set_volume_in(s->adc_voice[0], s->mute, | |
142 | + s->inmute[0] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[0]), | |
143 | + s->inmute[1] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[1])); | |
144 | + AUD_set_volume_in(s->adc_voice[1], s->mute, | |
145 | + s->inmute[0] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[0]), | |
146 | + s->inmute[1] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[1])); | |
147 | + AUD_set_volume_in(s->adc_voice[2], s->mute, | |
148 | + s->inmute[0] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[0]), | |
149 | + s->inmute[1] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[1])); | |
143 | 150 | |
144 | 151 | /* FIXME: multiply all volumes by s->outvol[0], s->outvol[1] */ |
145 | 152 | |
146 | 153 | /* Speaker: LOUT2VOL ROUT2VOL */ |
147 | 154 | AUD_set_volume_out(s->dac_voice[0], s->mute, |
148 | - s->outmute[0] ? 0 : WM8750_VOL_TRANSFORM(s->outvol[4]), | |
149 | - s->outmute[1] ? 0 : WM8750_VOL_TRANSFORM(s->outvol[5])); | |
155 | + s->outmute[0] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[4]), | |
156 | + s->outmute[1] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[5])); | |
150 | 157 | |
151 | - /* Headphone: LOUT2VOL ROUT2VOL */ | |
158 | + /* Headphone: LOUT1VOL ROUT1VOL */ | |
152 | 159 | AUD_set_volume_out(s->dac_voice[1], s->mute, |
153 | - s->outmute[0] ? 0 : WM8750_VOL_TRANSFORM(s->outvol[2]), | |
154 | - s->outmute[1] ? 0 : WM8750_VOL_TRANSFORM(s->outvol[3])); | |
160 | + s->outmute[0] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[2]), | |
161 | + s->outmute[1] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[3])); | |
155 | 162 | |
156 | 163 | /* MONOOUT: MONOVOL MONOVOL */ |
157 | 164 | AUD_set_volume_out(s->dac_voice[2], s->mute, |
158 | - s->outmute[0] ? 0 : WM8750_VOL_TRANSFORM(s->outvol[6]), | |
159 | - s->outmute[1] ? 0 : WM8750_VOL_TRANSFORM(s->outvol[6])); | |
165 | + s->outmute[0] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[6]), | |
166 | + s->outmute[1] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[6])); | |
160 | 167 | } |
161 | 168 | |
162 | 169 | static void wm8750_set_format(struct wm8750_s *s) |
... | ... | @@ -253,6 +260,7 @@ void wm8750_reset(i2c_slave *i2c) |
253 | 260 | s->outvol[3] = 0x79; |
254 | 261 | s->outvol[4] = 0x79; |
255 | 262 | s->outvol[5] = 0x79; |
263 | + s->outvol[6] = 0x79; | |
256 | 264 | s->inmute[0] = 0; |
257 | 265 | s->inmute[1] = 0; |
258 | 266 | s->outmute[0] = 0; |
... | ... | @@ -407,10 +415,12 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) |
407 | 415 | |
408 | 416 | case WM8750_LADC: /* Left ADC Digital Volume */ |
409 | 417 | s->invol[2] = value & 0xff; /* LADCVOL */ |
418 | + wm8750_vol_update(s); | |
410 | 419 | break; |
411 | 420 | |
412 | 421 | case WM8750_RADC: /* Right ADC Digital Volume */ |
413 | 422 | s->invol[3] = value & 0xff; /* RADCVOL */ |
423 | + wm8750_vol_update(s); | |
414 | 424 | break; |
415 | 425 | |
416 | 426 | case WM8750_ALC1: /* ALC Control (1) */ |
... | ... | @@ -423,10 +433,12 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) |
423 | 433 | |
424 | 434 | case WM8750_LDAC: /* Left Channel Digital Volume */ |
425 | 435 | s->outvol[0] = value & 0xff; /* LDACVOL */ |
436 | + wm8750_vol_update(s); | |
426 | 437 | break; |
427 | 438 | |
428 | 439 | case WM8750_RDAC: /* Right Channel Digital Volume */ |
429 | 440 | s->outvol[1] = value & 0xff; /* RDACVOL */ |
441 | + wm8750_vol_update(s); | |
430 | 442 | break; |
431 | 443 | |
432 | 444 | case WM8750_BASS: /* Bass Control */ |
... | ... | @@ -434,30 +446,43 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) |
434 | 446 | |
435 | 447 | case WM8750_LOUTM1: /* Left Mixer Control (1) */ |
436 | 448 | s->path[0] = (value >> 8) & 1; /* LD2LO */ |
449 | + /* TODO: mute/unmute respective paths */ | |
450 | + wm8750_vol_update(s); | |
437 | 451 | break; |
438 | 452 | |
439 | 453 | case WM8750_LOUTM2: /* Left Mixer Control (2) */ |
440 | 454 | s->path[1] = (value >> 8) & 1; /* RD2LO */ |
455 | + /* TODO: mute/unmute respective paths */ | |
456 | + wm8750_vol_update(s); | |
441 | 457 | break; |
442 | 458 | |
443 | 459 | case WM8750_ROUTM1: /* Right Mixer Control (1) */ |
444 | 460 | s->path[2] = (value >> 8) & 1; /* LD2RO */ |
461 | + /* TODO: mute/unmute respective paths */ | |
462 | + wm8750_vol_update(s); | |
445 | 463 | break; |
446 | 464 | |
447 | 465 | case WM8750_ROUTM2: /* Right Mixer Control (2) */ |
448 | 466 | s->path[3] = (value >> 8) & 1; /* RD2RO */ |
467 | + /* TODO: mute/unmute respective paths */ | |
468 | + wm8750_vol_update(s); | |
449 | 469 | break; |
450 | 470 | |
451 | 471 | case WM8750_MOUTM1: /* Mono Mixer Control (1) */ |
452 | 472 | s->mpath[0] = (value >> 8) & 1; /* LD2MO */ |
473 | + /* TODO: mute/unmute respective paths */ | |
474 | + wm8750_vol_update(s); | |
453 | 475 | break; |
454 | 476 | |
455 | 477 | case WM8750_MOUTM2: /* Mono Mixer Control (2) */ |
456 | 478 | s->mpath[1] = (value >> 8) & 1; /* RD2MO */ |
479 | + /* TODO: mute/unmute respective paths */ | |
480 | + wm8750_vol_update(s); | |
457 | 481 | break; |
458 | 482 | |
459 | 483 | case WM8750_LOUT1V: /* LOUT1 Volume */ |
460 | 484 | s->outvol[2] = value & 0x7f; /* LOUT1VOL */ |
485 | + wm8750_vol_update(s); | |
461 | 486 | break; |
462 | 487 | |
463 | 488 | case WM8750_LOUT2V: /* LOUT2 Volume */ |
... | ... | @@ -467,6 +492,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) |
467 | 492 | |
468 | 493 | case WM8750_ROUT1V: /* ROUT1 Volume */ |
469 | 494 | s->outvol[3] = value & 0x7f; /* ROUT1VOL */ |
495 | + wm8750_vol_update(s); | |
470 | 496 | break; |
471 | 497 | |
472 | 498 | case WM8750_ROUT2V: /* ROUT2 Volume */ |
... | ... | @@ -476,6 +502,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) |
476 | 502 | |
477 | 503 | case WM8750_MOUTV: /* MONOOUT Volume */ |
478 | 504 | s->outvol[6] = value & 0x7f; /* MONOOUTVOL */ |
505 | + wm8750_vol_update(s); | |
479 | 506 | break; |
480 | 507 | |
481 | 508 | case WM8750_ADCTL2: /* Additional Control (2) */ |
... | ... | @@ -483,6 +510,8 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) |
483 | 510 | |
484 | 511 | case WM8750_PWR2: /* Power Management (2) */ |
485 | 512 | s->power = value & 0x7e; |
513 | + /* TODO: mute/unmute respective paths */ | |
514 | + wm8750_vol_update(s); | |
486 | 515 | break; |
487 | 516 | |
488 | 517 | case WM8750_IFACE: /* Digital Audio Interface Format */ | ... | ... |