27
#include "qemu/osdep.h"
28
#include "hw/i2c/i2c.h"
29
#include "migration/vmstate.h"
30
#include "qapi/error.h"
31
#include "qapi/visitor.h"
32
#include "qemu/module.h"
33
#include "qom/object.h"
36
#define TMP421_MANUFACTURER_ID 0x55
37
#define TMP421_DEVICE_ID 0x21
38
#define TMP422_DEVICE_ID 0x22
39
#define TMP423_DEVICE_ID 0x23
41
typedef struct DeviceInfo {
46
static const DeviceInfo devices[] = {
47
{ TMP421_DEVICE_ID, "tmp421" },
48
{ TMP422_DEVICE_ID, "tmp422" },
49
{ TMP423_DEVICE_ID, "tmp423" },
57
int16_t temperature[4];
70
I2CSlaveClass parent_class;
74
#define TYPE_TMP421 "tmp421-generic"
75
OBJECT_DECLARE_TYPE(TMP421State, TMP421Class, TMP421)
79
#define TMP421_STATUS_REG 0x08
80
#define TMP421_STATUS_BUSY (1 << 7)
81
#define TMP421_CONFIG_REG_1 0x09
82
#define TMP421_CONFIG_RANGE (1 << 2)
83
#define TMP421_CONFIG_SHUTDOWN (1 << 6)
84
#define TMP421_CONFIG_REG_2 0x0A
85
#define TMP421_CONFIG_RC (1 << 2)
86
#define TMP421_CONFIG_LEN (1 << 3)
87
#define TMP421_CONFIG_REN (1 << 4)
88
#define TMP421_CONFIG_REN2 (1 << 5)
89
#define TMP421_CONFIG_REN3 (1 << 6)
91
#define TMP421_CONVERSION_RATE_REG 0x0B
92
#define TMP421_ONE_SHOT 0x0F
94
#define TMP421_RESET 0xFC
95
#define TMP421_MANUFACTURER_ID_REG 0xFE
96
#define TMP421_DEVICE_ID_REG 0xFF
98
#define TMP421_TEMP_MSB0 0x00
99
#define TMP421_TEMP_MSB1 0x01
100
#define TMP421_TEMP_MSB2 0x02
101
#define TMP421_TEMP_MSB3 0x03
102
#define TMP421_TEMP_LSB0 0x10
103
#define TMP421_TEMP_LSB1 0x11
104
#define TMP421_TEMP_LSB2 0x12
105
#define TMP421_TEMP_LSB3 0x13
107
static const int32_t mins[2] = { -40000, -55000 };
108
static const int32_t maxs[2] = { 127000, 150000 };
110
static void tmp421_get_temperature(Object *obj, Visitor *v, const char *name,
111
void *opaque, Error **errp)
113
TMP421State *s = TMP421(obj);
114
bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
115
int offset = ext_range * 64 * 256;
119
if (sscanf(name, "temperature%d", &tempid) != 1) {
120
error_setg(errp, "error reading %s: %s", name, g_strerror(errno));
124
if (tempid >= 4 || tempid < 0) {
125
error_setg(errp, "error reading %s", name);
129
value = ((s->temperature[tempid] - offset) * 1000 + 128) / 256;
131
visit_type_int(v, name, &value, errp);
137
static void tmp421_set_temperature(Object *obj, Visitor *v, const char *name,
138
void *opaque, Error **errp)
140
TMP421State *s = TMP421(obj);
142
bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
143
int offset = ext_range * 64 * 256;
146
if (!visit_type_int(v, name, &temp, errp)) {
150
if (temp >= maxs[ext_range] || temp < mins[ext_range]) {
151
error_setg(errp, "value %" PRId64 ".%03" PRIu64 " C is out of range",
152
temp / 1000, temp % 1000);
156
if (sscanf(name, "temperature%d", &tempid) != 1) {
157
error_setg(errp, "error reading %s: %s", name, g_strerror(errno));
161
if (tempid >= 4 || tempid < 0) {
162
error_setg(errp, "error reading %s", name);
166
s->temperature[tempid] = (int16_t) ((temp * 256 - 128) / 1000) + offset;
169
static void tmp421_read(TMP421State *s)
171
TMP421Class *sc = TMP421_GET_CLASS(s);
175
switch (s->pointer) {
176
case TMP421_MANUFACTURER_ID_REG:
177
s->buf[s->len++] = TMP421_MANUFACTURER_ID;
179
case TMP421_DEVICE_ID_REG:
180
s->buf[s->len++] = sc->dev->model;
182
case TMP421_CONFIG_REG_1:
183
s->buf[s->len++] = s->config[0];
185
case TMP421_CONFIG_REG_2:
186
s->buf[s->len++] = s->config[1];
188
case TMP421_CONVERSION_RATE_REG:
189
s->buf[s->len++] = s->rate;
191
case TMP421_STATUS_REG:
192
s->buf[s->len++] = s->status;
196
case TMP421_TEMP_MSB0:
197
s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 8);
198
s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
200
case TMP421_TEMP_MSB1:
201
s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 8);
202
s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
204
case TMP421_TEMP_MSB2:
205
s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 8);
206
s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
208
case TMP421_TEMP_MSB3:
209
s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 8);
210
s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
212
case TMP421_TEMP_LSB0:
213
s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
215
case TMP421_TEMP_LSB1:
216
s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
218
case TMP421_TEMP_LSB2:
219
s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
221
case TMP421_TEMP_LSB3:
222
s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
227
static void tmp421_reset(I2CSlave *i2c);
229
static void tmp421_write(TMP421State *s)
231
switch (s->pointer) {
232
case TMP421_CONVERSION_RATE_REG:
235
case TMP421_CONFIG_REG_1:
236
s->config[0] = s->buf[0];
238
case TMP421_CONFIG_REG_2:
239
s->config[1] = s->buf[0];
242
tmp421_reset(I2C_SLAVE(s));
247
static uint8_t tmp421_rx(I2CSlave *i2c)
249
TMP421State *s = TMP421(i2c);
252
return s->buf[s->len++];
258
static int tmp421_tx(I2CSlave *i2c, uint8_t data)
260
TMP421State *s = TMP421(i2c);
267
} else if (s->len == 1) {
277
static int tmp421_event(I2CSlave *i2c, enum i2c_event event)
279
TMP421State *s = TMP421(i2c);
281
if (event == I2C_START_RECV) {
289
static const VMStateDescription vmstate_tmp421 = {
292
.minimum_version_id = 0,
293
.fields = (const VMStateField[]) {
294
VMSTATE_UINT8(len, TMP421State),
295
VMSTATE_UINT8_ARRAY(buf, TMP421State, 2),
296
VMSTATE_UINT8(pointer, TMP421State),
297
VMSTATE_UINT8_ARRAY(config, TMP421State, 2),
298
VMSTATE_UINT8(status, TMP421State),
299
VMSTATE_UINT8(rate, TMP421State),
300
VMSTATE_INT16_ARRAY(temperature, TMP421State, 4),
301
VMSTATE_I2C_SLAVE(i2c, TMP421State),
302
VMSTATE_END_OF_LIST()
306
static void tmp421_reset(I2CSlave *i2c)
308
TMP421State *s = TMP421(i2c);
309
TMP421Class *sc = TMP421_GET_CLASS(s);
311
memset(s->temperature, 0, sizeof(s->temperature));
317
switch (sc->dev->model) {
318
case TMP421_DEVICE_ID:
321
case TMP422_DEVICE_ID:
324
case TMP423_DEVICE_ID:
333
static void tmp421_realize(DeviceState *dev, Error **errp)
335
TMP421State *s = TMP421(dev);
337
tmp421_reset(&s->i2c);
340
static void tmp421_class_init(ObjectClass *klass, void *data)
342
DeviceClass *dc = DEVICE_CLASS(klass);
343
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
344
TMP421Class *sc = TMP421_CLASS(klass);
346
dc->realize = tmp421_realize;
347
k->event = tmp421_event;
350
dc->vmsd = &vmstate_tmp421;
351
sc->dev = (DeviceInfo *) data;
353
object_class_property_add(klass, "temperature0", "int",
354
tmp421_get_temperature,
355
tmp421_set_temperature, NULL, NULL);
356
object_class_property_add(klass, "temperature1", "int",
357
tmp421_get_temperature,
358
tmp421_set_temperature, NULL, NULL);
359
object_class_property_add(klass, "temperature2", "int",
360
tmp421_get_temperature,
361
tmp421_set_temperature, NULL, NULL);
362
object_class_property_add(klass, "temperature3", "int",
363
tmp421_get_temperature,
364
tmp421_set_temperature, NULL, NULL);
367
static const TypeInfo tmp421_info = {
369
.parent = TYPE_I2C_SLAVE,
370
.instance_size = sizeof(TMP421State),
371
.class_size = sizeof(TMP421Class),
375
static void tmp421_register_types(void)
379
type_register_static(&tmp421_info);
380
for (i = 0; i < ARRAY_SIZE(devices); ++i) {
382
.name = devices[i].name,
383
.parent = TYPE_TMP421,
384
.class_init = tmp421_class_init,
385
.class_data = (void *) &devices[i],
391
type_init(tmp421_register_types)