10
#include "qemu/osdep.h"
12
#include "hw/i2c/i2c.h"
13
#include "qapi/error.h"
14
#include "qapi/visitor.h"
15
#include "migration/vmstate.h"
17
#define NUM_REGISTERS 0x33
19
typedef struct DPS310State {
24
uint8_t regs[NUM_REGISTERS];
31
#define TYPE_DPS310 "dps310"
32
#define DPS310(obj) OBJECT_CHECK(DPS310State, (obj), TYPE_DPS310)
34
#define DPS310_PRS_B2 0x00
35
#define DPS310_PRS_B1 0x01
36
#define DPS310_PRS_B0 0x02
37
#define DPS310_TMP_B2 0x03
38
#define DPS310_TMP_B1 0x04
39
#define DPS310_TMP_B0 0x05
40
#define DPS310_PRS_CFG 0x06
41
#define DPS310_TMP_CFG 0x07
42
#define DPS310_TMP_RATE_BITS (0x70)
43
#define DPS310_MEAS_CFG 0x08
44
#define DPS310_MEAS_CTRL_BITS (0x07)
45
#define DPS310_PRESSURE_EN BIT(0)
46
#define DPS310_TEMP_EN BIT(1)
47
#define DPS310_BACKGROUND BIT(2)
48
#define DPS310_PRS_RDY BIT(4)
49
#define DPS310_TMP_RDY BIT(5)
50
#define DPS310_SENSOR_RDY BIT(6)
51
#define DPS310_COEF_RDY BIT(7)
52
#define DPS310_CFG_REG 0x09
53
#define DPS310_RESET 0x0c
54
#define DPS310_RESET_MAGIC (BIT(0) | BIT(3))
55
#define DPS310_COEF_BASE 0x10
56
#define DPS310_COEF_LAST 0x21
57
#define DPS310_COEF_SRC 0x28
59
static void dps310_reset(DeviceState *dev)
61
DPS310State *s = DPS310(dev);
63
static const uint8_t regs_reset_state[sizeof(s->regs)] = {
64
0xfe, 0x2f, 0xee, 0x02, 0x69, 0xa6, 0x00, 0x80, 0xc7, 0x00, 0x00, 0x00,
65
0x00, 0x10, 0x00, 0x00, 0x0e, 0x1e, 0xdd, 0x13, 0xca, 0x5f, 0x21, 0x52,
66
0xf9, 0xc6, 0x04, 0xd1, 0xdb, 0x47, 0x00, 0x5b, 0xfb, 0x3a, 0x00, 0x00,
67
0x20, 0x49, 0x4e, 0xa5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71
memcpy(s->regs, regs_reset_state, sizeof(s->regs));
75
s->regs[DPS310_MEAS_CFG] = DPS310_COEF_RDY | DPS310_SENSOR_RDY
76
| DPS310_TMP_RDY | DPS310_PRS_RDY;
79
static uint8_t dps310_read(DPS310State *s, uint8_t reg)
81
if (reg >= sizeof(s->regs)) {
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: register 0x%02x out of bounds\n",
83
__func__, s->pointer);
98
case DPS310_COEF_BASE...DPS310_COEF_LAST:
103
qemu_log_mask(LOG_UNIMP, "%s: register 0x%02x unimplemented\n",
109
static void dps310_write(DPS310State *s, uint8_t reg, uint8_t data)
111
if (reg >= sizeof(s->regs)) {
112
qemu_log_mask(LOG_GUEST_ERROR, "%s: register %d out of bounds\n",
113
__func__, s->pointer);
119
if (data == DPS310_RESET_MAGIC) {
120
device_cold_reset(DEVICE(s));
125
case DPS310_MEAS_CFG:
130
qemu_log_mask(LOG_UNIMP, "%s: register 0x%02x unimplemented\n",
136
static uint8_t dps310_rx(I2CSlave *i2c)
138
DPS310State *s = DPS310(i2c);
141
return dps310_read(s, s->pointer++);
147
static int dps310_tx(I2CSlave *i2c, uint8_t data)
149
DPS310State *s = DPS310(i2c);
158
} else if (s->len == 1) {
159
dps310_write(s, s->pointer++, data);
165
static int dps310_event(I2CSlave *i2c, enum i2c_event event)
167
DPS310State *s = DPS310(i2c);
176
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid recv sequence\n",
187
static const VMStateDescription vmstate_dps310 = {
190
.minimum_version_id = 0,
191
.fields = (const VMStateField[]) {
192
VMSTATE_UINT8(len, DPS310State),
193
VMSTATE_UINT8_ARRAY(regs, DPS310State, NUM_REGISTERS),
194
VMSTATE_UINT8(pointer, DPS310State),
195
VMSTATE_I2C_SLAVE(i2c, DPS310State),
196
VMSTATE_END_OF_LIST()
200
static void dps310_class_init(ObjectClass *klass, void *data)
202
DeviceClass *dc = DEVICE_CLASS(klass);
203
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
205
k->event = dps310_event;
208
dc->reset = dps310_reset;
209
dc->vmsd = &vmstate_dps310;
212
static const TypeInfo dps310_info = {
214
.parent = TYPE_I2C_SLAVE,
215
.instance_size = sizeof(DPS310State),
216
.class_init = dps310_class_init,
219
static void dps310_register_types(void)
221
type_register_static(&dps310_info);
224
type_init(dps310_register_types)