#include "qemu-timer.h"
#include "console.h"
-struct lm_kbd_s {
+typedef struct {
i2c_slave i2c;
int i2c_dir;
int i2c_cycle;
uint8_t addr[3];
QEMUTimer *tm[3];
} pwm;
-};
+} LM823KbdState;
#define INT_KEYPAD (1 << 0)
#define INT_ERROR (1 << 3)
#define ERR_KEYOVR (1 << 2)
#define ERR_FIFOOVR (1 << 6)
-static void lm_kbd_irq_update(struct lm_kbd_s *s)
+static void lm_kbd_irq_update(LM823KbdState *s)
{
qemu_set_irq(s->nirq, !s->status);
}
-static void lm_kbd_gpio_update(struct lm_kbd_s *s)
+static void lm_kbd_gpio_update(LM823KbdState *s)
{
}
-static void lm_kbd_reset(struct lm_kbd_s *s)
+static void lm_kbd_reset(LM823KbdState *s)
{
s->config = 0x80;
s->status = INT_NOINIT;
lm_kbd_gpio_update(s);
}
-static void lm_kbd_error(struct lm_kbd_s *s, int err)
+static void lm_kbd_error(LM823KbdState *s, int err)
{
s->error |= err;
s->status |= INT_ERROR;
lm_kbd_irq_update(s);
}
-static void lm_kbd_pwm_tick(struct lm_kbd_s *s, int line)
+static void lm_kbd_pwm_tick(LM823KbdState *s, int line)
{
}
-static void lm_kbd_pwm_start(struct lm_kbd_s *s, int line)
+static void lm_kbd_pwm_start(LM823KbdState *s, int line)
{
lm_kbd_pwm_tick(s, line);
}
#define LM832x_MAX_KPX 8
#define LM832x_MAX_KPY 12
-static uint8_t lm_kbd_read(struct lm_kbd_s *s, int reg, int byte)
+static uint8_t lm_kbd_read(LM823KbdState *s, int reg, int byte)
{
int ret;
return ret >> (byte << 3);
}
-static void lm_kbd_write(struct lm_kbd_s *s, int reg, int byte, uint8_t value)
+static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
{
switch (reg) {
case LM832x_CMD_WRITE_CFG:
static void lm_i2c_event(i2c_slave *i2c, enum i2c_event event)
{
- struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
+ LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
switch (event) {
case I2C_START_RECV:
static int lm_i2c_rx(i2c_slave *i2c)
{
- struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
+ LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
}
static int lm_i2c_tx(i2c_slave *i2c, uint8_t data)
{
- struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
+ LM823KbdState *s = (LM823KbdState *) i2c;
if (!s->i2c_cycle)
s->reg = data;
static void lm_kbd_save(QEMUFile *f, void *opaque)
{
- struct lm_kbd_s *s = (struct lm_kbd_s *) opaque;
+ LM823KbdState *s = (LM823KbdState *) opaque;
int i;
i2c_slave_save(f, &s->i2c);
static int lm_kbd_load(QEMUFile *f, void *opaque, int version_id)
{
- struct lm_kbd_s *s = (struct lm_kbd_s *) opaque;
+ LM823KbdState *s = (LM823KbdState *) opaque;
int i;
i2c_slave_load(f, &s->i2c);
return 0;
}
-struct i2c_slave *lm8323_init(i2c_bus *bus, qemu_irq nirq)
+static void lm8323_init(i2c_slave *i2c)
{
- struct lm_kbd_s *s;
+ LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
- s = (struct lm_kbd_s *) i2c_slave_init(bus, 0, sizeof(struct lm_kbd_s));
s->model = 0x8323;
s->pwm.tm[0] = qemu_new_timer(vm_clock, lm_kbd_pwm0_tick, s);
s->pwm.tm[1] = qemu_new_timer(vm_clock, lm_kbd_pwm1_tick, s);
s->pwm.tm[2] = qemu_new_timer(vm_clock, lm_kbd_pwm2_tick, s);
- s->nirq = nirq;
-
- s->i2c.event = lm_i2c_event;
- s->i2c.recv = lm_i2c_rx;
- s->i2c.send = lm_i2c_tx;
+ qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
lm_kbd_reset(s);
- qemu_register_reset((void *) lm_kbd_reset, s);
+ qemu_register_reset((void *) lm_kbd_reset, 0, s);
register_savevm("LM8323", -1, 0, lm_kbd_save, lm_kbd_load, s);
-
- return &s->i2c;
}
void lm832x_key_event(struct i2c_slave *i2c, int key, int state)
{
- struct lm_kbd_s *s = (struct lm_kbd_s *) i2c;
+ LM823KbdState *s = (LM823KbdState *) i2c;
if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
return;
s->status |= INT_KEYPAD;
lm_kbd_irq_update(s);
}
+
+static I2CSlaveInfo lm8323_info = {
+ .init = lm8323_init,
+ .event = lm_i2c_event,
+ .recv = lm_i2c_rx,
+ .send = lm_i2c_tx
+};
+
+static void lm832x_register_devices(void)
+{
+ i2c_register_slave("lm8323", sizeof(LM823KbdState), &lm8323_info);
+}
+
+device_init(lm832x_register_devices)