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,14 +42,15 @@ struct wm8750_s { | ||
| 42 | const struct wm_rate_s *rate; | 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 | static const uint8_t wm8750_vol_db_table[] = { | 46 | static const uint8_t wm8750_vol_db_table[] = { |
| 47 | 255, 227, 203, 181, 161, 143, 128, 114, 102, 90, 81, 72, 64, 57, 51, 45, | 47 | 255, 227, 203, 181, 161, 143, 128, 114, 102, 90, 81, 72, 64, 57, 51, 45, |
| 48 | 40, 36, 32, 29, 26, 23, 20, 18, 16, 14, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, | 48 | 40, 36, 32, 29, 26, 23, 20, 18, 16, 14, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, |
| 49 | 4, 4, 3, 3, 3, 2, 2 | 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 | static inline void wm8750_in_load(struct wm8750_s *s) | 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,26 +138,32 @@ static void wm8750_vol_update(struct wm8750_s *s) | ||
| 137 | { | 138 | { |
| 138 | /* FIXME: multiply all volumes by s->invol[2], s->invol[3] */ | 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 | /* FIXME: multiply all volumes by s->outvol[0], s->outvol[1] */ | 151 | /* FIXME: multiply all volumes by s->outvol[0], s->outvol[1] */ |
| 145 | 152 | ||
| 146 | /* Speaker: LOUT2VOL ROUT2VOL */ | 153 | /* Speaker: LOUT2VOL ROUT2VOL */ |
| 147 | AUD_set_volume_out(s->dac_voice[0], s->mute, | 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 | AUD_set_volume_out(s->dac_voice[1], s->mute, | 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 | /* MONOOUT: MONOVOL MONOVOL */ | 163 | /* MONOOUT: MONOVOL MONOVOL */ |
| 157 | AUD_set_volume_out(s->dac_voice[2], s->mute, | 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 | static void wm8750_set_format(struct wm8750_s *s) | 169 | static void wm8750_set_format(struct wm8750_s *s) |
| @@ -253,6 +260,7 @@ void wm8750_reset(i2c_slave *i2c) | @@ -253,6 +260,7 @@ void wm8750_reset(i2c_slave *i2c) | ||
| 253 | s->outvol[3] = 0x79; | 260 | s->outvol[3] = 0x79; |
| 254 | s->outvol[4] = 0x79; | 261 | s->outvol[4] = 0x79; |
| 255 | s->outvol[5] = 0x79; | 262 | s->outvol[5] = 0x79; |
| 263 | + s->outvol[6] = 0x79; | ||
| 256 | s->inmute[0] = 0; | 264 | s->inmute[0] = 0; |
| 257 | s->inmute[1] = 0; | 265 | s->inmute[1] = 0; |
| 258 | s->outmute[0] = 0; | 266 | s->outmute[0] = 0; |
| @@ -407,10 +415,12 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | @@ -407,10 +415,12 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | ||
| 407 | 415 | ||
| 408 | case WM8750_LADC: /* Left ADC Digital Volume */ | 416 | case WM8750_LADC: /* Left ADC Digital Volume */ |
| 409 | s->invol[2] = value & 0xff; /* LADCVOL */ | 417 | s->invol[2] = value & 0xff; /* LADCVOL */ |
| 418 | + wm8750_vol_update(s); | ||
| 410 | break; | 419 | break; |
| 411 | 420 | ||
| 412 | case WM8750_RADC: /* Right ADC Digital Volume */ | 421 | case WM8750_RADC: /* Right ADC Digital Volume */ |
| 413 | s->invol[3] = value & 0xff; /* RADCVOL */ | 422 | s->invol[3] = value & 0xff; /* RADCVOL */ |
| 423 | + wm8750_vol_update(s); | ||
| 414 | break; | 424 | break; |
| 415 | 425 | ||
| 416 | case WM8750_ALC1: /* ALC Control (1) */ | 426 | case WM8750_ALC1: /* ALC Control (1) */ |
| @@ -423,10 +433,12 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | @@ -423,10 +433,12 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | ||
| 423 | 433 | ||
| 424 | case WM8750_LDAC: /* Left Channel Digital Volume */ | 434 | case WM8750_LDAC: /* Left Channel Digital Volume */ |
| 425 | s->outvol[0] = value & 0xff; /* LDACVOL */ | 435 | s->outvol[0] = value & 0xff; /* LDACVOL */ |
| 436 | + wm8750_vol_update(s); | ||
| 426 | break; | 437 | break; |
| 427 | 438 | ||
| 428 | case WM8750_RDAC: /* Right Channel Digital Volume */ | 439 | case WM8750_RDAC: /* Right Channel Digital Volume */ |
| 429 | s->outvol[1] = value & 0xff; /* RDACVOL */ | 440 | s->outvol[1] = value & 0xff; /* RDACVOL */ |
| 441 | + wm8750_vol_update(s); | ||
| 430 | break; | 442 | break; |
| 431 | 443 | ||
| 432 | case WM8750_BASS: /* Bass Control */ | 444 | case WM8750_BASS: /* Bass Control */ |
| @@ -434,30 +446,43 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | @@ -434,30 +446,43 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | ||
| 434 | 446 | ||
| 435 | case WM8750_LOUTM1: /* Left Mixer Control (1) */ | 447 | case WM8750_LOUTM1: /* Left Mixer Control (1) */ |
| 436 | s->path[0] = (value >> 8) & 1; /* LD2LO */ | 448 | s->path[0] = (value >> 8) & 1; /* LD2LO */ |
| 449 | + /* TODO: mute/unmute respective paths */ | ||
| 450 | + wm8750_vol_update(s); | ||
| 437 | break; | 451 | break; |
| 438 | 452 | ||
| 439 | case WM8750_LOUTM2: /* Left Mixer Control (2) */ | 453 | case WM8750_LOUTM2: /* Left Mixer Control (2) */ |
| 440 | s->path[1] = (value >> 8) & 1; /* RD2LO */ | 454 | s->path[1] = (value >> 8) & 1; /* RD2LO */ |
| 455 | + /* TODO: mute/unmute respective paths */ | ||
| 456 | + wm8750_vol_update(s); | ||
| 441 | break; | 457 | break; |
| 442 | 458 | ||
| 443 | case WM8750_ROUTM1: /* Right Mixer Control (1) */ | 459 | case WM8750_ROUTM1: /* Right Mixer Control (1) */ |
| 444 | s->path[2] = (value >> 8) & 1; /* LD2RO */ | 460 | s->path[2] = (value >> 8) & 1; /* LD2RO */ |
| 461 | + /* TODO: mute/unmute respective paths */ | ||
| 462 | + wm8750_vol_update(s); | ||
| 445 | break; | 463 | break; |
| 446 | 464 | ||
| 447 | case WM8750_ROUTM2: /* Right Mixer Control (2) */ | 465 | case WM8750_ROUTM2: /* Right Mixer Control (2) */ |
| 448 | s->path[3] = (value >> 8) & 1; /* RD2RO */ | 466 | s->path[3] = (value >> 8) & 1; /* RD2RO */ |
| 467 | + /* TODO: mute/unmute respective paths */ | ||
| 468 | + wm8750_vol_update(s); | ||
| 449 | break; | 469 | break; |
| 450 | 470 | ||
| 451 | case WM8750_MOUTM1: /* Mono Mixer Control (1) */ | 471 | case WM8750_MOUTM1: /* Mono Mixer Control (1) */ |
| 452 | s->mpath[0] = (value >> 8) & 1; /* LD2MO */ | 472 | s->mpath[0] = (value >> 8) & 1; /* LD2MO */ |
| 473 | + /* TODO: mute/unmute respective paths */ | ||
| 474 | + wm8750_vol_update(s); | ||
| 453 | break; | 475 | break; |
| 454 | 476 | ||
| 455 | case WM8750_MOUTM2: /* Mono Mixer Control (2) */ | 477 | case WM8750_MOUTM2: /* Mono Mixer Control (2) */ |
| 456 | s->mpath[1] = (value >> 8) & 1; /* RD2MO */ | 478 | s->mpath[1] = (value >> 8) & 1; /* RD2MO */ |
| 479 | + /* TODO: mute/unmute respective paths */ | ||
| 480 | + wm8750_vol_update(s); | ||
| 457 | break; | 481 | break; |
| 458 | 482 | ||
| 459 | case WM8750_LOUT1V: /* LOUT1 Volume */ | 483 | case WM8750_LOUT1V: /* LOUT1 Volume */ |
| 460 | s->outvol[2] = value & 0x7f; /* LOUT1VOL */ | 484 | s->outvol[2] = value & 0x7f; /* LOUT1VOL */ |
| 485 | + wm8750_vol_update(s); | ||
| 461 | break; | 486 | break; |
| 462 | 487 | ||
| 463 | case WM8750_LOUT2V: /* LOUT2 Volume */ | 488 | case WM8750_LOUT2V: /* LOUT2 Volume */ |
| @@ -467,6 +492,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | @@ -467,6 +492,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | ||
| 467 | 492 | ||
| 468 | case WM8750_ROUT1V: /* ROUT1 Volume */ | 493 | case WM8750_ROUT1V: /* ROUT1 Volume */ |
| 469 | s->outvol[3] = value & 0x7f; /* ROUT1VOL */ | 494 | s->outvol[3] = value & 0x7f; /* ROUT1VOL */ |
| 495 | + wm8750_vol_update(s); | ||
| 470 | break; | 496 | break; |
| 471 | 497 | ||
| 472 | case WM8750_ROUT2V: /* ROUT2 Volume */ | 498 | case WM8750_ROUT2V: /* ROUT2 Volume */ |
| @@ -476,6 +502,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | @@ -476,6 +502,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | ||
| 476 | 502 | ||
| 477 | case WM8750_MOUTV: /* MONOOUT Volume */ | 503 | case WM8750_MOUTV: /* MONOOUT Volume */ |
| 478 | s->outvol[6] = value & 0x7f; /* MONOOUTVOL */ | 504 | s->outvol[6] = value & 0x7f; /* MONOOUTVOL */ |
| 505 | + wm8750_vol_update(s); | ||
| 479 | break; | 506 | break; |
| 480 | 507 | ||
| 481 | case WM8750_ADCTL2: /* Additional Control (2) */ | 508 | case WM8750_ADCTL2: /* Additional Control (2) */ |
| @@ -483,6 +510,8 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | @@ -483,6 +510,8 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data) | ||
| 483 | 510 | ||
| 484 | case WM8750_PWR2: /* Power Management (2) */ | 511 | case WM8750_PWR2: /* Power Management (2) */ |
| 485 | s->power = value & 0x7e; | 512 | s->power = value & 0x7e; |
| 513 | + /* TODO: mute/unmute respective paths */ | ||
| 514 | + wm8750_vol_update(s); | ||
| 486 | break; | 515 | break; |
| 487 | 516 | ||
| 488 | case WM8750_IFACE: /* Digital Audio Interface Format */ | 517 | case WM8750_IFACE: /* Digital Audio Interface Format */ |