2 * SMSC EMC141X temperature sensor.
4 * Copyright (c) 2020 Bytedance Corporation
5 * Written by John Wang <wangzhiqiang.bj@bytedance.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 or
10 * (at your option) version 3 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "hw/i2c/i2c.h"
23 #include "migration/vmstate.h"
24 #include "qapi/error.h"
25 #include "qapi/visitor.h"
26 #include "qemu/module.h"
27 #include "qom/object.h"
28 #include "hw/sensor/emc141x_regs.h"
30 #define SENSORS_COUNT_MAX 4
36 uint8_t raw_temp_current
;
38 } sensor
[SENSORS_COUNT_MAX
];
45 I2CSlaveClass parent_class
;
47 unsigned sensors_count
;
50 #define TYPE_EMC141X "emc141x"
51 OBJECT_DECLARE_TYPE(EMC141XState
, EMC141XClass
, EMC141X
)
53 static void emc141x_get_temperature(Object
*obj
, Visitor
*v
, const char *name
,
54 void *opaque
, Error
**errp
)
56 EMC141XState
*s
= EMC141X(obj
);
57 EMC141XClass
*sc
= EMC141X_GET_CLASS(s
);
61 if (sscanf(name
, "temperature%u", &tempid
) != 1) {
62 error_setg(errp
, "error reading %s: %s", name
, g_strerror(errno
));
66 if (tempid
>= sc
->sensors_count
) {
67 error_setg(errp
, "error reading %s", name
);
71 value
= s
->sensor
[tempid
].raw_temp_current
* 1000;
73 visit_type_int(v
, name
, &value
, errp
);
76 static void emc141x_set_temperature(Object
*obj
, Visitor
*v
, const char *name
,
77 void *opaque
, Error
**errp
)
79 EMC141XState
*s
= EMC141X(obj
);
80 EMC141XClass
*sc
= EMC141X_GET_CLASS(s
);
84 if (!visit_type_int(v
, name
, &temp
, errp
)) {
88 if (sscanf(name
, "temperature%u", &tempid
) != 1) {
89 error_setg(errp
, "error reading %s: %s", name
, g_strerror(errno
));
93 if (tempid
>= sc
->sensors_count
) {
94 error_setg(errp
, "error reading %s", name
);
98 s
->sensor
[tempid
].raw_temp_current
= temp
/ 1000;
101 static void emc141x_read(EMC141XState
*s
)
103 EMC141XClass
*sc
= EMC141X_GET_CLASS(s
);
104 switch (s
->pointer
) {
105 case EMC141X_DEVICE_ID
:
108 case EMC141X_MANUFACTURER_ID
:
109 s
->data
= MANUFACTURER_ID
;
111 case EMC141X_REVISION
:
114 case EMC141X_TEMP_HIGH0
:
115 s
->data
= s
->sensor
[0].raw_temp_current
;
117 case EMC141X_TEMP_HIGH1
:
118 s
->data
= s
->sensor
[1].raw_temp_current
;
120 case EMC141X_TEMP_HIGH2
:
121 s
->data
= s
->sensor
[2].raw_temp_current
;
123 case EMC141X_TEMP_HIGH3
:
124 s
->data
= s
->sensor
[3].raw_temp_current
;
126 case EMC141X_TEMP_MAX_HIGH0
:
127 s
->data
= s
->sensor
[0].raw_temp_max
;
129 case EMC141X_TEMP_MAX_HIGH1
:
130 s
->data
= s
->sensor
[1].raw_temp_max
;
132 case EMC141X_TEMP_MAX_HIGH2
:
133 s
->data
= s
->sensor
[2].raw_temp_max
;
135 case EMC141X_TEMP_MAX_HIGH3
:
136 s
->data
= s
->sensor
[3].raw_temp_max
;
138 case EMC141X_TEMP_MIN_HIGH0
:
139 s
->data
= s
->sensor
[0].raw_temp_min
;
141 case EMC141X_TEMP_MIN_HIGH1
:
142 s
->data
= s
->sensor
[1].raw_temp_min
;
144 case EMC141X_TEMP_MIN_HIGH2
:
145 s
->data
= s
->sensor
[2].raw_temp_min
;
147 case EMC141X_TEMP_MIN_HIGH3
:
148 s
->data
= s
->sensor
[3].raw_temp_min
;
155 static void emc141x_write(EMC141XState
*s
)
157 switch (s
->pointer
) {
158 case EMC141X_TEMP_MAX_HIGH0
:
159 s
->sensor
[0].raw_temp_max
= s
->data
;
161 case EMC141X_TEMP_MAX_HIGH1
:
162 s
->sensor
[1].raw_temp_max
= s
->data
;
164 case EMC141X_TEMP_MAX_HIGH2
:
165 s
->sensor
[2].raw_temp_max
= s
->data
;
167 case EMC141X_TEMP_MAX_HIGH3
:
168 s
->sensor
[3].raw_temp_max
= s
->data
;
170 case EMC141X_TEMP_MIN_HIGH0
:
171 s
->sensor
[0].raw_temp_min
= s
->data
;
173 case EMC141X_TEMP_MIN_HIGH1
:
174 s
->sensor
[1].raw_temp_min
= s
->data
;
176 case EMC141X_TEMP_MIN_HIGH2
:
177 s
->sensor
[2].raw_temp_min
= s
->data
;
179 case EMC141X_TEMP_MIN_HIGH3
:
180 s
->sensor
[3].raw_temp_min
= s
->data
;
187 static uint8_t emc141x_rx(I2CSlave
*i2c
)
189 EMC141XState
*s
= EMC141X(i2c
);
199 static int emc141x_tx(I2CSlave
*i2c
, uint8_t data
)
201 EMC141XState
*s
= EMC141X(i2c
);
204 /* first byte is the reg pointer */
207 } else if (s
->len
== 1) {
215 static int emc141x_event(I2CSlave
*i2c
, enum i2c_event event
)
217 EMC141XState
*s
= EMC141X(i2c
);
219 if (event
== I2C_START_RECV
) {
227 static const VMStateDescription vmstate_emc141x
= {
230 .minimum_version_id
= 0,
231 .fields
= (VMStateField
[]) {
232 VMSTATE_UINT8(len
, EMC141XState
),
233 VMSTATE_UINT8(data
, EMC141XState
),
234 VMSTATE_UINT8(pointer
, EMC141XState
),
235 VMSTATE_I2C_SLAVE(parent_obj
, EMC141XState
),
236 VMSTATE_END_OF_LIST()
240 static void emc141x_reset(DeviceState
*dev
)
242 EMC141XState
*s
= EMC141X(dev
);
245 for (i
= 0; i
< SENSORS_COUNT_MAX
; i
++) {
246 s
->sensor
[i
].raw_temp_max
= 0x55;
252 static void emc141x_initfn(Object
*obj
)
254 object_property_add(obj
, "temperature0", "int",
255 emc141x_get_temperature
,
256 emc141x_set_temperature
, NULL
, NULL
);
257 object_property_add(obj
, "temperature1", "int",
258 emc141x_get_temperature
,
259 emc141x_set_temperature
, NULL
, NULL
);
260 object_property_add(obj
, "temperature2", "int",
261 emc141x_get_temperature
,
262 emc141x_set_temperature
, NULL
, NULL
);
263 object_property_add(obj
, "temperature3", "int",
264 emc141x_get_temperature
,
265 emc141x_set_temperature
, NULL
, NULL
);
268 static void emc141x_class_init(ObjectClass
*klass
, void *data
)
270 DeviceClass
*dc
= DEVICE_CLASS(klass
);
271 I2CSlaveClass
*k
= I2C_SLAVE_CLASS(klass
);
273 dc
->reset
= emc141x_reset
;
274 k
->event
= emc141x_event
;
275 k
->recv
= emc141x_rx
;
276 k
->send
= emc141x_tx
;
277 dc
->vmsd
= &vmstate_emc141x
;
280 static void emc1413_class_init(ObjectClass
*klass
, void *data
)
282 EMC141XClass
*ec
= EMC141X_CLASS(klass
);
284 emc141x_class_init(klass
, data
);
285 ec
->model
= EMC1413_DEVICE_ID
;
286 ec
->sensors_count
= 3;
289 static void emc1414_class_init(ObjectClass
*klass
, void *data
)
291 EMC141XClass
*ec
= EMC141X_CLASS(klass
);
293 emc141x_class_init(klass
, data
);
294 ec
->model
= EMC1414_DEVICE_ID
;
295 ec
->sensors_count
= 4;
298 static const TypeInfo emc141x_info
= {
299 .name
= TYPE_EMC141X
,
300 .parent
= TYPE_I2C_SLAVE
,
301 .instance_size
= sizeof(EMC141XState
),
302 .class_size
= sizeof(EMC141XClass
),
303 .instance_init
= emc141x_initfn
,
307 static const TypeInfo emc1413_info
= {
309 .parent
= TYPE_EMC141X
,
310 .class_init
= emc1413_class_init
,
313 static const TypeInfo emc1414_info
= {
315 .parent
= TYPE_EMC141X
,
316 .class_init
= emc1414_class_init
,
319 static void emc141x_register_types(void)
321 type_register_static(&emc141x_info
);
322 type_register_static(&emc1413_info
);
323 type_register_static(&emc1414_info
);
326 type_init(emc141x_register_types
)