qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4325] Use external clock in wm8750 slave mode.


From: Andrzej Zaborowski
Subject: [Qemu-devel] [4325] Use external clock in wm8750 slave mode.
Date: Sun, 04 May 2008 12:15:54 +0000

Revision: 4325
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4325
Author:   balrog
Date:     2008-05-04 12:15:51 +0000 (Sun, 04 May 2008)

Log Message:
-----------
Use external clock in wm8750 slave mode.

Modified Paths:
--------------
    trunk/hw/i2c.h
    trunk/hw/musicpal.c
    trunk/hw/wm8750.c

Modified: trunk/hw/i2c.h
===================================================================
--- trunk/hw/i2c.h      2008-05-04 12:00:16 UTC (rev 4324)
+++ trunk/hw/i2c.h      2008-05-04 12:15:51 UTC (rev 4325)
@@ -69,6 +69,7 @@
 uint32_t wm8750_adc_dat(void *opaque);
 void *wm8750_dac_buffer(void *opaque, int samples);
 void wm8750_dac_commit(void *opaque);
+void wm8750_set_bclk_in(void *opaque, int hz);
 
 /* ssd0303.c */
 void ssd0303_init(DisplayState *ds, i2c_bus *bus, int address);

Modified: trunk/hw/musicpal.c
===================================================================
--- trunk/hw/musicpal.c 2008-05-04 12:00:16 UTC (rev 4324)
+++ trunk/hw/musicpal.c 2008-05-04 12:15:51 UTC (rev 4325)
@@ -298,6 +298,20 @@
         qemu_irq_raise(s->irq);
 }
 
+static void musicpal_audio_clock_update(musicpal_audio_state *s)
+{
+    int rate;
+
+    if (s->playback_mode & MP_AUDIO_CLOCK_24MHZ)
+        rate = 24576000 / 64; /* 24.576MHz */
+    else
+        rate = 11289600 / 64; /* 11.2896MHz */
+
+    rate /= ((s->clock_div >> 8) & 0xff) + 1;
+
+    wm8750_set_bclk_in(s->wm, rate / 2);
+}
+
 static uint32_t musicpal_audio_read(void *opaque, target_phys_addr_t offset)
 {
     musicpal_audio_state *s = opaque;
@@ -339,12 +353,14 @@
             s->play_pos = 0;
         }
         s->playback_mode = value;
+        musicpal_audio_clock_update(s);
         break;
 
     case MP_AUDIO_CLOCK_DIV:
         s->clock_div = value;
         s->last_free = 0;
         s->play_pos = 0;
+        musicpal_audio_clock_update(s);
         break;
 
     case MP_AUDIO_IRQ_STATUS:

Modified: trunk/hw/wm8750.c
===================================================================
--- trunk/hw/wm8750.c   2008-05-04 12:00:16 UTC (rev 4324)
+++ trunk/hw/wm8750.c   2008-05-04 12:15:51 UTC (rev 4325)
@@ -40,6 +40,7 @@
     uint8_t diff[2], pol, ds, monomix[2], alc, mute;
     uint8_t path[4], mpath[2], power, format;
     const struct wm_rate_s *rate;
+    int adc_hz, dac_hz, ext_adc_hz, ext_dac_hz, master;
 };
 
 /* pow(10.0, -i / 20.0) * 255, i = 0..42 */
@@ -197,7 +198,7 @@
     /* Setup input */
     in_fmt.endianness = 0;
     in_fmt.nchannels = 2;
-    in_fmt.freq = s->rate->adc_hz;
+    in_fmt.freq = s->adc_hz;
     in_fmt.fmt = AUD_FMT_S16;
 
     s->adc_voice[0] = AUD_open_in(&s->card, s->adc_voice[0],
@@ -210,7 +211,7 @@
     /* Setup output */
     out_fmt.endianness = 0;
     out_fmt.nchannels = 2;
-    out_fmt.freq = s->rate->dac_hz;
+    out_fmt.freq = s->dac_hz;
     out_fmt.fmt = AUD_FMT_S16;
     monoout_fmt.endianness = 0;
     monoout_fmt.nchannels = 1;
@@ -238,12 +239,33 @@
         AUD_set_active_out(*s->out[0], 1);
 }
 
+static void wm8750_clk_update(struct wm8750_s *s, int ext)
+{
+    if (s->master || !s->ext_dac_hz)
+        s->dac_hz = s->rate->dac_hz;
+    else
+        s->dac_hz = s->ext_dac_hz;
+
+    if (s->master || !s->ext_adc_hz)
+        s->adc_hz = s->rate->adc_hz;
+    else
+        s->adc_hz = s->ext_adc_hz;
+
+    if (s->master || (!s->ext_dac_hz && !s->ext_adc_hz)) {
+        if (!ext)
+            wm8750_set_format(s);
+    } else {
+        if (ext)
+            wm8750_set_format(s);
+    }
+}
+
 void wm8750_reset(i2c_slave *i2c)
 {
     struct wm8750_s *s = (struct wm8750_s *) i2c;
     s->rate = &wm_rate_table[0];
     s->enable = 0;
-    wm8750_set_format(s);
+    wm8750_clk_update(s, 1);
     s->diff[0] = 0;
     s->diff[1] = 0;
     s->ds = 0;
@@ -515,17 +537,14 @@
         break;
 
     case WM8750_IFACE: /* Digital Audio Interface Format */
-#ifdef VERBOSE
-        if (value & 0x40)                      /* MS */
-            printf("%s: attempt to enable Master Mode\n", __FUNCTION__);
-#endif
         s->format = value;
-        wm8750_set_format(s);
+        s->master = (value >> 6) & 1;                  /* MS */
+        wm8750_clk_update(s, s->master);
         break;
 
     case WM8750_SRATE: /* Clocking and Sample Rate Control */
         s->rate = &wm_rate_table[(value >> 1) & 0x1f];
-        wm8750_set_format(s);
+        wm8750_clk_update(s, 0);
         break;
 
     case WM8750_RESET: /* Reset */
@@ -666,6 +685,7 @@
 void wm8750_dac_dat(void *opaque, uint32_t sample)
 {
     struct wm8750_s *s = (struct wm8750_s *) opaque;
+
     *(uint32_t *) &s->data_out[s->idx_out] = sample;
     s->req_out -= 4;
     s->idx_out += 4;
@@ -695,10 +715,21 @@
 {
     struct wm8750_s *s = (struct wm8750_s *) opaque;
     uint32_t *data;
+
     if (s->idx_in >= sizeof(s->data_in))
         wm8750_in_load(s);
+
     data = (uint32_t *) &s->data_in[s->idx_in];
     s->req_in -= 4;
     s->idx_in += 4;
     return *data;
 }
+
+void wm8750_set_bclk_in(void *opaque, int hz)
+{
+    struct wm8750_s *s = (struct wm8750_s *) opaque;
+
+    s->ext_adc_hz = hz;
+    s->ext_dac_hz = hz;
+    wm8750_clk_update(s, 1);
+}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]