aboutsummaryrefslogtreecommitdiff
path: root/hw/tsc210x.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/tsc210x.c')
-rw-r--r--hw/tsc210x.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/hw/tsc210x.c b/hw/tsc210x.c
index f04b19d..6082aa0 100644
--- a/hw/tsc210x.c
+++ b/hw/tsc210x.c
@@ -283,10 +283,30 @@ static void tsc210x_audio_out_cb(struct tsc210x_state_s *s, int free_b)
qemu_irq_raise(s->codec.tx_start);
}
-static void tsc2102_audio_set_format(struct tsc210x_state_s *s)
+static void tsc2102_audio_rate_update(struct tsc210x_state_s *s)
{
- int enable;
const struct tsc210x_rate_info_s *rate;
+
+ s->codec.tx_rate = 0;
+ s->codec.rx_rate = 0;
+ if (s->dac_power & (1 << 15)) /* PWDNC */
+ return;
+
+ for (rate = tsc2102_rates; rate->rate; rate ++)
+ if (rate->dsor == (s->audio_ctrl1 & 0x3f) && /* DACFS */
+ rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
+ break;
+ if (!rate->rate) {
+ printf("%s: unknown sampling rate configured\n", __FUNCTION__);
+ return;
+ }
+
+ s->codec.tx_rate = rate->rate;
+}
+
+static void tsc2102_audio_output_update(struct tsc210x_state_s *s)
+{
+ int enable;
audsettings_t fmt;
if (s->dac_voice[0]) {
@@ -296,32 +316,26 @@ static void tsc2102_audio_set_format(struct tsc210x_state_s *s)
AUD_close_out(&s->card, s->dac_voice[0]);
s->dac_voice[0] = 0;
}
+ s->codec.cts = 0;
enable =
(~s->dac_power & (1 << 15)) && /* PWDNC */
(~s->dac_power & (1 << 10)); /* DAPWDN */
- if (!enable)
- return;
-
- for (rate = tsc2102_rates; rate->rate; rate ++)
- if (rate->dsor == (s->audio_ctrl1 & 0x3f) && /* DACFS */
- rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
- break;
- if (!rate->rate) {
- printf("%s: unknown sampling rate configured\n", __FUNCTION__);
+ if (!enable || !s->codec.tx_rate)
return;
- }
/* Force our own sampling rate even in slave DAC mode */
fmt.endianness = 0;
fmt.nchannels = 2;
- fmt.freq = rate->rate;
+ fmt.freq = s->codec.tx_rate;
fmt.fmt = AUD_FMT_S16;
s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
"tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
- if (s->dac_voice[0])
+ if (s->dac_voice[0]) {
+ s->codec.cts = 1;
AUD_set_active_out(s->dac_voice[0], 1);
+ }
}
static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
@@ -587,8 +601,9 @@ static void tsc2102_audio_register_write(
fprintf(stderr, "tsc2102_audio_register_write: "
"wrong value written into Audio 1\n");
#endif
+ tsc2102_audio_rate_update(s);
if (s->audio)
- tsc2102_audio_set_format(s);
+ tsc2102_audio_output_update(s);
return;
case 0x01:
@@ -631,8 +646,9 @@ static void tsc2102_audio_register_write(
fprintf(stderr, "tsc2102_audio_register_write: "
"wrong value written into Power\n");
#endif
+ tsc2102_audio_rate_update(s);
if (s->audio)
- tsc2102_audio_set_format(s);
+ tsc2102_audio_output_update(s);
return;
case 0x06: /* Audio Control 3 */
@@ -644,7 +660,7 @@ static void tsc2102_audio_register_write(
"wrong value written into Audio 3\n");
#endif
if (s->audio)
- tsc2102_audio_set_format(s);
+ tsc2102_audio_output_update(s);
return;
case 0x07: /* LCH_BASS_BOOST_N0 */