40
40
uint8_t diff[2], pol, ds, monomix[2], alc, mute;
41
41
uint8_t path[4], mpath[2], power, format;
42
uint32_t inmask, outmask;
43
42
const struct wm_rate_s *rate;
43
int adc_hz, dac_hz, ext_adc_hz, ext_dac_hz, master;
46
/* pow(10.0, -i / 20.0) * 255, i = 0..42 */
47
static const uint8_t wm8750_vol_db_table[] = {
48
255, 227, 203, 181, 161, 143, 128, 114, 102, 90, 81, 72, 64, 57, 51, 45,
49
40, 36, 32, 29, 26, 23, 20, 18, 16, 14, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5,
53
#define WM8750_OUTVOL_TRANSFORM(x) wm8750_vol_db_table[(0x7f - x) / 3]
54
#define WM8750_INVOL_TRANSFORM(x) (x << 2)
46
56
static inline void wm8750_in_load(struct wm8750_s *s)
67
77
struct wm8750_s *s = (struct wm8750_s *) opaque;
68
78
s->req_in = avail_b;
69
79
s->data_req(s->opaque, s->req_out >> 2, avail_b >> 2);
76
82
static void wm8750_audio_out_cb(void *opaque, int free_b)
78
84
struct wm8750_s *s = (struct wm8750_s *) opaque;
82
s->data_req(s->opaque, free_b >> 2, s->req_in >> 2);
86
if (s->idx_out >= free_b) {
91
s->req_out = free_b - s->idx_out;
93
s->data_req(s->opaque, s->req_out >> 2, s->req_in >> 2);
121
132
{ 512, 24000, 512, 24000 }, /* SR: 11100 */
122
133
{ 768, 24000, 768, 24000 }, /* SR: 11101 */
123
134
{ 128, 88200, 128, 88200 }, /* SR: 11110 */
124
{ 192, 88200, 128, 88200 }, /* SR: 11111 */
135
{ 192, 88200, 192, 88200 }, /* SR: 11111 */
138
static void wm8750_vol_update(struct wm8750_s *s)
140
/* FIXME: multiply all volumes by s->invol[2], s->invol[3] */
142
AUD_set_volume_in(s->adc_voice[0], s->mute,
143
s->inmute[0] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[0]),
144
s->inmute[1] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[1]));
145
AUD_set_volume_in(s->adc_voice[1], s->mute,
146
s->inmute[0] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[0]),
147
s->inmute[1] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[1]));
148
AUD_set_volume_in(s->adc_voice[2], s->mute,
149
s->inmute[0] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[0]),
150
s->inmute[1] ? 0 : WM8750_INVOL_TRANSFORM(s->invol[1]));
152
/* FIXME: multiply all volumes by s->outvol[0], s->outvol[1] */
154
/* Speaker: LOUT2VOL ROUT2VOL */
155
AUD_set_volume_out(s->dac_voice[0], s->mute,
156
s->outmute[0] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[4]),
157
s->outmute[1] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[5]));
159
/* Headphone: LOUT1VOL ROUT1VOL */
160
AUD_set_volume_out(s->dac_voice[1], s->mute,
161
s->outmute[0] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[2]),
162
s->outmute[1] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[3]));
164
/* MONOOUT: MONOVOL MONOVOL */
165
AUD_set_volume_out(s->dac_voice[2], s->mute,
166
s->outmute[0] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[6]),
167
s->outmute[1] ? 0 : WM8750_OUTVOL_TRANSFORM(s->outvol[6]));
127
170
static void wm8750_set_format(struct wm8750_s *s)
130
audsettings_t in_fmt;
131
audsettings_t out_fmt;
132
audsettings_t monoout_fmt;
173
struct audsettings in_fmt;
174
struct audsettings out_fmt;
175
struct audsettings monoout_fmt;
134
177
wm8750_out_flush(s);
184
227
CODEC ".monomix", s, wm8750_audio_out_cb, &out_fmt);
185
228
/* no sense emulating OUT3 which is a mix of other outputs */
230
wm8750_vol_update(s);
187
232
/* We should connect the left and right channels to their
188
233
* respective inputs/outputs but we have completely no need
189
234
* for mixing or combining paths to different ports, so we
194
239
AUD_set_active_out(*s->out[0], 1);
197
static void inline wm8750_mask_update(struct wm8750_s *s)
242
static void wm8750_clk_update(struct wm8750_s *s, int ext)
199
#define R_ONLY 0x0000ffff
200
#define L_ONLY 0xffff0000
201
#define BOTH (R_ONLY | L_ONLY)
202
#define NONE (R_ONLY & L_ONLY)
204
(s->inmute[0] ? R_ONLY : BOTH) &
205
(s->inmute[1] ? L_ONLY : BOTH) &
206
(s->mute ? NONE : BOTH);
208
(s->outmute[0] ? R_ONLY : BOTH) &
209
(s->outmute[1] ? L_ONLY : BOTH) &
210
(s->mute ? NONE : BOTH);
244
if (s->master || !s->ext_dac_hz)
245
s->dac_hz = s->rate->dac_hz;
247
s->dac_hz = s->ext_dac_hz;
249
if (s->master || !s->ext_adc_hz)
250
s->adc_hz = s->rate->adc_hz;
252
s->adc_hz = s->ext_adc_hz;
254
if (s->master || (!s->ext_dac_hz && !s->ext_adc_hz)) {
256
wm8750_set_format(s);
259
wm8750_set_format(s);
213
263
void wm8750_reset(i2c_slave *i2c)
215
265
struct wm8750_s *s = (struct wm8750_s *) i2c;
266
s->rate = &wm_rate_table[0];
217
wm8750_set_format(s);
268
wm8750_clk_update(s, 1);
365
417
case WM8750_LINVOL: /* Left Channel PGA */
366
418
s->invol[0] = value & 0x3f; /* LINVOL */
367
419
s->inmute[0] = (value >> 7) & 1; /* LINMUTE */
368
wm8750_mask_update(s);
420
wm8750_vol_update(s);
371
423
case WM8750_RINVOL: /* Right Channel PGA */
372
424
s->invol[1] = value & 0x3f; /* RINVOL */
373
425
s->inmute[1] = (value >> 7) & 1; /* RINMUTE */
374
wm8750_mask_update(s);
426
wm8750_vol_update(s);
377
429
case WM8750_ADCDAC: /* ADC and DAC Control */
378
430
s->pol = (value >> 5) & 3; /* ADCPOL */
379
431
s->mute = (value >> 3) & 1; /* DACMU */
380
wm8750_mask_update(s);
432
wm8750_vol_update(s);
383
435
case WM8750_ADCTL3: /* Additional Control (3) */
413
469
case WM8750_LOUTM1: /* Left Mixer Control (1) */
414
470
s->path[0] = (value >> 8) & 1; /* LD2LO */
471
/* TODO: mute/unmute respective paths */
472
wm8750_vol_update(s);
417
475
case WM8750_LOUTM2: /* Left Mixer Control (2) */
418
476
s->path[1] = (value >> 8) & 1; /* RD2LO */
477
/* TODO: mute/unmute respective paths */
478
wm8750_vol_update(s);
421
481
case WM8750_ROUTM1: /* Right Mixer Control (1) */
422
482
s->path[2] = (value >> 8) & 1; /* LD2RO */
483
/* TODO: mute/unmute respective paths */
484
wm8750_vol_update(s);
425
487
case WM8750_ROUTM2: /* Right Mixer Control (2) */
426
488
s->path[3] = (value >> 8) & 1; /* RD2RO */
489
/* TODO: mute/unmute respective paths */
490
wm8750_vol_update(s);
429
493
case WM8750_MOUTM1: /* Mono Mixer Control (1) */
430
494
s->mpath[0] = (value >> 8) & 1; /* LD2MO */
495
/* TODO: mute/unmute respective paths */
496
wm8750_vol_update(s);
433
499
case WM8750_MOUTM2: /* Mono Mixer Control (2) */
434
500
s->mpath[1] = (value >> 8) & 1; /* RD2MO */
501
/* TODO: mute/unmute respective paths */
502
wm8750_vol_update(s);
437
505
case WM8750_LOUT1V: /* LOUT1 Volume */
438
s->outvol[2] = value & 0x7f; /* LOUT2VOL */
506
s->outvol[2] = value & 0x7f; /* LOUT1VOL */
507
wm8750_vol_update(s);
441
510
case WM8750_LOUT2V: /* LOUT2 Volume */
442
511
s->outvol[4] = value & 0x7f; /* LOUT2VOL */
512
wm8750_vol_update(s);
445
515
case WM8750_ROUT1V: /* ROUT1 Volume */
446
s->outvol[3] = value & 0x7f; /* ROUT2VOL */
516
s->outvol[3] = value & 0x7f; /* ROUT1VOL */
517
wm8750_vol_update(s);
449
520
case WM8750_ROUT2V: /* ROUT2 Volume */
450
521
s->outvol[5] = value & 0x7f; /* ROUT2VOL */
522
wm8750_vol_update(s);
453
525
case WM8750_MOUTV: /* MONOOUT Volume */
454
526
s->outvol[6] = value & 0x7f; /* MONOOUTVOL */
527
wm8750_vol_update(s);
457
530
case WM8750_ADCTL2: /* Additional Control (2) */
460
533
case WM8750_PWR2: /* Power Management (2) */
461
534
s->power = value & 0x7e;
535
/* TODO: mute/unmute respective paths */
536
wm8750_vol_update(s);
464
539
case WM8750_IFACE: /* Digital Audio Interface Format */
466
if (value & 0x40) /* MS */
467
printf("%s: attempt to enable Master Mode\n", __FUNCTION__);
469
540
s->format = value;
470
wm8750_set_format(s);
541
s->master = (value >> 6) & 1; /* MS */
542
wm8750_clk_update(s, s->master);
473
545
case WM8750_SRATE: /* Clocking and Sample Rate Control */
474
546
s->rate = &wm_rate_table[(value >> 1) & 0x1f];
475
wm8750_set_format(s);
547
wm8750_clk_update(s, 0);
478
550
case WM8750_RESET: /* Reset */
529
601
qemu_put_8s(f, &s->mpath[i]);
530
602
qemu_put_8s(f, &s->format);
531
603
qemu_put_8s(f, &s->power);
532
qemu_put_be32s(f, &s->inmask);
533
qemu_put_be32s(f, &s->outmask);
534
604
qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate));
535
605
i2c_slave_save(f, &s->i2c);
571
641
qemu_get_8s(f, &s->mpath[i]);
572
642
qemu_get_8s(f, &s->format);
573
643
qemu_get_8s(f, &s->power);
574
qemu_get_be32s(f, &s->inmask);
575
qemu_get_be32s(f, &s->outmask);
576
644
s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f];
577
645
i2c_slave_load(f, &s->i2c);
581
static int wm8750_iid = 0;
583
649
i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio)
585
651
struct wm8750_s *s = (struct wm8750_s *)
591
657
AUD_register_card(audio, CODEC, &s->card);
592
658
wm8750_reset(&s->i2c);
594
register_savevm(CODEC, wm8750_iid ++, 0, wm8750_save, wm8750_load, s);
660
register_savevm(CODEC, -1, 0, wm8750_save, wm8750_load, s);
599
666
static void wm8750_fini(i2c_slave *i2c)
601
668
struct wm8750_s *s = (struct wm8750_s *) i2c;
615
683
void wm8750_dac_dat(void *opaque, uint32_t sample)
617
685
struct wm8750_s *s = (struct wm8750_s *) opaque;
618
uint32_t *data = (uint32_t *) &s->data_out[s->idx_out];
619
*data = sample & s->outmask;
687
*(uint32_t *) &s->data_out[s->idx_out] = sample;
622
690
if (s->idx_out >= sizeof(s->data_out) || s->req_out <= 0)
623
691
wm8750_out_flush(s);
694
void *wm8750_dac_buffer(void *opaque, int samples)
696
struct wm8750_s *s = (struct wm8750_s *) opaque;
697
/* XXX: Should check if there are <i>samples</i> free samples available */
698
void *ret = s->data_out + s->idx_out;
700
s->idx_out += samples << 2;
701
s->req_out -= samples << 2;
705
void wm8750_dac_commit(void *opaque)
707
struct wm8750_s *s = (struct wm8750_s *) opaque;
709
return wm8750_out_flush(s);
626
712
uint32_t wm8750_adc_dat(void *opaque)
628
714
struct wm8750_s *s = (struct wm8750_s *) opaque;
630
717
if (s->idx_in >= sizeof(s->data_in))
631
718
wm8750_in_load(s);
632
720
data = (uint32_t *) &s->data_in[s->idx_in];
635
return *data & s->inmask;
726
void wm8750_set_bclk_in(void *opaque, int new_hz)
728
struct wm8750_s *s = (struct wm8750_s *) opaque;
730
s->ext_adc_hz = new_hz;
731
s->ext_dac_hz = new_hz;
732
wm8750_clk_update(s, 1);