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 */ | ... | ... |