From: Jan Kiszka <jan.kiszka@web.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 2/2] wm8570: switch to generic volume control
Date: Sun, 27 Apr 2008 13:27:12 +0200 [thread overview]
Message-ID: <48146310.8080304@web.de> (raw)
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 <jan.kiszka@web.de>
---
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;
}
reply other threads:[~2008-04-27 11:27 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48146310.8080304@web.de \
--to=jan.kiszka@web.de \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.