X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/5193be3be35f29a35bc465036cd64ad60d43385f..2222e0a633070f7f3eafcc9d0e95e7f1a4e6fe36:/hw/input/tsc210x.c diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c index aa5b6886ea..b068343771 100644 --- a/hw/input/tsc210x.c +++ b/hw/input/tsc210x.c @@ -19,6 +19,7 @@ * with this program; if not, see . */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "audio/audio.h" #include "qemu/timer.h" @@ -46,24 +47,25 @@ typedef struct { uint8_t out_fifo[16384]; uint16_t model; - int x, y; - int pressure; - - int state, page, offset, irq; - uint16_t command, dav; - - int busy; - int enabled; - int host_mode; - int function; - int nextfunction; - int precision; - int nextprecision; - int filter; - int pin_func; - int ref; - int timing; - int noise; + int32_t x, y; + bool pressure; + + uint8_t page, offset; + uint16_t dav; + + bool state; + bool irq; + bool command; + bool busy; + bool enabled; + bool host_mode; + uint8_t function, nextfunction; + uint8_t precision, nextprecision; + uint8_t filter; + uint8_t pin_func; + uint8_t ref; + uint8_t timing; + uint8_t noise; uint16_t audio_ctrl1; uint16_t audio_ctrl2; @@ -71,7 +73,7 @@ typedef struct { uint16_t pll[3]; uint16_t volume; int64_t volume_change; - int softstep; + bool softstep; uint16_t dac_power; int64_t powerdown; uint16_t filter_data[0x14]; @@ -92,6 +94,7 @@ typedef struct { int mode; int intr; } kb; + int64_t now; /* Time at migration */ } TSC210xState; static const int resolution[4] = { 12, 8, 10, 12 }; @@ -153,14 +156,14 @@ static const uint16_t mode_regs[16] = { static void tsc210x_reset(TSC210xState *s) { - s->state = 0; + s->state = false; s->pin_func = 2; - s->enabled = 0; - s->busy = 0; + s->enabled = false; + s->busy = false; s->nextfunction = 0; s->ref = 0; s->timing = 0; - s->irq = 0; + s->irq = false; s->dav = 0; s->audio_ctrl1 = 0x0000; @@ -171,7 +174,7 @@ static void tsc210x_reset(TSC210xState *s) s->pll[2] = 0x1fff; s->volume = 0xffff; s->dac_power = 0x8540; - s->softstep = 1; + s->softstep = true; s->volume_change = 0; s->powerdown = 0; s->filter_data[0x00] = 0x6be3; @@ -215,36 +218,6 @@ typedef struct { int fsref; } TSC210xRateInfo; -/* { rate, dsor, fsref } */ -static const TSC210xRateInfo tsc2101_rates[] = { - /* Fsref / 6.0 */ - { 7350, 7, 1 }, - { 8000, 7, 0 }, - /* Fsref / 5.5 */ - { 8018, 6, 1 }, - { 8727, 6, 0 }, - /* Fsref / 5.0 */ - { 8820, 5, 1 }, - { 9600, 5, 0 }, - /* Fsref / 4.0 */ - { 11025, 4, 1 }, - { 12000, 4, 0 }, - /* Fsref / 3.0 */ - { 14700, 3, 1 }, - { 16000, 3, 0 }, - /* Fsref / 2.0 */ - { 22050, 2, 1 }, - { 24000, 2, 0 }, - /* Fsref / 1.5 */ - { 29400, 1, 1 }, - { 32000, 1, 0 }, - /* Fsref */ - { 44100, 0, 1 }, - { 48000, 0, 0 }, - - { 0, 0, 0 }, -}; - /* { rate, dsor, fsref } */ static const TSC210xRateInfo tsc2102_rates[] = { /* Fsref / 6.0 */ @@ -595,7 +568,7 @@ static void tsc2102_control_register_write( s->enabled = !(value & 0x4000); if (s->busy && !s->enabled) timer_del(s->timer); - s->busy &= s->enabled; + s->busy = s->busy && s->enabled; s->nextfunction = (value >> 10) & 0xf; s->nextprecision = (value >> 8) & 3; s->filter = value & 0xff; @@ -802,7 +775,7 @@ static void tsc2102_audio_register_write( static void tsc210x_pin_update(TSC210xState *s) { int64_t expires; - int pin_state; + bool pin_state; switch (s->pin_func) { case 0: @@ -817,7 +790,7 @@ static void tsc210x_pin_update(TSC210xState *s) } if (!s->enabled) - pin_state = 0; + pin_state = false; if (pin_state != s->irq) { s->irq = pin_state; @@ -843,7 +816,7 @@ static void tsc210x_pin_update(TSC210xState *s) case TSC_MODE_TEMP1: case TSC_MODE_TEMP2: if (s->dav) - s->enabled = 0; + s->enabled = false; break; case TSC_MODE_AUX_SCAN: @@ -861,10 +834,11 @@ static void tsc210x_pin_update(TSC210xState *s) if (!s->enabled || s->busy || s->dav) return; - s->busy = 1; + s->busy = true; s->precision = s->nextprecision; s->function = s->nextfunction; - expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 10); + expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND >> 10); timer_mod(s->timer, expires); } @@ -895,7 +869,7 @@ static uint16_t tsc210x_read(TSC210xState *s) /* Allow sequential reads. */ s->offset ++; - s->state = 0; + s->state = false; return ret; } @@ -906,10 +880,10 @@ static void tsc210x_write(TSC210xState *s, uint16_t value) * command and data every second time. */ if (!s->state) { - s->command = value >> 15; + s->command = (value >> 15) != 0; s->page = (value >> 11) & 0x0f; s->offset = (value >> 5) & 0x3f; - s->state = 1; + s->state = true; } else { if (s->command) fprintf(stderr, "tsc210x_write: SPI overrun!\n"); @@ -929,7 +903,7 @@ static void tsc210x_write(TSC210xState *s, uint16_t value) } tsc210x_pin_update(s); - s->state = 0; + s->state = false; } } @@ -961,7 +935,7 @@ static void tsc210x_timer_tick(void *opaque) if (!s->busy) return; - s->busy = 0; + s->busy = false; s->dav |= mode_regs[s->function]; tsc210x_pin_update(s); qemu_irq_lower(s->davint); @@ -1002,108 +976,34 @@ static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out) s->i2s_rx_rate = in; } -static void tsc210x_save(QEMUFile *f, void *opaque) +static void tsc210x_pre_save(void *opaque) { TSC210xState *s = (TSC210xState *) opaque; - int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - int i; - - qemu_put_be16(f, s->x); - qemu_put_be16(f, s->y); - qemu_put_byte(f, s->pressure); - - qemu_put_byte(f, s->state); - qemu_put_byte(f, s->page); - qemu_put_byte(f, s->offset); - qemu_put_byte(f, s->command); - - qemu_put_byte(f, s->irq); - qemu_put_be16s(f, &s->dav); - - timer_put(f, s->timer); - qemu_put_byte(f, s->enabled); - qemu_put_byte(f, s->host_mode); - qemu_put_byte(f, s->function); - qemu_put_byte(f, s->nextfunction); - qemu_put_byte(f, s->precision); - qemu_put_byte(f, s->nextprecision); - qemu_put_byte(f, s->filter); - qemu_put_byte(f, s->pin_func); - qemu_put_byte(f, s->ref); - qemu_put_byte(f, s->timing); - qemu_put_be32(f, s->noise); - - qemu_put_be16s(f, &s->audio_ctrl1); - qemu_put_be16s(f, &s->audio_ctrl2); - qemu_put_be16s(f, &s->audio_ctrl3); - qemu_put_be16s(f, &s->pll[0]); - qemu_put_be16s(f, &s->pll[1]); - qemu_put_be16s(f, &s->volume); - qemu_put_sbe64(f, (s->volume_change - now)); - qemu_put_sbe64(f, (s->powerdown - now)); - qemu_put_byte(f, s->softstep); - qemu_put_be16s(f, &s->dac_power); - - for (i = 0; i < 0x14; i ++) - qemu_put_be16s(f, &s->filter_data[i]); + s->now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); } -static int tsc210x_load(QEMUFile *f, void *opaque, int version_id) +static int tsc210x_post_load(void *opaque, int version_id) { TSC210xState *s = (TSC210xState *) opaque; int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - int i; - - s->x = qemu_get_be16(f); - s->y = qemu_get_be16(f); - s->pressure = qemu_get_byte(f); - s->state = qemu_get_byte(f); - s->page = qemu_get_byte(f); - s->offset = qemu_get_byte(f); - s->command = qemu_get_byte(f); - - s->irq = qemu_get_byte(f); - qemu_get_be16s(f, &s->dav); - - timer_get(f, s->timer); - s->enabled = qemu_get_byte(f); - s->host_mode = qemu_get_byte(f); - s->function = qemu_get_byte(f); - if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) { + if (s->function >= ARRAY_SIZE(mode_regs)) { return -EINVAL; } - s->nextfunction = qemu_get_byte(f); - if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) { + if (s->nextfunction >= ARRAY_SIZE(mode_regs)) { return -EINVAL; } - s->precision = qemu_get_byte(f); - if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) { + if (s->precision >= ARRAY_SIZE(resolution)) { return -EINVAL; } - s->nextprecision = qemu_get_byte(f); - if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) { + if (s->nextprecision >= ARRAY_SIZE(resolution)) { return -EINVAL; } - s->filter = qemu_get_byte(f); - s->pin_func = qemu_get_byte(f); - s->ref = qemu_get_byte(f); - s->timing = qemu_get_byte(f); - s->noise = qemu_get_be32(f); - - qemu_get_be16s(f, &s->audio_ctrl1); - qemu_get_be16s(f, &s->audio_ctrl2); - qemu_get_be16s(f, &s->audio_ctrl3); - qemu_get_be16s(f, &s->pll[0]); - qemu_get_be16s(f, &s->pll[1]); - qemu_get_be16s(f, &s->volume); - s->volume_change = qemu_get_sbe64(f) + now; - s->powerdown = qemu_get_sbe64(f) + now; - s->softstep = qemu_get_byte(f); - qemu_get_be16s(f, &s->dac_power); - - for (i = 0; i < 0x14; i ++) - qemu_get_be16s(f, &s->filter_data[i]); + + s->volume_change -= s->now; + s->volume_change += now; + s->powerdown -= s->now; + s->powerdown += now; s->busy = timer_pending(s->timer); qemu_set_irq(s->pint, !s->irq); @@ -1112,13 +1012,65 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id) return 0; } +static VMStateField vmstatefields_tsc210x[] = { + VMSTATE_BOOL(enabled, TSC210xState), + VMSTATE_BOOL(host_mode, TSC210xState), + VMSTATE_BOOL(irq, TSC210xState), + VMSTATE_BOOL(command, TSC210xState), + VMSTATE_BOOL(pressure, TSC210xState), + VMSTATE_BOOL(softstep, TSC210xState), + VMSTATE_BOOL(state, TSC210xState), + VMSTATE_UINT16(dav, TSC210xState), + VMSTATE_INT32(x, TSC210xState), + VMSTATE_INT32(y, TSC210xState), + VMSTATE_UINT8(offset, TSC210xState), + VMSTATE_UINT8(page, TSC210xState), + VMSTATE_UINT8(filter, TSC210xState), + VMSTATE_UINT8(pin_func, TSC210xState), + VMSTATE_UINT8(ref, TSC210xState), + VMSTATE_UINT8(timing, TSC210xState), + VMSTATE_UINT8(noise, TSC210xState), + VMSTATE_UINT8(function, TSC210xState), + VMSTATE_UINT8(nextfunction, TSC210xState), + VMSTATE_UINT8(precision, TSC210xState), + VMSTATE_UINT8(nextprecision, TSC210xState), + VMSTATE_UINT16(audio_ctrl1, TSC210xState), + VMSTATE_UINT16(audio_ctrl2, TSC210xState), + VMSTATE_UINT16(audio_ctrl3, TSC210xState), + VMSTATE_UINT16_ARRAY(pll, TSC210xState, 3), + VMSTATE_UINT16(volume, TSC210xState), + VMSTATE_UINT16(dac_power, TSC210xState), + VMSTATE_INT64(volume_change, TSC210xState), + VMSTATE_INT64(powerdown, TSC210xState), + VMSTATE_INT64(now, TSC210xState), + VMSTATE_UINT16_ARRAY(filter_data, TSC210xState, 0x14), + VMSTATE_TIMER_PTR(timer, TSC210xState), + VMSTATE_END_OF_LIST() +}; + +static const VMStateDescription vmstate_tsc2102 = { + .name = "tsc2102", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = tsc210x_pre_save, + .post_load = tsc210x_post_load, + .fields = vmstatefields_tsc210x, +}; + +static const VMStateDescription vmstate_tsc2301 = { + .name = "tsc2301", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = tsc210x_pre_save, + .post_load = tsc210x_post_load, + .fields = vmstatefields_tsc210x, +}; + uWireSlave *tsc2102_init(qemu_irq pint) { TSC210xState *s; - s = (TSC210xState *) - g_malloc0(sizeof(TSC210xState)); - memset(s, 0, sizeof(TSC210xState)); + s = g_new0(TSC210xState, 1); s->x = 160; s->y = 160; s->pressure = 0; @@ -1155,8 +1107,7 @@ uWireSlave *tsc2102_init(qemu_irq pint) AUD_register_card(s->name, &s->card); qemu_register_reset((void *) tsc210x_reset, s); - register_savevm(NULL, s->name, -1, 0, - tsc210x_save, tsc210x_load, s); + vmstate_register(NULL, 0, &vmstate_tsc2102, s); return &s->chip; } @@ -1165,9 +1116,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav) { TSC210xState *s; - s = (TSC210xState *) - g_malloc0(sizeof(TSC210xState)); - memset(s, 0, sizeof(TSC210xState)); + s = g_new0(TSC210xState, 1); s->x = 400; s->y = 240; s->pressure = 0; @@ -1206,7 +1155,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav) AUD_register_card(s->name, &s->card); qemu_register_reset((void *) tsc210x_reset, s); - register_savevm(NULL, s->name, -1, 0, tsc210x_save, tsc210x_load, s); + vmstate_register(NULL, 0, &vmstate_tsc2301, s); return &s->chip; }