max6621.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /*
  2. * Hardware monitoring driver for Maxim MAX6621
  3. *
  4. * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
  5. * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  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. #include <linux/bitops.h>
  18. #include <linux/hwmon.h>
  19. #include <linux/hwmon-sysfs.h>
  20. #include <linux/i2c.h>
  21. #include <linux/init.h>
  22. #include <linux/module.h>
  23. #include <linux/of_device.h>
  24. #include <linux/regmap.h>
  25. #define MAX6621_DRV_NAME "max6621"
  26. #define MAX6621_TEMP_INPUT_REG_NUM 9
  27. #define MAX6621_TEMP_INPUT_MIN -127000
  28. #define MAX6621_TEMP_INPUT_MAX 128000
  29. #define MAX6621_TEMP_ALERT_CHAN_SHIFT 1
  30. #define MAX6621_TEMP_S0D0_REG 0x00
  31. #define MAX6621_TEMP_S0D1_REG 0x01
  32. #define MAX6621_TEMP_S1D0_REG 0x02
  33. #define MAX6621_TEMP_S1D1_REG 0x03
  34. #define MAX6621_TEMP_S2D0_REG 0x04
  35. #define MAX6621_TEMP_S2D1_REG 0x05
  36. #define MAX6621_TEMP_S3D0_REG 0x06
  37. #define MAX6621_TEMP_S3D1_REG 0x07
  38. #define MAX6621_TEMP_MAX_REG 0x08
  39. #define MAX6621_TEMP_MAX_ADDR_REG 0x0a
  40. #define MAX6621_TEMP_ALERT_CAUSE_REG 0x0b
  41. #define MAX6621_CONFIG0_REG 0x0c
  42. #define MAX6621_CONFIG1_REG 0x0d
  43. #define MAX6621_CONFIG2_REG 0x0e
  44. #define MAX6621_CONFIG3_REG 0x0f
  45. #define MAX6621_TEMP_S0_ALERT_REG 0x10
  46. #define MAX6621_TEMP_S1_ALERT_REG 0x11
  47. #define MAX6621_TEMP_S2_ALERT_REG 0x12
  48. #define MAX6621_TEMP_S3_ALERT_REG 0x13
  49. #define MAX6621_CLEAR_ALERT_REG 0x15
  50. #define MAX6621_REG_MAX (MAX6621_CLEAR_ALERT_REG + 1)
  51. #define MAX6621_REG_TEMP_SHIFT 0x06
  52. #define MAX6621_ENABLE_TEMP_ALERTS_BIT 4
  53. #define MAX6621_ENABLE_I2C_CRC_BIT 5
  54. #define MAX6621_ENABLE_ALTERNATE_DATA 6
  55. #define MAX6621_ENABLE_LOCKUP_TO 7
  56. #define MAX6621_ENABLE_S0D0_BIT 8
  57. #define MAX6621_ENABLE_S3D1_BIT 15
  58. #define MAX6621_ENABLE_TEMP_ALL GENMASK(MAX6621_ENABLE_S3D1_BIT, \
  59. MAX6621_ENABLE_S0D0_BIT)
  60. #define MAX6621_POLL_DELAY_MASK 0x5
  61. #define MAX6621_CONFIG0_INIT (MAX6621_ENABLE_TEMP_ALL | \
  62. BIT(MAX6621_ENABLE_LOCKUP_TO) | \
  63. BIT(MAX6621_ENABLE_I2C_CRC_BIT) | \
  64. MAX6621_POLL_DELAY_MASK)
  65. #define MAX6621_PECI_BIT_TIME 0x2
  66. #define MAX6621_PECI_RETRY_NUM 0x3
  67. #define MAX6621_CONFIG1_INIT ((MAX6621_PECI_BIT_TIME << 8) | \
  68. MAX6621_PECI_RETRY_NUM)
  69. /* Error codes */
  70. #define MAX6621_TRAN_FAILED 0x8100 /*
  71. * PECI transaction failed for more
  72. * than the configured number of
  73. * consecutive retries.
  74. */
  75. #define MAX6621_POOL_DIS 0x8101 /*
  76. * Polling disabled for requested
  77. * socket/domain.
  78. */
  79. #define MAX6621_POOL_UNCOMPLETE 0x8102 /*
  80. * First poll not yet completed for
  81. * requested socket/domain (on
  82. * startup).
  83. */
  84. #define MAX6621_SD_DIS 0x8103 /*
  85. * Read maximum temperature requested,
  86. * but no sockets/domains enabled or
  87. * all enabled sockets/domains have
  88. * errors; or read maximum temperature
  89. * address requested, but read maximum
  90. * temperature was not called.
  91. */
  92. #define MAX6621_ALERT_DIS 0x8104 /*
  93. * Get alert socket/domain requested,
  94. * but no alert active.
  95. */
  96. #define MAX6621_PECI_ERR_MIN 0x8000 /* Intel spec PECI error min value. */
  97. #define MAX6621_PECI_ERR_MAX 0x80ff /* Intel spec PECI error max value. */
  98. static const u32 max6621_temp_regs[] = {
  99. MAX6621_TEMP_MAX_REG, MAX6621_TEMP_S0D0_REG, MAX6621_TEMP_S1D0_REG,
  100. MAX6621_TEMP_S2D0_REG, MAX6621_TEMP_S3D0_REG, MAX6621_TEMP_S0D1_REG,
  101. MAX6621_TEMP_S1D1_REG, MAX6621_TEMP_S2D1_REG, MAX6621_TEMP_S3D1_REG,
  102. };
  103. static const char *const max6621_temp_labels[] = {
  104. "maximum",
  105. "socket0_0",
  106. "socket1_0",
  107. "socket2_0",
  108. "socket3_0",
  109. "socket0_1",
  110. "socket1_1",
  111. "socket2_1",
  112. "socket3_1",
  113. };
  114. static const int max6621_temp_alert_chan2reg[] = {
  115. MAX6621_TEMP_S0_ALERT_REG,
  116. MAX6621_TEMP_S1_ALERT_REG,
  117. MAX6621_TEMP_S2_ALERT_REG,
  118. MAX6621_TEMP_S3_ALERT_REG,
  119. };
  120. /**
  121. * struct max6621_data - private data:
  122. *
  123. * @client: I2C client;
  124. * @regmap: register map handle;
  125. * @input_chan2reg: mapping from channel to register;
  126. */
  127. struct max6621_data {
  128. struct i2c_client *client;
  129. struct regmap *regmap;
  130. int input_chan2reg[MAX6621_TEMP_INPUT_REG_NUM + 1];
  131. };
  132. static long max6621_temp_mc2reg(long val)
  133. {
  134. return (val / 1000L) << MAX6621_REG_TEMP_SHIFT;
  135. }
  136. static umode_t
  137. max6621_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
  138. int channel)
  139. {
  140. /* Skip channels which are not physically conncted. */
  141. if (((struct max6621_data *)data)->input_chan2reg[channel] < 0)
  142. return 0;
  143. switch (type) {
  144. case hwmon_temp:
  145. switch (attr) {
  146. case hwmon_temp_input:
  147. case hwmon_temp_label:
  148. case hwmon_temp_crit_alarm:
  149. return 0444;
  150. case hwmon_temp_offset:
  151. case hwmon_temp_crit:
  152. return 0644;
  153. default:
  154. break;
  155. }
  156. default:
  157. break;
  158. }
  159. return 0;
  160. }
  161. static int max6621_verify_reg_data(struct device *dev, int regval)
  162. {
  163. if (regval >= MAX6621_PECI_ERR_MIN &&
  164. regval <= MAX6621_PECI_ERR_MAX) {
  165. dev_dbg(dev, "PECI error code - err 0x%04x.\n",
  166. regval);
  167. return -EIO;
  168. }
  169. switch (regval) {
  170. case MAX6621_TRAN_FAILED:
  171. dev_dbg(dev, "PECI transaction failed - err 0x%04x.\n",
  172. regval);
  173. return -EIO;
  174. case MAX6621_POOL_DIS:
  175. dev_dbg(dev, "Polling disabled - err 0x%04x.\n", regval);
  176. return -EOPNOTSUPP;
  177. case MAX6621_POOL_UNCOMPLETE:
  178. dev_dbg(dev, "First poll not completed on startup - err 0x%04x.\n",
  179. regval);
  180. return -EIO;
  181. case MAX6621_SD_DIS:
  182. dev_dbg(dev, "Resource is disabled - err 0x%04x.\n", regval);
  183. return -EOPNOTSUPP;
  184. case MAX6621_ALERT_DIS:
  185. dev_dbg(dev, "No alert active - err 0x%04x.\n", regval);
  186. return -EOPNOTSUPP;
  187. default:
  188. return 0;
  189. }
  190. }
  191. static int
  192. max6621_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  193. int channel, long *val)
  194. {
  195. struct max6621_data *data = dev_get_drvdata(dev);
  196. u32 regval;
  197. int reg;
  198. s8 temp;
  199. int ret;
  200. switch (type) {
  201. case hwmon_temp:
  202. switch (attr) {
  203. case hwmon_temp_input:
  204. reg = data->input_chan2reg[channel];
  205. ret = regmap_read(data->regmap, reg, &regval);
  206. if (ret)
  207. return ret;
  208. ret = max6621_verify_reg_data(dev, regval);
  209. if (ret)
  210. return ret;
  211. /*
  212. * Bit MAX6621_REG_TEMP_SHIFT represents 1 degree step.
  213. * The temperature is given in two's complement and 8
  214. * bits is used for the register conversion.
  215. */
  216. temp = (regval >> MAX6621_REG_TEMP_SHIFT);
  217. *val = temp * 1000L;
  218. break;
  219. case hwmon_temp_offset:
  220. ret = regmap_read(data->regmap, MAX6621_CONFIG2_REG,
  221. &regval);
  222. if (ret)
  223. return ret;
  224. ret = max6621_verify_reg_data(dev, regval);
  225. if (ret)
  226. return ret;
  227. *val = (regval >> MAX6621_REG_TEMP_SHIFT) *
  228. 1000L;
  229. break;
  230. case hwmon_temp_crit:
  231. channel -= MAX6621_TEMP_ALERT_CHAN_SHIFT;
  232. reg = max6621_temp_alert_chan2reg[channel];
  233. ret = regmap_read(data->regmap, reg, &regval);
  234. if (ret)
  235. return ret;
  236. ret = max6621_verify_reg_data(dev, regval);
  237. if (ret)
  238. return ret;
  239. *val = regval * 1000L;
  240. break;
  241. case hwmon_temp_crit_alarm:
  242. /*
  243. * Set val to zero to recover the case, when reading
  244. * MAX6621_TEMP_ALERT_CAUSE_REG results in for example
  245. * MAX6621_ALERT_DIS. Reading will return with error,
  246. * but in such case alarm should be returned as 0.
  247. */
  248. *val = 0;
  249. ret = regmap_read(data->regmap,
  250. MAX6621_TEMP_ALERT_CAUSE_REG,
  251. &regval);
  252. if (ret)
  253. return ret;
  254. ret = max6621_verify_reg_data(dev, regval);
  255. if (ret) {
  256. /* Do not report error if alert is disabled. */
  257. if (regval == MAX6621_ALERT_DIS)
  258. return 0;
  259. else
  260. return ret;
  261. }
  262. /*
  263. * Clear the alert automatically, using send-byte
  264. * smbus protocol for clearing alert.
  265. */
  266. if (regval) {
  267. ret = i2c_smbus_write_byte(data->client,
  268. MAX6621_CLEAR_ALERT_REG);
  269. if (ret)
  270. return ret;
  271. }
  272. *val = !!regval;
  273. break;
  274. default:
  275. return -EOPNOTSUPP;
  276. }
  277. break;
  278. default:
  279. return -EOPNOTSUPP;
  280. }
  281. return 0;
  282. }
  283. static int
  284. max6621_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  285. int channel, long val)
  286. {
  287. struct max6621_data *data = dev_get_drvdata(dev);
  288. u32 reg;
  289. switch (type) {
  290. case hwmon_temp:
  291. switch (attr) {
  292. case hwmon_temp_offset:
  293. /* Clamp to allowed range to prevent overflow. */
  294. val = clamp_val(val, MAX6621_TEMP_INPUT_MIN,
  295. MAX6621_TEMP_INPUT_MAX);
  296. val = max6621_temp_mc2reg(val);
  297. return regmap_write(data->regmap,
  298. MAX6621_CONFIG2_REG, val);
  299. case hwmon_temp_crit:
  300. channel -= MAX6621_TEMP_ALERT_CHAN_SHIFT;
  301. reg = max6621_temp_alert_chan2reg[channel];
  302. /* Clamp to allowed range to prevent overflow. */
  303. val = clamp_val(val, MAX6621_TEMP_INPUT_MIN,
  304. MAX6621_TEMP_INPUT_MAX);
  305. val = val / 1000L;
  306. return regmap_write(data->regmap, reg, val);
  307. default:
  308. return -EOPNOTSUPP;
  309. }
  310. break;
  311. default:
  312. return -EOPNOTSUPP;
  313. }
  314. return -EOPNOTSUPP;
  315. }
  316. static int
  317. max6621_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  318. int channel, const char **str)
  319. {
  320. switch (type) {
  321. case hwmon_temp:
  322. switch (attr) {
  323. case hwmon_temp_label:
  324. *str = max6621_temp_labels[channel];
  325. return 0;
  326. default:
  327. return -EOPNOTSUPP;
  328. }
  329. break;
  330. default:
  331. return -EOPNOTSUPP;
  332. }
  333. return -EOPNOTSUPP;
  334. }
  335. static bool max6621_writeable_reg(struct device *dev, unsigned int reg)
  336. {
  337. switch (reg) {
  338. case MAX6621_CONFIG0_REG:
  339. case MAX6621_CONFIG1_REG:
  340. case MAX6621_CONFIG2_REG:
  341. case MAX6621_CONFIG3_REG:
  342. case MAX6621_TEMP_S0_ALERT_REG:
  343. case MAX6621_TEMP_S1_ALERT_REG:
  344. case MAX6621_TEMP_S2_ALERT_REG:
  345. case MAX6621_TEMP_S3_ALERT_REG:
  346. case MAX6621_TEMP_ALERT_CAUSE_REG:
  347. return true;
  348. }
  349. return false;
  350. }
  351. static bool max6621_readable_reg(struct device *dev, unsigned int reg)
  352. {
  353. switch (reg) {
  354. case MAX6621_TEMP_S0D0_REG:
  355. case MAX6621_TEMP_S0D1_REG:
  356. case MAX6621_TEMP_S1D0_REG:
  357. case MAX6621_TEMP_S1D1_REG:
  358. case MAX6621_TEMP_S2D0_REG:
  359. case MAX6621_TEMP_S2D1_REG:
  360. case MAX6621_TEMP_S3D0_REG:
  361. case MAX6621_TEMP_S3D1_REG:
  362. case MAX6621_TEMP_MAX_REG:
  363. case MAX6621_TEMP_MAX_ADDR_REG:
  364. case MAX6621_CONFIG0_REG:
  365. case MAX6621_CONFIG1_REG:
  366. case MAX6621_CONFIG2_REG:
  367. case MAX6621_CONFIG3_REG:
  368. case MAX6621_TEMP_S0_ALERT_REG:
  369. case MAX6621_TEMP_S1_ALERT_REG:
  370. case MAX6621_TEMP_S2_ALERT_REG:
  371. case MAX6621_TEMP_S3_ALERT_REG:
  372. return true;
  373. }
  374. return false;
  375. }
  376. static bool max6621_volatile_reg(struct device *dev, unsigned int reg)
  377. {
  378. switch (reg) {
  379. case MAX6621_TEMP_S0D0_REG:
  380. case MAX6621_TEMP_S0D1_REG:
  381. case MAX6621_TEMP_S1D0_REG:
  382. case MAX6621_TEMP_S1D1_REG:
  383. case MAX6621_TEMP_S2D0_REG:
  384. case MAX6621_TEMP_S2D1_REG:
  385. case MAX6621_TEMP_S3D0_REG:
  386. case MAX6621_TEMP_S3D1_REG:
  387. case MAX6621_TEMP_MAX_REG:
  388. case MAX6621_TEMP_S0_ALERT_REG:
  389. case MAX6621_TEMP_S1_ALERT_REG:
  390. case MAX6621_TEMP_S2_ALERT_REG:
  391. case MAX6621_TEMP_S3_ALERT_REG:
  392. case MAX6621_TEMP_ALERT_CAUSE_REG:
  393. return true;
  394. }
  395. return false;
  396. }
  397. static const struct reg_default max6621_regmap_default[] = {
  398. { MAX6621_CONFIG0_REG, MAX6621_CONFIG0_INIT },
  399. { MAX6621_CONFIG1_REG, MAX6621_CONFIG1_INIT },
  400. };
  401. static const struct regmap_config max6621_regmap_config = {
  402. .reg_bits = 8,
  403. .val_bits = 16,
  404. .max_register = MAX6621_REG_MAX,
  405. .val_format_endian = REGMAP_ENDIAN_LITTLE,
  406. .cache_type = REGCACHE_FLAT,
  407. .writeable_reg = max6621_writeable_reg,
  408. .readable_reg = max6621_readable_reg,
  409. .volatile_reg = max6621_volatile_reg,
  410. .reg_defaults = max6621_regmap_default,
  411. .num_reg_defaults = ARRAY_SIZE(max6621_regmap_default),
  412. };
  413. static u32 max6621_chip_config[] = {
  414. HWMON_C_REGISTER_TZ,
  415. 0
  416. };
  417. static const struct hwmon_channel_info max6621_chip = {
  418. .type = hwmon_chip,
  419. .config = max6621_chip_config,
  420. };
  421. static const u32 max6621_temp_config[] = {
  422. HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
  423. HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
  424. HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
  425. HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
  426. HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
  427. HWMON_T_INPUT | HWMON_T_LABEL,
  428. HWMON_T_INPUT | HWMON_T_LABEL,
  429. HWMON_T_INPUT | HWMON_T_LABEL,
  430. HWMON_T_INPUT | HWMON_T_LABEL,
  431. 0
  432. };
  433. static const struct hwmon_channel_info max6621_temp = {
  434. .type = hwmon_temp,
  435. .config = max6621_temp_config,
  436. };
  437. static const struct hwmon_channel_info *max6621_info[] = {
  438. &max6621_chip,
  439. &max6621_temp,
  440. NULL
  441. };
  442. static const struct hwmon_ops max6621_hwmon_ops = {
  443. .read = max6621_read,
  444. .write = max6621_write,
  445. .read_string = max6621_read_string,
  446. .is_visible = max6621_is_visible,
  447. };
  448. static const struct hwmon_chip_info max6621_chip_info = {
  449. .ops = &max6621_hwmon_ops,
  450. .info = max6621_info,
  451. };
  452. static int max6621_probe(struct i2c_client *client,
  453. const struct i2c_device_id *id)
  454. {
  455. struct device *dev = &client->dev;
  456. struct max6621_data *data;
  457. struct device *hwmon_dev;
  458. int i;
  459. int ret;
  460. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  461. if (!data)
  462. return -ENOMEM;
  463. data->regmap = devm_regmap_init_i2c(client, &max6621_regmap_config);
  464. if (IS_ERR(data->regmap))
  465. return PTR_ERR(data->regmap);
  466. i2c_set_clientdata(client, data);
  467. data->client = client;
  468. /* Set CONFIG0 register masking temperature alerts and PEC. */
  469. ret = regmap_write(data->regmap, MAX6621_CONFIG0_REG,
  470. MAX6621_CONFIG0_INIT);
  471. if (ret)
  472. return ret;
  473. /* Set CONFIG1 register for PEC access retry number. */
  474. ret = regmap_write(data->regmap, MAX6621_CONFIG1_REG,
  475. MAX6621_CONFIG1_INIT);
  476. if (ret)
  477. return ret;
  478. /* Sync registers with hardware. */
  479. regcache_mark_dirty(data->regmap);
  480. ret = regcache_sync(data->regmap);
  481. if (ret)
  482. return ret;
  483. /* Verify which temperature input registers are enabled. */
  484. for (i = 0; i < MAX6621_TEMP_INPUT_REG_NUM; i++) {
  485. ret = i2c_smbus_read_word_data(client, max6621_temp_regs[i]);
  486. if (ret < 0)
  487. return ret;
  488. ret = max6621_verify_reg_data(dev, ret);
  489. if (ret) {
  490. data->input_chan2reg[i] = -1;
  491. continue;
  492. }
  493. data->input_chan2reg[i] = max6621_temp_regs[i];
  494. }
  495. hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
  496. data,
  497. &max6621_chip_info,
  498. NULL);
  499. return PTR_ERR_OR_ZERO(hwmon_dev);
  500. }
  501. static const struct i2c_device_id max6621_id[] = {
  502. { MAX6621_DRV_NAME, 0 },
  503. { }
  504. };
  505. MODULE_DEVICE_TABLE(i2c, max6621_id);
  506. static const struct of_device_id max6621_of_match[] = {
  507. { .compatible = "maxim,max6621" },
  508. { }
  509. };
  510. MODULE_DEVICE_TABLE(of, max6621_of_match);
  511. static struct i2c_driver max6621_driver = {
  512. .class = I2C_CLASS_HWMON,
  513. .driver = {
  514. .name = MAX6621_DRV_NAME,
  515. .of_match_table = of_match_ptr(max6621_of_match),
  516. },
  517. .probe = max6621_probe,
  518. .id_table = max6621_id,
  519. };
  520. module_i2c_driver(max6621_driver);
  521. MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
  522. MODULE_DESCRIPTION("Driver for Maxim MAX6621");
  523. MODULE_LICENSE("GPL");