* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "hw/hw.h"
+#include "qemu/osdep.h"
#include "hw/i2c/i2c.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
#include "qemu/timer.h"
#include "ui/console.h"
+#define TYPE_LM8323 "lm8323"
+#define LM8323(obj) OBJECT_CHECK(LM823KbdState, (obj), TYPE_LM8323)
+
typedef struct {
- I2CSlave i2c;
+ I2CSlave parent_obj;
+
uint8_t i2c_dir;
uint8_t i2c_cycle;
uint8_t reg;
struct {
uint16_t file[256];
- uint8_t faddr;
+ uint8_t faddr;
uint8_t addr[3];
QEMUTimer *tm[3];
} pwm;
{
}
-static void lm_kbd_reset(LM823KbdState *s)
+static void lm_kbd_reset(DeviceState *dev)
{
+ LM823KbdState *s = LM8323(dev);
+
s->config = 0x80;
s->status = INT_NOINIT;
s->acttime = 125;
default:
lm_kbd_error(s, ERR_CMDUNK);
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
+ fprintf(stderr, "%s: unknown command %02x\n", __func__, reg);
return 0x00;
}
case LM832x_CMD_RESET:
if (value == 0xaa)
- lm_kbd_reset(s);
+ lm_kbd_reset(DEVICE(s));
else
lm_kbd_error(s, ERR_BADPAR);
s->reg = LM832x_GENERAL_ERROR;
if ((value & 3) && (value & 3) != 3) {
lm_kbd_error(s, ERR_BADPAR);
fprintf(stderr, "%s: invalid clock setting in RCPWM\n",
- __FUNCTION__);
+ __func__);
}
/* TODO: Validate that the command is only issued once */
break;
break;
}
- qemu_del_timer(s->pwm.tm[(value & 3) - 1]);
+ timer_del(s->pwm.tm[(value & 3) - 1]);
break;
case LM832x_GENERAL_ERROR:
break;
default:
lm_kbd_error(s, ERR_CMDUNK);
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
+ fprintf(stderr, "%s: unknown command %02x\n", __func__, reg);
break;
}
}
-static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
+static int lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+ LM823KbdState *s = LM8323(i2c);
switch (event) {
case I2C_START_RECV:
default:
break;
}
+
+ return 0;
}
-static int lm_i2c_rx(I2CSlave *i2c)
+static uint8_t lm_i2c_rx(I2CSlave *i2c)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+ LM823KbdState *s = LM8323(i2c);
return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
}
static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
{
- LM823KbdState *s = (LM823KbdState *) i2c;
+ LM823KbdState *s = LM8323(i2c);
if (!s->i2c_cycle)
s->reg = data;
.name = "LM8323",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.post_load = lm_kbd_post_load,
- .fields = (VMStateField []) {
- VMSTATE_I2C_SLAVE(i2c, LM823KbdState),
+ .fields = (VMStateField[]) {
+ VMSTATE_I2C_SLAVE(parent_obj, LM823KbdState),
VMSTATE_UINT8(i2c_dir, LM823KbdState),
VMSTATE_UINT8(i2c_cycle, LM823KbdState),
VMSTATE_UINT8(reg, LM823KbdState),
VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256),
VMSTATE_UINT8(pwm.faddr, LM823KbdState),
VMSTATE_BUFFER(pwm.addr, LM823KbdState),
- VMSTATE_TIMER_ARRAY(pwm.tm, LM823KbdState, 3),
+ VMSTATE_TIMER_PTR_ARRAY(pwm.tm, LM823KbdState, 3),
VMSTATE_END_OF_LIST()
}
};
-static int lm8323_init(I2CSlave *i2c)
+static void lm8323_realize(DeviceState *dev, Error **errp)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+ LM823KbdState *s = LM8323(dev);
s->model = 0x8323;
- s->pwm.tm[0] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm0_tick, s);
- s->pwm.tm[1] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm1_tick, s);
- s->pwm.tm[2] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm2_tick, s);
- qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
-
- lm_kbd_reset(s);
-
- qemu_register_reset((void *) lm_kbd_reset, s);
- return 0;
+ s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
+ s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
+ s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
+ qdev_init_gpio_out(dev, &s->nirq, 1);
}
void lm832x_key_event(DeviceState *dev, int key, int state)
{
- LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, I2C_SLAVE(dev));
+ LM823KbdState *s = LM8323(dev);
if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
return;
DeviceClass *dc = DEVICE_CLASS(klass);
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
- k->init = lm8323_init;
+ dc->reset = lm_kbd_reset;
+ dc->realize = lm8323_realize;
k->event = lm_i2c_event;
k->recv = lm_i2c_rx;
k->send = lm_i2c_tx;
}
static const TypeInfo lm8323_info = {
- .name = "lm8323",
+ .name = TYPE_LM8323,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(LM823KbdState),
.class_init = lm8323_class_init,