From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Jq52I-0000Yc-8A for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:27:14 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Jq52H-0000Ww-7h for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:27:13 -0400 Received: from [199.232.76.173] (port=48243 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Jq52H-0000We-0m for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:27:13 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Jq52G-0002dG-J4 for qemu-devel@nongnu.org; Sun, 27 Apr 2008 07:27:12 -0400 Received: from smtp08.web.de (fmsmtp08.dlan.cinetic.de [172.20.5.216]) by fmmailgate01.web.de (Postfix) with ESMTP id 144CADCEA054 for ; Sun, 27 Apr 2008 13:27:12 +0200 (CEST) Received: from [88.64.4.240] (helo=[192.168.1.198]) by smtp08.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.109 #226) id 1Jq52F-0005kJ-00 for qemu-devel@nongnu.org; Sun, 27 Apr 2008 13:27:12 +0200 Message-ID: <48146310.8080304@web.de> Date: Sun, 27 Apr 2008 13:27:12 +0200 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Sender: jan.kiszka@web.de Subject: [Qemu-devel] [PATCH 2/2] wm8570: switch to generic volume control Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Make use of AUD_set_volume for muting and OUT2V, drop all internally applied mute masks. Note that - this time - I avoid pow() in favor of a look-up table. Successfully tested with the MusicPal. Line-in volume control still needs to be added, I'm lacking an appropriate test case. Signed-off-by: Jan Kiszka --- hw/wm8750.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) Index: b/hw/wm8750.c =================================================================== --- a/hw/wm8750.c +++ b/hw/wm8750.c @@ -39,10 +39,16 @@ struct wm8750_s { uint8_t diff[2], pol, ds, monomix[2], alc, mute; uint8_t path[4], mpath[2], power, format; - uint32_t inmask, outmask; const struct wm_rate_s *rate; }; +/* pow(10.0, -i / 20.0), i = 0..42 */ +static const uint8_t vol_db_table[] = { + 255, 227, 203, 181, 161, 143, 128, 114, 102, 90, 81, 72, 64, 57, 51, 45, + 40, 36, 32, 29, 26, 23, 20, 18, 16, 14, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, + 4, 4, 3, 3, 3, 2, 2 +}; + static inline void wm8750_in_load(struct wm8750_s *s) { int acquired; @@ -195,20 +201,14 @@ static void wm8750_set_format(struct wm8 AUD_set_active_out(*s->out[0], 1); } -static void inline wm8750_mask_update(struct wm8750_s *s) +static void inline wm8750_vol_update(struct wm8750_s *s) { -#define R_ONLY 0x0000ffff -#define L_ONLY 0xffff0000 -#define BOTH (R_ONLY | L_ONLY) -#define NONE (R_ONLY & L_ONLY) - s->inmask = - (s->inmute[0] ? R_ONLY : BOTH) & - (s->inmute[1] ? L_ONLY : BOTH) & - (s->mute ? NONE : BOTH); - s->outmask = - (s->outmute[0] ? R_ONLY : BOTH) & - (s->outmute[1] ? L_ONLY : BOTH) & - (s->mute ? NONE : BOTH); + AUD_set_volume(AUD_MIXER_LINE_IN, s->mute, + s->inmute[0] ? 0 : 0xff, + s->inmute[1] ? 0 : 0xff); + AUD_set_volume(AUD_MIXER_PCM_OUT, s->mute, + s->outmute[0] ? 0 : vol_db_table[(0x7f-s->outvol[4])/3], + s->outmute[1] ? 0 : vol_db_table[(0x7f-s->outvol[5])/3]); } void wm8750_reset(i2c_slave *i2c) @@ -249,7 +249,7 @@ void wm8750_reset(i2c_slave *i2c) s->req_in = 0; s->idx_out = 0; s->req_out = 0; - wm8750_mask_update(s); + wm8750_vol_update(s); s->i2c_len = 0; } @@ -367,19 +367,19 @@ static int wm8750_tx(i2c_slave *i2c, uin case WM8750_LINVOL: /* Left Channel PGA */ s->invol[0] = value & 0x3f; /* LINVOL */ s->inmute[0] = (value >> 7) & 1; /* LINMUTE */ - wm8750_mask_update(s); + wm8750_vol_update(s); break; case WM8750_RINVOL: /* Right Channel PGA */ s->invol[1] = value & 0x3f; /* RINVOL */ s->inmute[1] = (value >> 7) & 1; /* RINMUTE */ - wm8750_mask_update(s); + wm8750_vol_update(s); break; case WM8750_ADCDAC: /* ADC and DAC Control */ s->pol = (value >> 5) & 3; /* ADCPOL */ s->mute = (value >> 3) & 1; /* DACMU */ - wm8750_mask_update(s); + wm8750_vol_update(s); break; case WM8750_ADCTL3: /* Additional Control (3) */ @@ -442,6 +442,7 @@ static int wm8750_tx(i2c_slave *i2c, uin case WM8750_LOUT2V: /* LOUT2 Volume */ s->outvol[4] = value & 0x7f; /* LOUT2VOL */ + wm8750_vol_update(s); break; case WM8750_ROUT1V: /* ROUT1 Volume */ @@ -450,6 +451,7 @@ static int wm8750_tx(i2c_slave *i2c, uin case WM8750_ROUT2V: /* ROUT2 Volume */ s->outvol[5] = value & 0x7f; /* ROUT2VOL */ + wm8750_vol_update(s); break; case WM8750_MOUTV: /* MONOOUT Volume */ @@ -531,8 +533,6 @@ static void wm8750_save(QEMUFile *f, voi qemu_put_8s(f, &s->mpath[i]); qemu_put_8s(f, &s->format); qemu_put_8s(f, &s->power); - qemu_put_be32s(f, &s->inmask); - qemu_put_be32s(f, &s->outmask); qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate)); i2c_slave_save(f, &s->i2c); } @@ -573,8 +573,6 @@ static int wm8750_load(QEMUFile *f, void qemu_get_8s(f, &s->mpath[i]); qemu_get_8s(f, &s->format); qemu_get_8s(f, &s->power); - qemu_get_be32s(f, &s->inmask); - qemu_get_be32s(f, &s->outmask); s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f]; i2c_slave_load(f, &s->i2c); return 0; @@ -619,8 +617,7 @@ void wm8750_data_req_set(i2c_slave *i2c, void wm8750_dac_dat(void *opaque, uint32_t sample) { struct wm8750_s *s = (struct wm8750_s *) opaque; - uint32_t *data = (uint32_t *) &s->data_out[s->idx_out]; - *data = sample & s->outmask; + *(uint32_t *) &s->data_out[s->idx_out] = sample; s->req_out -= 4; s->idx_out += 4; if (s->idx_out >= sizeof(s->data_out) || s->req_out <= 0) @@ -654,5 +651,5 @@ uint32_t wm8750_adc_dat(void *opaque) data = (uint32_t *) &s->data_in[s->idx_in]; s->req_in -= 4; s->idx_in += 4; - return *data & s->inmask; + return *data; }