1 /* 2 * SMSC EMC141X temperature sensor. 3 * 4 * Copyright (c) 2020 Bytedance Corporation 5 * Written by John Wang <wangzhiqiang.bj@bytedance.com> 6 * 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. 11 * 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. 16 * 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/>. 19 */ 20 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" 29 30 #define SENSORS_COUNT_MAX 4 31 32 struct EMC141XState { 33 I2CSlave parent_obj; 34 struct { 35 uint8_t raw_temp_min; 36 uint8_t raw_temp_current; 37 uint8_t raw_temp_max; 38 } sensor[SENSORS_COUNT_MAX]; 39 uint8_t len; 40 uint8_t data; 41 uint8_t pointer; 42 }; 43 44 struct EMC141XClass { 45 I2CSlaveClass parent_class; 46 uint8_t model; 47 unsigned sensors_count; 48 }; 49 50 #define TYPE_EMC141X "emc141x" 51 OBJECT_DECLARE_TYPE(EMC141XState, EMC141XClass, EMC141X) 52 53 static void emc141x_get_temperature(Object *obj, Visitor *v, const char *name, 54 void *opaque, Error **errp) 55 { 56 EMC141XState *s = EMC141X(obj); 57 EMC141XClass *sc = EMC141X_GET_CLASS(s); 58 int64_t value; 59 unsigned tempid; 60 61 if (sscanf(name, "temperature%u", &tempid) != 1) { 62 error_setg(errp, "error reading %s: %s", name, g_strerror(errno)); 63 return; 64 } 65 66 if (tempid >= sc->sensors_count) { 67 error_setg(errp, "error reading %s", name); 68 return; 69 } 70 71 value = s->sensor[tempid].raw_temp_current * 1000; 72 73 visit_type_int(v, name, &value, errp); 74 } 75 76 static void emc141x_set_temperature(Object *obj, Visitor *v, const char *name, 77 void *opaque, Error **errp) 78 { 79 EMC141XState *s = EMC141X(obj); 80 EMC141XClass *sc = EMC141X_GET_CLASS(s); 81 int64_t temp; 82 unsigned tempid; 83 84 if (!visit_type_int(v, name, &temp, errp)) { 85 return; 86 } 87 88 if (sscanf(name, "temperature%u", &tempid) != 1) { 89 error_setg(errp, "error reading %s: %s", name, g_strerror(errno)); 90 return; 91 } 92 93 if (tempid >= sc->sensors_count) { 94 error_setg(errp, "error reading %s", name); 95 return; 96 } 97 98 s->sensor[tempid].raw_temp_current = temp / 1000; 99 } 100 101 static void emc141x_read(EMC141XState *s) 102 { 103 EMC141XClass *sc = EMC141X_GET_CLASS(s); 104 switch (s->pointer) { 105 case EMC141X_DEVICE_ID: 106 s->data = sc->model; 107 break; 108 case EMC141X_MANUFACTURER_ID: 109 s->data = MANUFACTURER_ID; 110 break; 111 case EMC141X_REVISION: 112 s->data = REVISION; 113 break; 114 case EMC141X_TEMP_HIGH0: 115 s->data = s->sensor[0].raw_temp_current; 116 break; 117 case EMC141X_TEMP_HIGH1: 118 s->data = s->sensor[1].raw_temp_current; 119 break; 120 case EMC141X_TEMP_HIGH2: 121 s->data = s->sensor[2].raw_temp_current; 122 break; 123 case EMC141X_TEMP_HIGH3: 124 s->data = s->sensor[3].raw_temp_current; 125 break; 126 case EMC141X_TEMP_MAX_HIGH0: 127 s->data = s->sensor[0].raw_temp_max; 128 break; 129 case EMC141X_TEMP_MAX_HIGH1: 130 s->data = s->sensor[1].raw_temp_max; 131 break; 132 case EMC141X_TEMP_MAX_HIGH2: 133 s->data = s->sensor[2].raw_temp_max; 134 break; 135 case EMC141X_TEMP_MAX_HIGH3: 136 s->data = s->sensor[3].raw_temp_max; 137 break; 138 case EMC141X_TEMP_MIN_HIGH0: 139 s->data = s->sensor[0].raw_temp_min; 140 break; 141 case EMC141X_TEMP_MIN_HIGH1: 142 s->data = s->sensor[1].raw_temp_min; 143 break; 144 case EMC141X_TEMP_MIN_HIGH2: 145 s->data = s->sensor[2].raw_temp_min; 146 break; 147 case EMC141X_TEMP_MIN_HIGH3: 148 s->data = s->sensor[3].raw_temp_min; 149 break; 150 default: 151 s->data = 0; 152 } 153 } 154 155 static void emc141x_write(EMC141XState *s) 156 { 157 switch (s->pointer) { 158 case EMC141X_TEMP_MAX_HIGH0: 159 s->sensor[0].raw_temp_max = s->data; 160 break; 161 case EMC141X_TEMP_MAX_HIGH1: 162 s->sensor[1].raw_temp_max = s->data; 163 break; 164 case EMC141X_TEMP_MAX_HIGH2: 165 s->sensor[2].raw_temp_max = s->data; 166 break; 167 case EMC141X_TEMP_MAX_HIGH3: 168 s->sensor[3].raw_temp_max = s->data; 169 break; 170 case EMC141X_TEMP_MIN_HIGH0: 171 s->sensor[0].raw_temp_min = s->data; 172 break; 173 case EMC141X_TEMP_MIN_HIGH1: 174 s->sensor[1].raw_temp_min = s->data; 175 break; 176 case EMC141X_TEMP_MIN_HIGH2: 177 s->sensor[2].raw_temp_min = s->data; 178 break; 179 case EMC141X_TEMP_MIN_HIGH3: 180 s->sensor[3].raw_temp_min = s->data; 181 break; 182 default: 183 s->data = 0; 184 } 185 } 186 187 static uint8_t emc141x_rx(I2CSlave *i2c) 188 { 189 EMC141XState *s = EMC141X(i2c); 190 191 if (s->len == 0) { 192 s->len++; 193 return s->data; 194 } else { 195 return 0xff; 196 } 197 } 198 199 static int emc141x_tx(I2CSlave *i2c, uint8_t data) 200 { 201 EMC141XState *s = EMC141X(i2c); 202 203 if (s->len == 0) { 204 /* first byte is the reg pointer */ 205 s->pointer = data; 206 s->len++; 207 } else if (s->len == 1) { 208 s->data = data; 209 emc141x_write(s); 210 } 211 212 return 0; 213 } 214 215 static int emc141x_event(I2CSlave *i2c, enum i2c_event event) 216 { 217 EMC141XState *s = EMC141X(i2c); 218 219 if (event == I2C_START_RECV) { 220 emc141x_read(s); 221 } 222 223 s->len = 0; 224 return 0; 225 } 226 227 static const VMStateDescription vmstate_emc141x = { 228 .name = "EMC141X", 229 .version_id = 0, 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() 237 } 238 }; 239 240 static void emc141x_reset(DeviceState *dev) 241 { 242 EMC141XState *s = EMC141X(dev); 243 int i; 244 245 for (i = 0; i < SENSORS_COUNT_MAX; i++) { 246 s->sensor[i].raw_temp_max = 0x55; 247 } 248 s->pointer = 0; 249 s->len = 0; 250 } 251 252 static void emc141x_initfn(Object *obj) 253 { 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); 266 } 267 268 static void emc141x_class_init(ObjectClass *klass, void *data) 269 { 270 DeviceClass *dc = DEVICE_CLASS(klass); 271 I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); 272 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; 278 } 279 280 static void emc1413_class_init(ObjectClass *klass, void *data) 281 { 282 EMC141XClass *ec = EMC141X_CLASS(klass); 283 284 emc141x_class_init(klass, data); 285 ec->model = EMC1413_DEVICE_ID; 286 ec->sensors_count = 3; 287 } 288 289 static void emc1414_class_init(ObjectClass *klass, void *data) 290 { 291 EMC141XClass *ec = EMC141X_CLASS(klass); 292 293 emc141x_class_init(klass, data); 294 ec->model = EMC1414_DEVICE_ID; 295 ec->sensors_count = 4; 296 } 297 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, 304 .abstract = true, 305 }; 306 307 static const TypeInfo emc1413_info = { 308 .name = "emc1413", 309 .parent = TYPE_EMC141X, 310 .class_init = emc1413_class_init, 311 }; 312 313 static const TypeInfo emc1414_info = { 314 .name = "emc1414", 315 .parent = TYPE_EMC141X, 316 .class_init = emc1414_class_init, 317 }; 318 319 static void emc141x_register_types(void) 320 { 321 type_register_static(&emc141x_info); 322 type_register_static(&emc1413_info); 323 type_register_static(&emc1414_info); 324 } 325 326 type_init(emc141x_register_types) 327