lm25066.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066
  3. *
  4. * Copyright (c) 2011 Ericsson AB.
  5. * Copyright (c) 2013 Guenter Roeck
  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. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <linux/bitops.h>
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/init.h>
  25. #include <linux/err.h>
  26. #include <linux/slab.h>
  27. #include <linux/i2c.h>
  28. #include "pmbus.h"
  29. enum chips { lm25056, lm25066, lm5064, lm5066, lm5066i };
  30. #define LM25066_READ_VAUX 0xd0
  31. #define LM25066_MFR_READ_IIN 0xd1
  32. #define LM25066_MFR_READ_PIN 0xd2
  33. #define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3
  34. #define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4
  35. #define LM25066_READ_PIN_PEAK 0xd5
  36. #define LM25066_CLEAR_PIN_PEAK 0xd6
  37. #define LM25066_DEVICE_SETUP 0xd9
  38. #define LM25066_READ_AVG_VIN 0xdc
  39. #define LM25066_READ_AVG_VOUT 0xdd
  40. #define LM25066_READ_AVG_IIN 0xde
  41. #define LM25066_READ_AVG_PIN 0xdf
  42. #define LM25066_DEV_SETUP_CL BIT(4) /* Current limit */
  43. /* LM25056 only */
  44. #define LM25056_VAUX_OV_WARN_LIMIT 0xe3
  45. #define LM25056_VAUX_UV_WARN_LIMIT 0xe4
  46. #define LM25056_MFR_STS_VAUX_OV_WARN BIT(1)
  47. #define LM25056_MFR_STS_VAUX_UV_WARN BIT(0)
  48. struct __coeff {
  49. short m, b, R;
  50. };
  51. #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES)
  52. #define PSC_POWER_L (PSC_NUM_CLASSES + 1)
  53. static struct __coeff lm25066_coeff[6][PSC_NUM_CLASSES + 2] = {
  54. [lm25056] = {
  55. [PSC_VOLTAGE_IN] = {
  56. .m = 16296,
  57. .R = -2,
  58. },
  59. [PSC_CURRENT_IN] = {
  60. .m = 13797,
  61. .R = -2,
  62. },
  63. [PSC_CURRENT_IN_L] = {
  64. .m = 6726,
  65. .R = -2,
  66. },
  67. [PSC_POWER] = {
  68. .m = 5501,
  69. .R = -3,
  70. },
  71. [PSC_POWER_L] = {
  72. .m = 26882,
  73. .R = -4,
  74. },
  75. [PSC_TEMPERATURE] = {
  76. .m = 1580,
  77. .b = -14500,
  78. .R = -2,
  79. },
  80. },
  81. [lm25066] = {
  82. [PSC_VOLTAGE_IN] = {
  83. .m = 22070,
  84. .R = -2,
  85. },
  86. [PSC_VOLTAGE_OUT] = {
  87. .m = 22070,
  88. .R = -2,
  89. },
  90. [PSC_CURRENT_IN] = {
  91. .m = 13661,
  92. .R = -2,
  93. },
  94. [PSC_CURRENT_IN_L] = {
  95. .m = 6852,
  96. .R = -2,
  97. },
  98. [PSC_POWER] = {
  99. .m = 736,
  100. .R = -2,
  101. },
  102. [PSC_POWER_L] = {
  103. .m = 369,
  104. .R = -2,
  105. },
  106. [PSC_TEMPERATURE] = {
  107. .m = 16,
  108. },
  109. },
  110. [lm5064] = {
  111. [PSC_VOLTAGE_IN] = {
  112. .m = 4611,
  113. .R = -2,
  114. },
  115. [PSC_VOLTAGE_OUT] = {
  116. .m = 4621,
  117. .R = -2,
  118. },
  119. [PSC_CURRENT_IN] = {
  120. .m = 10742,
  121. .R = -2,
  122. },
  123. [PSC_CURRENT_IN_L] = {
  124. .m = 5456,
  125. .R = -2,
  126. },
  127. [PSC_POWER] = {
  128. .m = 1204,
  129. .R = -3,
  130. },
  131. [PSC_POWER_L] = {
  132. .m = 612,
  133. .R = -3,
  134. },
  135. [PSC_TEMPERATURE] = {
  136. .m = 16,
  137. },
  138. },
  139. [lm5066] = {
  140. [PSC_VOLTAGE_IN] = {
  141. .m = 4587,
  142. .R = -2,
  143. },
  144. [PSC_VOLTAGE_OUT] = {
  145. .m = 4587,
  146. .R = -2,
  147. },
  148. [PSC_CURRENT_IN] = {
  149. .m = 10753,
  150. .R = -2,
  151. },
  152. [PSC_CURRENT_IN_L] = {
  153. .m = 5405,
  154. .R = -2,
  155. },
  156. [PSC_POWER] = {
  157. .m = 1204,
  158. .R = -3,
  159. },
  160. [PSC_POWER_L] = {
  161. .m = 605,
  162. .R = -3,
  163. },
  164. [PSC_TEMPERATURE] = {
  165. .m = 16,
  166. },
  167. },
  168. [lm5066i] = {
  169. [PSC_VOLTAGE_IN] = {
  170. .m = 4617,
  171. .b = -140,
  172. .R = -2,
  173. },
  174. [PSC_VOLTAGE_OUT] = {
  175. .m = 4602,
  176. .b = 500,
  177. .R = -2,
  178. },
  179. [PSC_CURRENT_IN] = {
  180. .m = 15076,
  181. .b = -504,
  182. .R = -2,
  183. },
  184. [PSC_CURRENT_IN_L] = {
  185. .m = 7645,
  186. .b = 100,
  187. .R = -2,
  188. },
  189. [PSC_POWER] = {
  190. .m = 1701,
  191. .b = -4000,
  192. .R = -3,
  193. },
  194. [PSC_POWER_L] = {
  195. .m = 861,
  196. .b = -965,
  197. .R = -3,
  198. },
  199. [PSC_TEMPERATURE] = {
  200. .m = 16,
  201. },
  202. },
  203. };
  204. struct lm25066_data {
  205. int id;
  206. u16 rlimit; /* Maximum register value */
  207. struct pmbus_driver_info info;
  208. };
  209. #define to_lm25066_data(x) container_of(x, struct lm25066_data, info)
  210. static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
  211. {
  212. const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
  213. const struct lm25066_data *data = to_lm25066_data(info);
  214. int ret;
  215. switch (reg) {
  216. case PMBUS_VIRT_READ_VMON:
  217. ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX);
  218. if (ret < 0)
  219. break;
  220. /* Adjust returned value to match VIN coefficients */
  221. switch (data->id) {
  222. case lm25056:
  223. /* VIN: 6.14 mV VAUX: 293 uV LSB */
  224. ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
  225. break;
  226. case lm25066:
  227. /* VIN: 4.54 mV VAUX: 283.2 uV LSB */
  228. ret = DIV_ROUND_CLOSEST(ret * 2832, 45400);
  229. break;
  230. case lm5064:
  231. /* VIN: 4.53 mV VAUX: 700 uV LSB */
  232. ret = DIV_ROUND_CLOSEST(ret * 70, 453);
  233. break;
  234. case lm5066:
  235. case lm5066i:
  236. /* VIN: 2.18 mV VAUX: 725 uV LSB */
  237. ret = DIV_ROUND_CLOSEST(ret * 725, 2180);
  238. break;
  239. }
  240. break;
  241. case PMBUS_READ_IIN:
  242. ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN);
  243. break;
  244. case PMBUS_READ_PIN:
  245. ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN);
  246. break;
  247. case PMBUS_IIN_OC_WARN_LIMIT:
  248. ret = pmbus_read_word_data(client, 0,
  249. LM25066_MFR_IIN_OC_WARN_LIMIT);
  250. break;
  251. case PMBUS_PIN_OP_WARN_LIMIT:
  252. ret = pmbus_read_word_data(client, 0,
  253. LM25066_MFR_PIN_OP_WARN_LIMIT);
  254. break;
  255. case PMBUS_VIRT_READ_VIN_AVG:
  256. ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN);
  257. break;
  258. case PMBUS_VIRT_READ_VOUT_AVG:
  259. ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT);
  260. break;
  261. case PMBUS_VIRT_READ_IIN_AVG:
  262. ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN);
  263. break;
  264. case PMBUS_VIRT_READ_PIN_AVG:
  265. ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN);
  266. break;
  267. case PMBUS_VIRT_READ_PIN_MAX:
  268. ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK);
  269. break;
  270. case PMBUS_VIRT_RESET_PIN_HISTORY:
  271. ret = 0;
  272. break;
  273. default:
  274. ret = -ENODATA;
  275. break;
  276. }
  277. return ret;
  278. }
  279. static int lm25056_read_word_data(struct i2c_client *client, int page, int reg)
  280. {
  281. int ret;
  282. switch (reg) {
  283. case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
  284. ret = pmbus_read_word_data(client, 0,
  285. LM25056_VAUX_UV_WARN_LIMIT);
  286. if (ret < 0)
  287. break;
  288. /* Adjust returned value to match VIN coefficients */
  289. ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
  290. break;
  291. case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
  292. ret = pmbus_read_word_data(client, 0,
  293. LM25056_VAUX_OV_WARN_LIMIT);
  294. if (ret < 0)
  295. break;
  296. /* Adjust returned value to match VIN coefficients */
  297. ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
  298. break;
  299. default:
  300. ret = lm25066_read_word_data(client, page, reg);
  301. break;
  302. }
  303. return ret;
  304. }
  305. static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg)
  306. {
  307. int ret, s;
  308. switch (reg) {
  309. case PMBUS_VIRT_STATUS_VMON:
  310. ret = pmbus_read_byte_data(client, 0,
  311. PMBUS_STATUS_MFR_SPECIFIC);
  312. if (ret < 0)
  313. break;
  314. s = 0;
  315. if (ret & LM25056_MFR_STS_VAUX_UV_WARN)
  316. s |= PB_VOLTAGE_UV_WARNING;
  317. if (ret & LM25056_MFR_STS_VAUX_OV_WARN)
  318. s |= PB_VOLTAGE_OV_WARNING;
  319. ret = s;
  320. break;
  321. default:
  322. ret = -ENODATA;
  323. break;
  324. }
  325. return ret;
  326. }
  327. static int lm25066_write_word_data(struct i2c_client *client, int page, int reg,
  328. u16 word)
  329. {
  330. const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
  331. const struct lm25066_data *data = to_lm25066_data(info);
  332. int ret;
  333. switch (reg) {
  334. case PMBUS_POUT_OP_FAULT_LIMIT:
  335. case PMBUS_POUT_OP_WARN_LIMIT:
  336. case PMBUS_VOUT_UV_WARN_LIMIT:
  337. case PMBUS_OT_FAULT_LIMIT:
  338. case PMBUS_OT_WARN_LIMIT:
  339. case PMBUS_IIN_OC_FAULT_LIMIT:
  340. case PMBUS_VIN_UV_WARN_LIMIT:
  341. case PMBUS_VIN_UV_FAULT_LIMIT:
  342. case PMBUS_VIN_OV_FAULT_LIMIT:
  343. case PMBUS_VIN_OV_WARN_LIMIT:
  344. word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
  345. ret = pmbus_write_word_data(client, 0, reg, word);
  346. pmbus_clear_cache(client);
  347. break;
  348. case PMBUS_IIN_OC_WARN_LIMIT:
  349. word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
  350. ret = pmbus_write_word_data(client, 0,
  351. LM25066_MFR_IIN_OC_WARN_LIMIT,
  352. word);
  353. pmbus_clear_cache(client);
  354. break;
  355. case PMBUS_PIN_OP_WARN_LIMIT:
  356. word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
  357. ret = pmbus_write_word_data(client, 0,
  358. LM25066_MFR_PIN_OP_WARN_LIMIT,
  359. word);
  360. pmbus_clear_cache(client);
  361. break;
  362. case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
  363. /* Adjust from VIN coefficients (for LM25056) */
  364. word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
  365. word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
  366. ret = pmbus_write_word_data(client, 0,
  367. LM25056_VAUX_UV_WARN_LIMIT, word);
  368. pmbus_clear_cache(client);
  369. break;
  370. case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
  371. /* Adjust from VIN coefficients (for LM25056) */
  372. word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
  373. word = ((s16)word < 0) ? 0 : clamp_val(word, 0, data->rlimit);
  374. ret = pmbus_write_word_data(client, 0,
  375. LM25056_VAUX_OV_WARN_LIMIT, word);
  376. pmbus_clear_cache(client);
  377. break;
  378. case PMBUS_VIRT_RESET_PIN_HISTORY:
  379. ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK);
  380. break;
  381. default:
  382. ret = -ENODATA;
  383. break;
  384. }
  385. return ret;
  386. }
  387. static int lm25066_probe(struct i2c_client *client,
  388. const struct i2c_device_id *id)
  389. {
  390. int config;
  391. struct lm25066_data *data;
  392. struct pmbus_driver_info *info;
  393. struct __coeff *coeff;
  394. if (!i2c_check_functionality(client->adapter,
  395. I2C_FUNC_SMBUS_READ_BYTE_DATA))
  396. return -ENODEV;
  397. data = devm_kzalloc(&client->dev, sizeof(struct lm25066_data),
  398. GFP_KERNEL);
  399. if (!data)
  400. return -ENOMEM;
  401. config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP);
  402. if (config < 0)
  403. return config;
  404. data->id = id->driver_data;
  405. info = &data->info;
  406. info->pages = 1;
  407. info->format[PSC_VOLTAGE_IN] = direct;
  408. info->format[PSC_VOLTAGE_OUT] = direct;
  409. info->format[PSC_CURRENT_IN] = direct;
  410. info->format[PSC_TEMPERATURE] = direct;
  411. info->format[PSC_POWER] = direct;
  412. info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON
  413. | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT
  414. | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
  415. if (data->id == lm25056) {
  416. info->func[0] |= PMBUS_HAVE_STATUS_VMON;
  417. info->read_word_data = lm25056_read_word_data;
  418. info->read_byte_data = lm25056_read_byte_data;
  419. data->rlimit = 0x0fff;
  420. } else {
  421. info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
  422. info->read_word_data = lm25066_read_word_data;
  423. data->rlimit = 0x0fff;
  424. }
  425. info->write_word_data = lm25066_write_word_data;
  426. coeff = &lm25066_coeff[data->id][0];
  427. info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m;
  428. info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b;
  429. info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R;
  430. info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m;
  431. info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b;
  432. info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R;
  433. info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m;
  434. info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b;
  435. info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R;
  436. info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R;
  437. info->R[PSC_POWER] = coeff[PSC_POWER].R;
  438. if (config & LM25066_DEV_SETUP_CL) {
  439. info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m;
  440. info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].b;
  441. info->m[PSC_POWER] = coeff[PSC_POWER_L].m;
  442. info->b[PSC_POWER] = coeff[PSC_POWER_L].b;
  443. } else {
  444. info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m;
  445. info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b;
  446. info->m[PSC_POWER] = coeff[PSC_POWER].m;
  447. info->b[PSC_POWER] = coeff[PSC_POWER].b;
  448. }
  449. return pmbus_do_probe(client, id, info);
  450. }
  451. static const struct i2c_device_id lm25066_id[] = {
  452. {"lm25056", lm25056},
  453. {"lm25066", lm25066},
  454. {"lm5064", lm5064},
  455. {"lm5066", lm5066},
  456. {"lm5066i", lm5066i},
  457. { }
  458. };
  459. MODULE_DEVICE_TABLE(i2c, lm25066_id);
  460. /* This is the driver that will be inserted */
  461. static struct i2c_driver lm25066_driver = {
  462. .driver = {
  463. .name = "lm25066",
  464. },
  465. .probe = lm25066_probe,
  466. .remove = pmbus_do_remove,
  467. .id_table = lm25066_id,
  468. };
  469. module_i2c_driver(lm25066_driver);
  470. MODULE_AUTHOR("Guenter Roeck");
  471. MODULE_DESCRIPTION("PMBus driver for LM25066 and compatible chips");
  472. MODULE_LICENSE("GPL");