qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 2/2] wm8570: switch to generic volume control
@ 2008-04-27 11:27 Jan Kiszka
  0 siblings, 0 replies; only message in thread
From: Jan Kiszka @ 2008-04-27 11:27 UTC (permalink / raw)
  To: qemu-devel

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;
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-04-27 11:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-27 11:27 [Qemu-devel] [PATCH 2/2] wm8570: switch to generic volume control Jan Kiszka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).