nct7363.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2023 Nuvoton Technology corporation.
  4. */
  5. #include <linux/bitfield.h>
  6. #include <linux/bits.h>
  7. #include <linux/err.h>
  8. #include <linux/hwmon.h>
  9. #include <linux/i2c.h>
  10. #include <linux/module.h>
  11. #include <linux/regmap.h>
  12. #include <linux/slab.h>
  13. #define NCT7363_REG_FUNC_CFG_BASE(x) (0x20 + (x))
  14. #define NCT7363_REG_LSRS(x) (0x34 + ((x) / 8))
  15. #define NCT7363_REG_PWMEN_BASE(x) (0x38 + (x))
  16. #define NCT7363_REG_FANINEN_BASE(x) (0x41 + (x))
  17. #define NCT7363_REG_FANINX_HVAL(x) (0x48 + ((x) * 2))
  18. #define NCT7363_REG_FANINX_LVAL(x) (0x49 + ((x) * 2))
  19. #define NCT7363_REG_FANINX_HL(x) (0x6C + ((x) * 2))
  20. #define NCT7363_REG_FANINX_LL(x) (0x6D + ((x) * 2))
  21. #define NCT7363_REG_FSCPXDUTY(x) (0x90 + ((x) * 2))
  22. #define NCT7363_REG_FSCPXDIV(x) (0x91 + ((x) * 2))
  23. #define PWM_SEL(x) (BIT(0) << ((x) * 2))
  24. #define FANIN_SEL(_x) ({typeof(_x) (x) = (_x); \
  25. BIT(1) << (((x) < 8) ? \
  26. (((x) + 8) * 2) : \
  27. (((x) % 8) * 2)); })
  28. #define ALARM_SEL(x, y) ((x) & (BIT((y) % 8)))
  29. #define VALUE_TO_REG(x, y) (((x) >> ((y) * 8)) & 0xFF)
  30. #define NCT7363_FANINX_LVAL_MASK GENMASK(4, 0)
  31. #define NCT7363_FANIN_MASK GENMASK(12, 0)
  32. #define NCT7363_PWM_COUNT 16
  33. static inline unsigned int fan_from_reg(u16 val)
  34. {
  35. if (val == NCT7363_FANIN_MASK || val == 0)
  36. return 0;
  37. return (1350000UL / val);
  38. }
  39. static const struct of_device_id nct7363_of_match[] = {
  40. { .compatible = "nuvoton,nct7363", },
  41. { .compatible = "nuvoton,nct7362", },
  42. { }
  43. };
  44. MODULE_DEVICE_TABLE(of, nct7363_of_match);
  45. struct nct7363_data {
  46. struct regmap *regmap;
  47. u16 fanin_mask;
  48. u16 pwm_mask;
  49. };
  50. static int nct7363_read_fan(struct device *dev, u32 attr, int channel,
  51. long *val)
  52. {
  53. struct nct7363_data *data = dev_get_drvdata(dev);
  54. unsigned int reg;
  55. u8 regval[2];
  56. int ret;
  57. u16 cnt;
  58. switch (attr) {
  59. case hwmon_fan_input:
  60. /*
  61. * High-byte register should be read first to latch
  62. * synchronous low-byte value
  63. */
  64. ret = regmap_bulk_read(data->regmap,
  65. NCT7363_REG_FANINX_HVAL(channel),
  66. &regval, 2);
  67. if (ret)
  68. return ret;
  69. cnt = (regval[0] << 5) | (regval[1] & NCT7363_FANINX_LVAL_MASK);
  70. *val = fan_from_reg(cnt);
  71. return 0;
  72. case hwmon_fan_min:
  73. ret = regmap_bulk_read(data->regmap,
  74. NCT7363_REG_FANINX_HL(channel),
  75. &regval, 2);
  76. if (ret)
  77. return ret;
  78. cnt = (regval[0] << 5) | (regval[1] & NCT7363_FANINX_LVAL_MASK);
  79. *val = fan_from_reg(cnt);
  80. return 0;
  81. case hwmon_fan_alarm:
  82. ret = regmap_read(data->regmap,
  83. NCT7363_REG_LSRS(channel), &reg);
  84. if (ret)
  85. return ret;
  86. *val = (long)ALARM_SEL(reg, channel) > 0 ? 1 : 0;
  87. return 0;
  88. default:
  89. return -EOPNOTSUPP;
  90. }
  91. }
  92. static int nct7363_write_fan(struct device *dev, u32 attr, int channel,
  93. long val)
  94. {
  95. struct nct7363_data *data = dev_get_drvdata(dev);
  96. u8 regval[2];
  97. int ret;
  98. if (val <= 0)
  99. return -EINVAL;
  100. switch (attr) {
  101. case hwmon_fan_min:
  102. val = clamp_val(DIV_ROUND_CLOSEST(1350000, val),
  103. 1, NCT7363_FANIN_MASK);
  104. regval[0] = val >> 5;
  105. regval[1] = val & NCT7363_FANINX_LVAL_MASK;
  106. ret = regmap_bulk_write(data->regmap,
  107. NCT7363_REG_FANINX_HL(channel),
  108. regval, 2);
  109. return ret;
  110. default:
  111. return -EOPNOTSUPP;
  112. }
  113. }
  114. static umode_t nct7363_fan_is_visible(const void *_data, u32 attr, int channel)
  115. {
  116. const struct nct7363_data *data = _data;
  117. switch (attr) {
  118. case hwmon_fan_input:
  119. case hwmon_fan_alarm:
  120. if (data->fanin_mask & BIT(channel))
  121. return 0444;
  122. break;
  123. case hwmon_fan_min:
  124. if (data->fanin_mask & BIT(channel))
  125. return 0644;
  126. break;
  127. default:
  128. break;
  129. }
  130. return 0;
  131. }
  132. static int nct7363_read_pwm(struct device *dev, u32 attr, int channel,
  133. long *val)
  134. {
  135. struct nct7363_data *data = dev_get_drvdata(dev);
  136. unsigned int regval;
  137. int ret;
  138. switch (attr) {
  139. case hwmon_pwm_input:
  140. ret = regmap_read(data->regmap,
  141. NCT7363_REG_FSCPXDUTY(channel), &regval);
  142. if (ret)
  143. return ret;
  144. *val = (long)regval;
  145. return 0;
  146. default:
  147. return -EOPNOTSUPP;
  148. }
  149. }
  150. static int nct7363_write_pwm(struct device *dev, u32 attr, int channel,
  151. long val)
  152. {
  153. struct nct7363_data *data = dev_get_drvdata(dev);
  154. int ret;
  155. switch (attr) {
  156. case hwmon_pwm_input:
  157. if (val < 0 || val > 255)
  158. return -EINVAL;
  159. ret = regmap_write(data->regmap,
  160. NCT7363_REG_FSCPXDUTY(channel), val);
  161. return ret;
  162. default:
  163. return -EOPNOTSUPP;
  164. }
  165. }
  166. static umode_t nct7363_pwm_is_visible(const void *_data, u32 attr, int channel)
  167. {
  168. const struct nct7363_data *data = _data;
  169. switch (attr) {
  170. case hwmon_pwm_input:
  171. if (data->pwm_mask & BIT(channel))
  172. return 0644;
  173. break;
  174. default:
  175. break;
  176. }
  177. return 0;
  178. }
  179. static int nct7363_read(struct device *dev, enum hwmon_sensor_types type,
  180. u32 attr, int channel, long *val)
  181. {
  182. switch (type) {
  183. case hwmon_fan:
  184. return nct7363_read_fan(dev, attr, channel, val);
  185. case hwmon_pwm:
  186. return nct7363_read_pwm(dev, attr, channel, val);
  187. default:
  188. return -EOPNOTSUPP;
  189. }
  190. }
  191. static int nct7363_write(struct device *dev, enum hwmon_sensor_types type,
  192. u32 attr, int channel, long val)
  193. {
  194. switch (type) {
  195. case hwmon_fan:
  196. return nct7363_write_fan(dev, attr, channel, val);
  197. case hwmon_pwm:
  198. return nct7363_write_pwm(dev, attr, channel, val);
  199. default:
  200. return -EOPNOTSUPP;
  201. }
  202. }
  203. static umode_t nct7363_is_visible(const void *data,
  204. enum hwmon_sensor_types type,
  205. u32 attr, int channel)
  206. {
  207. switch (type) {
  208. case hwmon_fan:
  209. return nct7363_fan_is_visible(data, attr, channel);
  210. case hwmon_pwm:
  211. return nct7363_pwm_is_visible(data, attr, channel);
  212. default:
  213. return 0;
  214. }
  215. }
  216. static const struct hwmon_channel_info *nct7363_info[] = {
  217. HWMON_CHANNEL_INFO(fan,
  218. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  219. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  220. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  221. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  222. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  223. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  224. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  225. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  226. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  227. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  228. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  229. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  230. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  231. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  232. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
  233. HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM),
  234. HWMON_CHANNEL_INFO(pwm,
  235. HWMON_PWM_INPUT,
  236. HWMON_PWM_INPUT,
  237. HWMON_PWM_INPUT,
  238. HWMON_PWM_INPUT,
  239. HWMON_PWM_INPUT,
  240. HWMON_PWM_INPUT,
  241. HWMON_PWM_INPUT,
  242. HWMON_PWM_INPUT,
  243. HWMON_PWM_INPUT,
  244. HWMON_PWM_INPUT,
  245. HWMON_PWM_INPUT,
  246. HWMON_PWM_INPUT,
  247. HWMON_PWM_INPUT,
  248. HWMON_PWM_INPUT,
  249. HWMON_PWM_INPUT,
  250. HWMON_PWM_INPUT),
  251. NULL
  252. };
  253. static const struct hwmon_ops nct7363_hwmon_ops = {
  254. .is_visible = nct7363_is_visible,
  255. .read = nct7363_read,
  256. .write = nct7363_write,
  257. };
  258. static const struct hwmon_chip_info nct7363_chip_info = {
  259. .ops = &nct7363_hwmon_ops,
  260. .info = nct7363_info,
  261. };
  262. static int nct7363_init_chip(struct nct7363_data *data)
  263. {
  264. u32 func_config = 0;
  265. int i, ret;
  266. /* Pin Function Configuration */
  267. for (i = 0; i < NCT7363_PWM_COUNT; i++) {
  268. if (data->pwm_mask & BIT(i))
  269. func_config |= PWM_SEL(i);
  270. if (data->fanin_mask & BIT(i))
  271. func_config |= FANIN_SEL(i);
  272. }
  273. for (i = 0; i < 4; i++) {
  274. ret = regmap_write(data->regmap, NCT7363_REG_FUNC_CFG_BASE(i),
  275. VALUE_TO_REG(func_config, i));
  276. if (ret < 0)
  277. return ret;
  278. }
  279. /* PWM and FANIN Monitoring Enable */
  280. for (i = 0; i < 2; i++) {
  281. ret = regmap_write(data->regmap, NCT7363_REG_PWMEN_BASE(i),
  282. VALUE_TO_REG(data->pwm_mask, i));
  283. if (ret < 0)
  284. return ret;
  285. ret = regmap_write(data->regmap, NCT7363_REG_FANINEN_BASE(i),
  286. VALUE_TO_REG(data->fanin_mask, i));
  287. if (ret < 0)
  288. return ret;
  289. }
  290. return 0;
  291. }
  292. static int nct7363_present_pwm_fanin(struct device *dev,
  293. struct device_node *child,
  294. struct nct7363_data *data)
  295. {
  296. u8 fanin_ch[NCT7363_PWM_COUNT];
  297. struct of_phandle_args args;
  298. int ret, fanin_cnt;
  299. u8 ch, index;
  300. ret = of_parse_phandle_with_args(child, "pwms", "#pwm-cells",
  301. 0, &args);
  302. if (ret)
  303. return ret;
  304. of_node_put(args.np);
  305. if (args.args[0] >= NCT7363_PWM_COUNT)
  306. return -EINVAL;
  307. data->pwm_mask |= BIT(args.args[0]);
  308. fanin_cnt = of_property_count_u8_elems(child, "tach-ch");
  309. if (fanin_cnt < 1 || fanin_cnt > NCT7363_PWM_COUNT)
  310. return -EINVAL;
  311. ret = of_property_read_u8_array(child, "tach-ch", fanin_ch, fanin_cnt);
  312. if (ret)
  313. return ret;
  314. for (ch = 0; ch < fanin_cnt; ch++) {
  315. index = fanin_ch[ch];
  316. if (index >= NCT7363_PWM_COUNT)
  317. return -EINVAL;
  318. data->fanin_mask |= BIT(index);
  319. }
  320. return 0;
  321. }
  322. static bool nct7363_regmap_is_volatile(struct device *dev, unsigned int reg)
  323. {
  324. switch (reg) {
  325. case NCT7363_REG_LSRS(0) ... NCT7363_REG_LSRS(15):
  326. case NCT7363_REG_FANINX_HVAL(0) ... NCT7363_REG_FANINX_LVAL(15):
  327. case NCT7363_REG_FANINX_HL(0) ... NCT7363_REG_FANINX_LL(15):
  328. case NCT7363_REG_FSCPXDUTY(0) ... NCT7363_REG_FSCPXDIV(15):
  329. return true;
  330. default:
  331. return false;
  332. }
  333. }
  334. static const struct regmap_config nct7363_regmap_config = {
  335. .reg_bits = 8,
  336. .val_bits = 8,
  337. .use_single_read = true,
  338. .use_single_write = true,
  339. .cache_type = REGCACHE_MAPLE,
  340. .volatile_reg = nct7363_regmap_is_volatile,
  341. };
  342. static int nct7363_probe(struct i2c_client *client)
  343. {
  344. struct device *dev = &client->dev;
  345. struct nct7363_data *data;
  346. struct device *hwmon_dev;
  347. int ret;
  348. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  349. if (!data)
  350. return -ENOMEM;
  351. data->regmap = devm_regmap_init_i2c(client, &nct7363_regmap_config);
  352. if (IS_ERR(data->regmap))
  353. return PTR_ERR(data->regmap);
  354. for_each_child_of_node_scoped(dev->of_node, child) {
  355. ret = nct7363_present_pwm_fanin(dev, child, data);
  356. if (ret)
  357. return ret;
  358. }
  359. /* Initialize the chip */
  360. ret = nct7363_init_chip(data);
  361. if (ret)
  362. return ret;
  363. hwmon_dev =
  364. devm_hwmon_device_register_with_info(dev, client->name, data,
  365. &nct7363_chip_info, NULL);
  366. return PTR_ERR_OR_ZERO(hwmon_dev);
  367. }
  368. static struct i2c_driver nct7363_driver = {
  369. .class = I2C_CLASS_HWMON,
  370. .driver = {
  371. .name = "nct7363",
  372. .of_match_table = nct7363_of_match,
  373. },
  374. .probe = nct7363_probe,
  375. };
  376. module_i2c_driver(nct7363_driver);
  377. MODULE_AUTHOR("CW Ho <cwho@nuvoton.com>");
  378. MODULE_AUTHOR("Ban Feng <kcfeng0@nuvoton.com>");
  379. MODULE_DESCRIPTION("NCT7363 Hardware Monitoring Driver");
  380. MODULE_LICENSE("GPL");