adm1272.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /*
  2. * Analog Devices ADM1272 High Voltage Positive Hot Swap Controller and Digital
  3. * Power Monitor with PMBus
  4. *
  5. * Copyright 2021 Google LLC
  6. *
  7. * SPDX-License-Identifier: GPL-2.0-or-later
  8. */
  9. #include "qemu/osdep.h"
  10. #include "hw/i2c/pmbus_device.h"
  11. #include "hw/irq.h"
  12. #include "migration/vmstate.h"
  13. #include "qapi/error.h"
  14. #include "qapi/visitor.h"
  15. #include "qemu/log.h"
  16. #include "qemu/module.h"
  17. #define TYPE_ADM1272 "adm1272"
  18. #define ADM1272(obj) OBJECT_CHECK(ADM1272State, (obj), TYPE_ADM1272)
  19. #define ADM1272_RESTART_TIME 0xCC
  20. #define ADM1272_MFR_PEAK_IOUT 0xD0
  21. #define ADM1272_MFR_PEAK_VIN 0xD1
  22. #define ADM1272_MFR_PEAK_VOUT 0xD2
  23. #define ADM1272_MFR_PMON_CONTROL 0xD3
  24. #define ADM1272_MFR_PMON_CONFIG 0xD4
  25. #define ADM1272_MFR_ALERT1_CONFIG 0xD5
  26. #define ADM1272_MFR_ALERT2_CONFIG 0xD6
  27. #define ADM1272_MFR_PEAK_TEMPERATURE 0xD7
  28. #define ADM1272_MFR_DEVICE_CONFIG 0xD8
  29. #define ADM1272_MFR_POWER_CYCLE 0xD9
  30. #define ADM1272_MFR_PEAK_PIN 0xDA
  31. #define ADM1272_MFR_READ_PIN_EXT 0xDB
  32. #define ADM1272_MFR_READ_EIN_EXT 0xDC
  33. #define ADM1272_HYSTERESIS_LOW 0xF2
  34. #define ADM1272_HYSTERESIS_HIGH 0xF3
  35. #define ADM1272_STATUS_HYSTERESIS 0xF4
  36. #define ADM1272_STATUS_GPIO 0xF5
  37. #define ADM1272_STRT_UP_IOUT_LIM 0xF6
  38. /* Defaults */
  39. #define ADM1272_OPERATION_DEFAULT 0x80
  40. #define ADM1272_CAPABILITY_DEFAULT 0xB0
  41. #define ADM1272_CAPABILITY_NO_PEC 0x30
  42. #define ADM1272_DIRECT_MODE 0x40
  43. #define ADM1272_HIGH_LIMIT_DEFAULT 0x0FFF
  44. #define ADM1272_PIN_OP_DEFAULT 0x7FFF
  45. #define ADM1272_PMBUS_REVISION_DEFAULT 0x22
  46. #define ADM1272_MFR_ID_DEFAULT "ADI"
  47. #define ADM1272_MODEL_DEFAULT "ADM1272-A1"
  48. #define ADM1272_MFR_DEFAULT_REVISION "25"
  49. #define ADM1272_DEFAULT_DATE "160301"
  50. #define ADM1272_RESTART_TIME_DEFAULT 0x64
  51. #define ADM1272_PMON_CONTROL_DEFAULT 0x1
  52. #define ADM1272_PMON_CONFIG_DEFAULT 0x3F35
  53. #define ADM1272_DEVICE_CONFIG_DEFAULT 0x8
  54. #define ADM1272_HYSTERESIS_HIGH_DEFAULT 0xFFFF
  55. #define ADM1272_STRT_UP_IOUT_LIM_DEFAULT 0x000F
  56. #define ADM1272_VOLT_DEFAULT 12000
  57. #define ADM1272_IOUT_DEFAULT 25000
  58. #define ADM1272_PWR_DEFAULT 300 /* 12V 25A */
  59. #define ADM1272_SHUNT 300 /* micro-ohms */
  60. #define ADM1272_VOLTAGE_COEFF_DEFAULT 1
  61. #define ADM1272_CURRENT_COEFF_DEFAULT 3
  62. #define ADM1272_PWR_COEFF_DEFAULT 7
  63. #define ADM1272_IOUT_OFFSET 0x5000
  64. #define ADM1272_IOUT_OFFSET 0x5000
  65. typedef struct ADM1272State {
  66. PMBusDevice parent;
  67. uint64_t ein_ext;
  68. uint32_t pin_ext;
  69. uint8_t restart_time;
  70. uint16_t peak_vin;
  71. uint16_t peak_vout;
  72. uint16_t peak_iout;
  73. uint16_t peak_temperature;
  74. uint16_t peak_pin;
  75. uint8_t pmon_control;
  76. uint16_t pmon_config;
  77. uint16_t alert1_config;
  78. uint16_t alert2_config;
  79. uint16_t device_config;
  80. uint16_t hysteresis_low;
  81. uint16_t hysteresis_high;
  82. uint8_t status_hysteresis;
  83. uint8_t status_gpio;
  84. uint16_t strt_up_iout_lim;
  85. } ADM1272State;
  86. static const PMBusCoefficients adm1272_coefficients[] = {
  87. [0] = { 6770, 0, -2 }, /* voltage, vrange 60V */
  88. [1] = { 4062, 0, -2 }, /* voltage, vrange 100V */
  89. [2] = { 1326, 20480, -1 }, /* current, vsense range 15mV */
  90. [3] = { 663, 20480, -1 }, /* current, vsense range 30mV */
  91. [4] = { 3512, 0, -2 }, /* power, vrange 60V, irange 15mV */
  92. [5] = { 21071, 0, -3 }, /* power, vrange 100V, irange 15mV */
  93. [6] = { 17561, 0, -3 }, /* power, vrange 60V, irange 30mV */
  94. [7] = { 10535, 0, -3 }, /* power, vrange 100V, irange 30mV */
  95. [8] = { 42, 31871, -1 }, /* temperature */
  96. };
  97. static void adm1272_check_limits(ADM1272State *s)
  98. {
  99. PMBusDevice *pmdev = PMBUS_DEVICE(s);
  100. pmbus_check_limits(pmdev);
  101. if (pmdev->pages[0].read_vout > s->peak_vout) {
  102. s->peak_vout = pmdev->pages[0].read_vout;
  103. }
  104. if (pmdev->pages[0].read_vin > s->peak_vin) {
  105. s->peak_vin = pmdev->pages[0].read_vin;
  106. }
  107. if (pmdev->pages[0].read_iout > s->peak_iout) {
  108. s->peak_iout = pmdev->pages[0].read_iout;
  109. }
  110. if (pmdev->pages[0].read_temperature_1 > s->peak_temperature) {
  111. s->peak_temperature = pmdev->pages[0].read_temperature_1;
  112. }
  113. if (pmdev->pages[0].read_pin > s->peak_pin) {
  114. s->peak_pin = pmdev->pages[0].read_pin;
  115. }
  116. }
  117. static uint16_t adm1272_millivolts_to_direct(uint32_t value)
  118. {
  119. PMBusCoefficients c = adm1272_coefficients[ADM1272_VOLTAGE_COEFF_DEFAULT];
  120. c.b = c.b * 1000;
  121. c.R = c.R - 3;
  122. return pmbus_data2direct_mode(c, value);
  123. }
  124. static uint32_t adm1272_direct_to_millivolts(uint16_t value)
  125. {
  126. PMBusCoefficients c = adm1272_coefficients[ADM1272_VOLTAGE_COEFF_DEFAULT];
  127. c.b = c.b * 1000;
  128. c.R = c.R - 3;
  129. return pmbus_direct_mode2data(c, value);
  130. }
  131. static uint16_t adm1272_milliamps_to_direct(uint32_t value)
  132. {
  133. PMBusCoefficients c = adm1272_coefficients[ADM1272_CURRENT_COEFF_DEFAULT];
  134. /* Y = (m * r_sense * x - b) * 10^R */
  135. c.m = c.m * ADM1272_SHUNT / 1000; /* micro-ohms */
  136. c.b = c.b * 1000;
  137. c.R = c.R - 3;
  138. return pmbus_data2direct_mode(c, value);
  139. }
  140. static uint32_t adm1272_direct_to_milliamps(uint16_t value)
  141. {
  142. PMBusCoefficients c = adm1272_coefficients[ADM1272_CURRENT_COEFF_DEFAULT];
  143. c.m = c.m * ADM1272_SHUNT / 1000;
  144. c.b = c.b * 1000;
  145. c.R = c.R - 3;
  146. return pmbus_direct_mode2data(c, value);
  147. }
  148. static uint16_t adm1272_watts_to_direct(uint32_t value)
  149. {
  150. PMBusCoefficients c = adm1272_coefficients[ADM1272_PWR_COEFF_DEFAULT];
  151. c.m = c.m * ADM1272_SHUNT / 1000;
  152. return pmbus_data2direct_mode(c, value);
  153. }
  154. static uint32_t adm1272_direct_to_watts(uint16_t value)
  155. {
  156. PMBusCoefficients c = adm1272_coefficients[ADM1272_PWR_COEFF_DEFAULT];
  157. c.m = c.m * ADM1272_SHUNT / 1000;
  158. return pmbus_direct_mode2data(c, value);
  159. }
  160. static void adm1272_exit_reset(Object *obj)
  161. {
  162. ADM1272State *s = ADM1272(obj);
  163. PMBusDevice *pmdev = PMBUS_DEVICE(obj);
  164. pmdev->page = 0;
  165. pmdev->pages[0].operation = ADM1272_OPERATION_DEFAULT;
  166. pmdev->capability = ADM1272_CAPABILITY_NO_PEC;
  167. pmdev->pages[0].revision = ADM1272_PMBUS_REVISION_DEFAULT;
  168. pmdev->pages[0].vout_mode = ADM1272_DIRECT_MODE;
  169. pmdev->pages[0].vout_ov_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
  170. pmdev->pages[0].vout_uv_warn_limit = 0;
  171. pmdev->pages[0].iout_oc_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
  172. pmdev->pages[0].ot_fault_limit = ADM1272_HIGH_LIMIT_DEFAULT;
  173. pmdev->pages[0].ot_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
  174. pmdev->pages[0].vin_ov_warn_limit = ADM1272_HIGH_LIMIT_DEFAULT;
  175. pmdev->pages[0].vin_uv_warn_limit = 0;
  176. pmdev->pages[0].pin_op_warn_limit = ADM1272_PIN_OP_DEFAULT;
  177. pmdev->pages[0].status_word = 0;
  178. pmdev->pages[0].status_vout = 0;
  179. pmdev->pages[0].status_iout = 0;
  180. pmdev->pages[0].status_input = 0;
  181. pmdev->pages[0].status_temperature = 0;
  182. pmdev->pages[0].status_mfr_specific = 0;
  183. pmdev->pages[0].read_vin
  184. = adm1272_millivolts_to_direct(ADM1272_VOLT_DEFAULT);
  185. pmdev->pages[0].read_vout
  186. = adm1272_millivolts_to_direct(ADM1272_VOLT_DEFAULT);
  187. pmdev->pages[0].read_iout
  188. = adm1272_milliamps_to_direct(ADM1272_IOUT_DEFAULT);
  189. pmdev->pages[0].read_temperature_1 = 0;
  190. pmdev->pages[0].read_pin = adm1272_watts_to_direct(ADM1272_PWR_DEFAULT);
  191. pmdev->pages[0].revision = ADM1272_PMBUS_REVISION_DEFAULT;
  192. pmdev->pages[0].mfr_id = ADM1272_MFR_ID_DEFAULT;
  193. pmdev->pages[0].mfr_model = ADM1272_MODEL_DEFAULT;
  194. pmdev->pages[0].mfr_revision = ADM1272_MFR_DEFAULT_REVISION;
  195. pmdev->pages[0].mfr_date = ADM1272_DEFAULT_DATE;
  196. s->pin_ext = 0;
  197. s->ein_ext = 0;
  198. s->restart_time = ADM1272_RESTART_TIME_DEFAULT;
  199. s->peak_vin = 0;
  200. s->peak_vout = 0;
  201. s->peak_iout = 0;
  202. s->peak_temperature = 0;
  203. s->peak_pin = 0;
  204. s->pmon_control = ADM1272_PMON_CONTROL_DEFAULT;
  205. s->pmon_config = ADM1272_PMON_CONFIG_DEFAULT;
  206. s->alert1_config = 0;
  207. s->alert2_config = 0;
  208. s->device_config = ADM1272_DEVICE_CONFIG_DEFAULT;
  209. s->hysteresis_low = 0;
  210. s->hysteresis_high = ADM1272_HYSTERESIS_HIGH_DEFAULT;
  211. s->status_hysteresis = 0;
  212. s->status_gpio = 0;
  213. s->strt_up_iout_lim = ADM1272_STRT_UP_IOUT_LIM_DEFAULT;
  214. }
  215. static uint8_t adm1272_read_byte(PMBusDevice *pmdev)
  216. {
  217. ADM1272State *s = ADM1272(pmdev);
  218. switch (pmdev->code) {
  219. case ADM1272_RESTART_TIME:
  220. pmbus_send8(pmdev, s->restart_time);
  221. break;
  222. case ADM1272_MFR_PEAK_IOUT:
  223. pmbus_send16(pmdev, s->peak_iout);
  224. break;
  225. case ADM1272_MFR_PEAK_VIN:
  226. pmbus_send16(pmdev, s->peak_vin);
  227. break;
  228. case ADM1272_MFR_PEAK_VOUT:
  229. pmbus_send16(pmdev, s->peak_vout);
  230. break;
  231. case ADM1272_MFR_PMON_CONTROL:
  232. pmbus_send8(pmdev, s->pmon_control);
  233. break;
  234. case ADM1272_MFR_PMON_CONFIG:
  235. pmbus_send16(pmdev, s->pmon_config);
  236. break;
  237. case ADM1272_MFR_ALERT1_CONFIG:
  238. pmbus_send16(pmdev, s->alert1_config);
  239. break;
  240. case ADM1272_MFR_ALERT2_CONFIG:
  241. pmbus_send16(pmdev, s->alert2_config);
  242. break;
  243. case ADM1272_MFR_PEAK_TEMPERATURE:
  244. pmbus_send16(pmdev, s->peak_temperature);
  245. break;
  246. case ADM1272_MFR_DEVICE_CONFIG:
  247. pmbus_send16(pmdev, s->device_config);
  248. break;
  249. case ADM1272_MFR_PEAK_PIN:
  250. pmbus_send16(pmdev, s->peak_pin);
  251. break;
  252. case ADM1272_MFR_READ_PIN_EXT:
  253. pmbus_send32(pmdev, s->pin_ext);
  254. break;
  255. case ADM1272_MFR_READ_EIN_EXT:
  256. pmbus_send64(pmdev, s->ein_ext);
  257. break;
  258. case ADM1272_HYSTERESIS_LOW:
  259. pmbus_send16(pmdev, s->hysteresis_low);
  260. break;
  261. case ADM1272_HYSTERESIS_HIGH:
  262. pmbus_send16(pmdev, s->hysteresis_high);
  263. break;
  264. case ADM1272_STATUS_HYSTERESIS:
  265. pmbus_send16(pmdev, s->status_hysteresis);
  266. break;
  267. case ADM1272_STATUS_GPIO:
  268. pmbus_send16(pmdev, s->status_gpio);
  269. break;
  270. case ADM1272_STRT_UP_IOUT_LIM:
  271. pmbus_send16(pmdev, s->strt_up_iout_lim);
  272. break;
  273. default:
  274. qemu_log_mask(LOG_GUEST_ERROR,
  275. "%s: reading from unsupported register: 0x%02x\n",
  276. __func__, pmdev->code);
  277. return 0xFF;
  278. break;
  279. }
  280. return 0;
  281. }
  282. static int adm1272_write_data(PMBusDevice *pmdev, const uint8_t *buf,
  283. uint8_t len)
  284. {
  285. ADM1272State *s = ADM1272(pmdev);
  286. if (len == 0) {
  287. qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__);
  288. return -1;
  289. }
  290. pmdev->code = buf[0]; /* PMBus command code */
  291. if (len == 1) {
  292. return 0;
  293. }
  294. /* Exclude command code from buffer */
  295. buf++;
  296. len--;
  297. switch (pmdev->code) {
  298. case ADM1272_RESTART_TIME:
  299. s->restart_time = pmbus_receive8(pmdev);
  300. break;
  301. case ADM1272_MFR_PMON_CONTROL:
  302. s->pmon_control = pmbus_receive8(pmdev);
  303. break;
  304. case ADM1272_MFR_PMON_CONFIG:
  305. s->pmon_config = pmbus_receive16(pmdev);
  306. break;
  307. case ADM1272_MFR_ALERT1_CONFIG:
  308. s->alert1_config = pmbus_receive16(pmdev);
  309. break;
  310. case ADM1272_MFR_ALERT2_CONFIG:
  311. s->alert2_config = pmbus_receive16(pmdev);
  312. break;
  313. case ADM1272_MFR_DEVICE_CONFIG:
  314. s->device_config = pmbus_receive16(pmdev);
  315. break;
  316. case ADM1272_MFR_POWER_CYCLE:
  317. adm1272_exit_reset((Object *)s);
  318. break;
  319. case ADM1272_HYSTERESIS_LOW:
  320. s->hysteresis_low = pmbus_receive16(pmdev);
  321. break;
  322. case ADM1272_HYSTERESIS_HIGH:
  323. s->hysteresis_high = pmbus_receive16(pmdev);
  324. break;
  325. case ADM1272_STRT_UP_IOUT_LIM:
  326. s->strt_up_iout_lim = pmbus_receive16(pmdev);
  327. adm1272_check_limits(s);
  328. break;
  329. default:
  330. qemu_log_mask(LOG_GUEST_ERROR,
  331. "%s: writing to unsupported register: 0x%02x\n",
  332. __func__, pmdev->code);
  333. break;
  334. }
  335. return 0;
  336. }
  337. static void adm1272_get(Object *obj, Visitor *v, const char *name, void *opaque,
  338. Error **errp)
  339. {
  340. uint16_t value;
  341. if (strcmp(name, "vin") == 0 || strcmp(name, "vout") == 0) {
  342. value = adm1272_direct_to_millivolts(*(uint16_t *)opaque);
  343. } else if (strcmp(name, "iout") == 0) {
  344. value = adm1272_direct_to_milliamps(*(uint16_t *)opaque);
  345. } else if (strcmp(name, "pin") == 0) {
  346. value = adm1272_direct_to_watts(*(uint16_t *)opaque);
  347. } else {
  348. value = *(uint16_t *)opaque;
  349. }
  350. visit_type_uint16(v, name, &value, errp);
  351. }
  352. static void adm1272_set(Object *obj, Visitor *v, const char *name, void *opaque,
  353. Error **errp)
  354. {
  355. ADM1272State *s = ADM1272(obj);
  356. uint16_t *internal = opaque;
  357. uint16_t value;
  358. if (!visit_type_uint16(v, name, &value, errp)) {
  359. return;
  360. }
  361. if (strcmp(name, "vin") == 0 || strcmp(name, "vout") == 0) {
  362. *internal = adm1272_millivolts_to_direct(value);
  363. } else if (strcmp(name, "iout") == 0) {
  364. *internal = adm1272_milliamps_to_direct(value);
  365. } else if (strcmp(name, "pin") == 0) {
  366. *internal = adm1272_watts_to_direct(value);
  367. } else {
  368. *internal = value;
  369. }
  370. adm1272_check_limits(s);
  371. }
  372. static const VMStateDescription vmstate_adm1272 = {
  373. .name = "ADM1272",
  374. .version_id = 0,
  375. .minimum_version_id = 0,
  376. .fields = (VMStateField[]){
  377. VMSTATE_PMBUS_DEVICE(parent, ADM1272State),
  378. VMSTATE_UINT64(ein_ext, ADM1272State),
  379. VMSTATE_UINT32(pin_ext, ADM1272State),
  380. VMSTATE_UINT8(restart_time, ADM1272State),
  381. VMSTATE_UINT16(peak_vin, ADM1272State),
  382. VMSTATE_UINT16(peak_vout, ADM1272State),
  383. VMSTATE_UINT16(peak_iout, ADM1272State),
  384. VMSTATE_UINT16(peak_temperature, ADM1272State),
  385. VMSTATE_UINT16(peak_pin, ADM1272State),
  386. VMSTATE_UINT8(pmon_control, ADM1272State),
  387. VMSTATE_UINT16(pmon_config, ADM1272State),
  388. VMSTATE_UINT16(alert1_config, ADM1272State),
  389. VMSTATE_UINT16(alert2_config, ADM1272State),
  390. VMSTATE_UINT16(device_config, ADM1272State),
  391. VMSTATE_UINT16(hysteresis_low, ADM1272State),
  392. VMSTATE_UINT16(hysteresis_high, ADM1272State),
  393. VMSTATE_UINT8(status_hysteresis, ADM1272State),
  394. VMSTATE_UINT8(status_gpio, ADM1272State),
  395. VMSTATE_UINT16(strt_up_iout_lim, ADM1272State),
  396. VMSTATE_END_OF_LIST()
  397. }
  398. };
  399. static void adm1272_init(Object *obj)
  400. {
  401. PMBusDevice *pmdev = PMBUS_DEVICE(obj);
  402. uint64_t flags = PB_HAS_VOUT_MODE | PB_HAS_VOUT | PB_HAS_VIN | PB_HAS_IOUT |
  403. PB_HAS_PIN | PB_HAS_TEMPERATURE | PB_HAS_MFR_INFO;
  404. pmbus_page_config(pmdev, 0, flags);
  405. object_property_add(obj, "vin", "uint16",
  406. adm1272_get,
  407. adm1272_set, NULL, &pmdev->pages[0].read_vin);
  408. object_property_add(obj, "vout", "uint16",
  409. adm1272_get,
  410. adm1272_set, NULL, &pmdev->pages[0].read_vout);
  411. object_property_add(obj, "iout", "uint16",
  412. adm1272_get,
  413. adm1272_set, NULL, &pmdev->pages[0].read_iout);
  414. object_property_add(obj, "pin", "uint16",
  415. adm1272_get,
  416. adm1272_set, NULL, &pmdev->pages[0].read_pin);
  417. }
  418. static void adm1272_class_init(ObjectClass *klass, void *data)
  419. {
  420. ResettableClass *rc = RESETTABLE_CLASS(klass);
  421. DeviceClass *dc = DEVICE_CLASS(klass);
  422. PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
  423. dc->desc = "Analog Devices ADM1272 Hot Swap controller";
  424. dc->vmsd = &vmstate_adm1272;
  425. k->write_data = adm1272_write_data;
  426. k->receive_byte = adm1272_read_byte;
  427. k->device_num_pages = 1;
  428. rc->phases.exit = adm1272_exit_reset;
  429. }
  430. static const TypeInfo adm1272_info = {
  431. .name = TYPE_ADM1272,
  432. .parent = TYPE_PMBUS_DEVICE,
  433. .instance_size = sizeof(ADM1272State),
  434. .instance_init = adm1272_init,
  435. .class_init = adm1272_class_init,
  436. };
  437. static void adm1272_register_types(void)
  438. {
  439. type_register_static(&adm1272_info);
  440. }
  441. type_init(adm1272_register_types)