mlxreg-fan.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
  2. //
  3. // Copyright (c) 2018 Mellanox Technologies. All rights reserved.
  4. // Copyright (c) 2018 Vadim Pasternak <vadimp@mellanox.com>
  5. #include <linux/bitops.h>
  6. #include <linux/device.h>
  7. #include <linux/hwmon.h>
  8. #include <linux/module.h>
  9. #include <linux/platform_data/mlxreg.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/regmap.h>
  12. #include <linux/thermal.h>
  13. #define MLXREG_FAN_MAX_TACHO 12
  14. #define MLXREG_FAN_MAX_STATE 10
  15. #define MLXREG_FAN_MIN_DUTY 51 /* 20% */
  16. #define MLXREG_FAN_MAX_DUTY 255 /* 100% */
  17. /*
  18. * Minimum and maximum FAN allowed speed in percent: from 20% to 100%. Values
  19. * MLXREG_FAN_MAX_STATE + x, where x is between 2 and 10 are used for
  20. * setting FAN speed dynamic minimum. For example, if value is set to 14 (40%)
  21. * cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to
  22. * introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100.
  23. */
  24. #define MLXREG_FAN_SPEED_MIN (MLXREG_FAN_MAX_STATE + 2)
  25. #define MLXREG_FAN_SPEED_MAX (MLXREG_FAN_MAX_STATE * 2)
  26. #define MLXREG_FAN_SPEED_MIN_LEVEL 2 /* 20 percent */
  27. #define MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF 44
  28. #define MLXREG_FAN_TACHO_DIVIDER_DEF 1132
  29. /*
  30. * FAN datasheet defines the formula for RPM calculations as RPM = 15/t-high.
  31. * The logic in a programmable device measures the time t-high by sampling the
  32. * tachometer every t-sample (with the default value 11.32 uS) and increment
  33. * a counter (N) as long as the pulse has not change:
  34. * RPM = 15 / (t-sample * (K + Regval)), where:
  35. * Regval: is the value read from the programmable device register;
  36. * - 0xff - represents tachometer fault;
  37. * - 0xfe - represents tachometer minimum value , which is 4444 RPM;
  38. * - 0x00 - represents tachometer maximum value , which is 300000 RPM;
  39. * K: is 44 and it represents the minimum allowed samples per pulse;
  40. * N: is equal K + Regval;
  41. * In order to calculate RPM from the register value the following formula is
  42. * used: RPM = 15 / ((Regval + K) * 11.32) * 10^(-6)), which in the
  43. * default case is modified to:
  44. * RPM = 15000000 * 100 / ((Regval + 44) * 1132);
  45. * - for Regval 0x00, RPM will be 15000000 * 100 / (44 * 1132) = 30115;
  46. * - for Regval 0xfe, RPM will be 15000000 * 100 / ((254 + 44) * 1132) = 4446;
  47. * In common case the formula is modified to:
  48. * RPM = 15000000 * 100 / ((Regval + samples) * divider).
  49. */
  50. #define MLXREG_FAN_GET_RPM(rval, d, s) (DIV_ROUND_CLOSEST(15000000 * 100, \
  51. ((rval) + (s)) * (d)))
  52. #define MLXREG_FAN_GET_FAULT(val, mask) (!((val) ^ (mask)))
  53. #define MLXREG_FAN_PWM_DUTY2STATE(duty) (DIV_ROUND_CLOSEST((duty) * \
  54. MLXREG_FAN_MAX_STATE, \
  55. MLXREG_FAN_MAX_DUTY))
  56. #define MLXREG_FAN_PWM_STATE2DUTY(stat) (DIV_ROUND_CLOSEST((stat) * \
  57. MLXREG_FAN_MAX_DUTY, \
  58. MLXREG_FAN_MAX_STATE))
  59. /*
  60. * struct mlxreg_fan_tacho - tachometer data (internal use):
  61. *
  62. * @connected: indicates if tachometer is connected;
  63. * @reg: register offset;
  64. * @mask: fault mask;
  65. */
  66. struct mlxreg_fan_tacho {
  67. bool connected;
  68. u32 reg;
  69. u32 mask;
  70. };
  71. /*
  72. * struct mlxreg_fan_pwm - PWM data (internal use):
  73. *
  74. * @connected: indicates if PWM is connected;
  75. * @reg: register offset;
  76. */
  77. struct mlxreg_fan_pwm {
  78. bool connected;
  79. u32 reg;
  80. };
  81. /*
  82. * struct mlxreg_fan - private data (internal use):
  83. *
  84. * @dev: basic device;
  85. * @regmap: register map of parent device;
  86. * @tacho: tachometer data;
  87. * @pwm: PWM data;
  88. * @samples: minimum allowed samples per pulse;
  89. * @divider: divider value for tachometer RPM calculation;
  90. * @cooling: cooling device levels;
  91. * @cdev: cooling device;
  92. */
  93. struct mlxreg_fan {
  94. struct device *dev;
  95. void *regmap;
  96. struct mlxreg_core_platform_data *pdata;
  97. struct mlxreg_fan_tacho tacho[MLXREG_FAN_MAX_TACHO];
  98. struct mlxreg_fan_pwm pwm;
  99. int samples;
  100. int divider;
  101. u8 cooling_levels[MLXREG_FAN_MAX_STATE + 1];
  102. struct thermal_cooling_device *cdev;
  103. };
  104. static int
  105. mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  106. int channel, long *val)
  107. {
  108. struct mlxreg_fan *fan = dev_get_drvdata(dev);
  109. struct mlxreg_fan_tacho *tacho;
  110. u32 regval;
  111. int err;
  112. switch (type) {
  113. case hwmon_fan:
  114. tacho = &fan->tacho[channel];
  115. switch (attr) {
  116. case hwmon_fan_input:
  117. err = regmap_read(fan->regmap, tacho->reg, &regval);
  118. if (err)
  119. return err;
  120. *val = MLXREG_FAN_GET_RPM(regval, fan->divider,
  121. fan->samples);
  122. break;
  123. case hwmon_fan_fault:
  124. err = regmap_read(fan->regmap, tacho->reg, &regval);
  125. if (err)
  126. return err;
  127. *val = MLXREG_FAN_GET_FAULT(regval, tacho->mask);
  128. break;
  129. default:
  130. return -EOPNOTSUPP;
  131. }
  132. break;
  133. case hwmon_pwm:
  134. switch (attr) {
  135. case hwmon_pwm_input:
  136. err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
  137. if (err)
  138. return err;
  139. *val = regval;
  140. break;
  141. default:
  142. return -EOPNOTSUPP;
  143. }
  144. break;
  145. default:
  146. return -EOPNOTSUPP;
  147. }
  148. return 0;
  149. }
  150. static int
  151. mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
  152. int channel, long val)
  153. {
  154. struct mlxreg_fan *fan = dev_get_drvdata(dev);
  155. switch (type) {
  156. case hwmon_pwm:
  157. switch (attr) {
  158. case hwmon_pwm_input:
  159. if (val < MLXREG_FAN_MIN_DUTY ||
  160. val > MLXREG_FAN_MAX_DUTY)
  161. return -EINVAL;
  162. return regmap_write(fan->regmap, fan->pwm.reg, val);
  163. default:
  164. return -EOPNOTSUPP;
  165. }
  166. break;
  167. default:
  168. return -EOPNOTSUPP;
  169. }
  170. return -EOPNOTSUPP;
  171. }
  172. static umode_t
  173. mlxreg_fan_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
  174. int channel)
  175. {
  176. switch (type) {
  177. case hwmon_fan:
  178. if (!(((struct mlxreg_fan *)data)->tacho[channel].connected))
  179. return 0;
  180. switch (attr) {
  181. case hwmon_fan_input:
  182. case hwmon_fan_fault:
  183. return 0444;
  184. default:
  185. break;
  186. }
  187. break;
  188. case hwmon_pwm:
  189. if (!(((struct mlxreg_fan *)data)->pwm.connected))
  190. return 0;
  191. switch (attr) {
  192. case hwmon_pwm_input:
  193. return 0644;
  194. default:
  195. break;
  196. }
  197. break;
  198. default:
  199. break;
  200. }
  201. return 0;
  202. }
  203. static const u32 mlxreg_fan_hwmon_fan_config[] = {
  204. HWMON_F_INPUT | HWMON_F_FAULT,
  205. HWMON_F_INPUT | HWMON_F_FAULT,
  206. HWMON_F_INPUT | HWMON_F_FAULT,
  207. HWMON_F_INPUT | HWMON_F_FAULT,
  208. HWMON_F_INPUT | HWMON_F_FAULT,
  209. HWMON_F_INPUT | HWMON_F_FAULT,
  210. HWMON_F_INPUT | HWMON_F_FAULT,
  211. HWMON_F_INPUT | HWMON_F_FAULT,
  212. HWMON_F_INPUT | HWMON_F_FAULT,
  213. HWMON_F_INPUT | HWMON_F_FAULT,
  214. HWMON_F_INPUT | HWMON_F_FAULT,
  215. HWMON_F_INPUT | HWMON_F_FAULT,
  216. 0
  217. };
  218. static const struct hwmon_channel_info mlxreg_fan_hwmon_fan = {
  219. .type = hwmon_fan,
  220. .config = mlxreg_fan_hwmon_fan_config,
  221. };
  222. static const u32 mlxreg_fan_hwmon_pwm_config[] = {
  223. HWMON_PWM_INPUT,
  224. 0
  225. };
  226. static const struct hwmon_channel_info mlxreg_fan_hwmon_pwm = {
  227. .type = hwmon_pwm,
  228. .config = mlxreg_fan_hwmon_pwm_config,
  229. };
  230. static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = {
  231. &mlxreg_fan_hwmon_fan,
  232. &mlxreg_fan_hwmon_pwm,
  233. NULL
  234. };
  235. static const struct hwmon_ops mlxreg_fan_hwmon_hwmon_ops = {
  236. .is_visible = mlxreg_fan_is_visible,
  237. .read = mlxreg_fan_read,
  238. .write = mlxreg_fan_write,
  239. };
  240. static const struct hwmon_chip_info mlxreg_fan_hwmon_chip_info = {
  241. .ops = &mlxreg_fan_hwmon_hwmon_ops,
  242. .info = mlxreg_fan_hwmon_info,
  243. };
  244. static int mlxreg_fan_get_max_state(struct thermal_cooling_device *cdev,
  245. unsigned long *state)
  246. {
  247. *state = MLXREG_FAN_MAX_STATE;
  248. return 0;
  249. }
  250. static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev,
  251. unsigned long *state)
  252. {
  253. struct mlxreg_fan *fan = cdev->devdata;
  254. u32 regval;
  255. int err;
  256. err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
  257. if (err) {
  258. dev_err(fan->dev, "Failed to query PWM duty\n");
  259. return err;
  260. }
  261. *state = MLXREG_FAN_PWM_DUTY2STATE(regval);
  262. return 0;
  263. }
  264. static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
  265. unsigned long state)
  266. {
  267. struct mlxreg_fan *fan = cdev->devdata;
  268. unsigned long cur_state;
  269. u32 regval;
  270. int i;
  271. int err;
  272. /*
  273. * Verify if this request is for changing allowed FAN dynamical
  274. * minimum. If it is - update cooling levels accordingly and update
  275. * state, if current state is below the newly requested minimum state.
  276. * For example, if current state is 5, and minimal state is to be
  277. * changed from 4 to 6, fan->cooling_levels[0 to 5] will be changed all
  278. * from 4 to 6. And state 5 (fan->cooling_levels[4]) should be
  279. * overwritten.
  280. */
  281. if (state >= MLXREG_FAN_SPEED_MIN && state <= MLXREG_FAN_SPEED_MAX) {
  282. state -= MLXREG_FAN_MAX_STATE;
  283. for (i = 0; i < state; i++)
  284. fan->cooling_levels[i] = state;
  285. for (i = state; i <= MLXREG_FAN_MAX_STATE; i++)
  286. fan->cooling_levels[i] = i;
  287. err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
  288. if (err) {
  289. dev_err(fan->dev, "Failed to query PWM duty\n");
  290. return err;
  291. }
  292. cur_state = MLXREG_FAN_PWM_DUTY2STATE(regval);
  293. if (state < cur_state)
  294. return 0;
  295. state = cur_state;
  296. }
  297. if (state > MLXREG_FAN_MAX_STATE)
  298. return -EINVAL;
  299. /* Normalize the state to the valid speed range. */
  300. state = fan->cooling_levels[state];
  301. err = regmap_write(fan->regmap, fan->pwm.reg,
  302. MLXREG_FAN_PWM_STATE2DUTY(state));
  303. if (err) {
  304. dev_err(fan->dev, "Failed to write PWM duty\n");
  305. return err;
  306. }
  307. return 0;
  308. }
  309. static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = {
  310. .get_max_state = mlxreg_fan_get_max_state,
  311. .get_cur_state = mlxreg_fan_get_cur_state,
  312. .set_cur_state = mlxreg_fan_set_cur_state,
  313. };
  314. static int mlxreg_fan_config(struct mlxreg_fan *fan,
  315. struct mlxreg_core_platform_data *pdata)
  316. {
  317. struct mlxreg_core_data *data = pdata->data;
  318. bool configured = false;
  319. int tacho_num = 0, i;
  320. fan->samples = MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF;
  321. fan->divider = MLXREG_FAN_TACHO_DIVIDER_DEF;
  322. for (i = 0; i < pdata->counter; i++, data++) {
  323. if (strnstr(data->label, "tacho", sizeof(data->label))) {
  324. if (tacho_num == MLXREG_FAN_MAX_TACHO) {
  325. dev_err(fan->dev, "too many tacho entries: %s\n",
  326. data->label);
  327. return -EINVAL;
  328. }
  329. fan->tacho[tacho_num].reg = data->reg;
  330. fan->tacho[tacho_num].mask = data->mask;
  331. fan->tacho[tacho_num++].connected = true;
  332. } else if (strnstr(data->label, "pwm", sizeof(data->label))) {
  333. if (fan->pwm.connected) {
  334. dev_err(fan->dev, "duplicate pwm entry: %s\n",
  335. data->label);
  336. return -EINVAL;
  337. }
  338. fan->pwm.reg = data->reg;
  339. fan->pwm.connected = true;
  340. } else if (strnstr(data->label, "conf", sizeof(data->label))) {
  341. if (configured) {
  342. dev_err(fan->dev, "duplicate conf entry: %s\n",
  343. data->label);
  344. return -EINVAL;
  345. }
  346. /* Validate that conf parameters are not zeros. */
  347. if (!data->mask || !data->bit) {
  348. dev_err(fan->dev, "invalid conf entry params: %s\n",
  349. data->label);
  350. return -EINVAL;
  351. }
  352. fan->samples = data->mask;
  353. fan->divider = data->bit;
  354. configured = true;
  355. } else {
  356. dev_err(fan->dev, "invalid label: %s\n", data->label);
  357. return -EINVAL;
  358. }
  359. }
  360. /* Init cooling levels per PWM state. */
  361. for (i = 0; i < MLXREG_FAN_SPEED_MIN_LEVEL; i++)
  362. fan->cooling_levels[i] = MLXREG_FAN_SPEED_MIN_LEVEL;
  363. for (i = MLXREG_FAN_SPEED_MIN_LEVEL; i <= MLXREG_FAN_MAX_STATE; i++)
  364. fan->cooling_levels[i] = i;
  365. return 0;
  366. }
  367. static int mlxreg_fan_probe(struct platform_device *pdev)
  368. {
  369. struct mlxreg_core_platform_data *pdata;
  370. struct mlxreg_fan *fan;
  371. struct device *hwm;
  372. int err;
  373. pdata = dev_get_platdata(&pdev->dev);
  374. if (!pdata) {
  375. dev_err(&pdev->dev, "Failed to get platform data.\n");
  376. return -EINVAL;
  377. }
  378. fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
  379. if (!fan)
  380. return -ENOMEM;
  381. fan->dev = &pdev->dev;
  382. fan->regmap = pdata->regmap;
  383. platform_set_drvdata(pdev, fan);
  384. err = mlxreg_fan_config(fan, pdata);
  385. if (err)
  386. return err;
  387. hwm = devm_hwmon_device_register_with_info(&pdev->dev, "mlxreg_fan",
  388. fan,
  389. &mlxreg_fan_hwmon_chip_info,
  390. NULL);
  391. if (IS_ERR(hwm)) {
  392. dev_err(&pdev->dev, "Failed to register hwmon device\n");
  393. return PTR_ERR(hwm);
  394. }
  395. if (IS_REACHABLE(CONFIG_THERMAL)) {
  396. fan->cdev = thermal_cooling_device_register("mlxreg_fan", fan,
  397. &mlxreg_fan_cooling_ops);
  398. if (IS_ERR(fan->cdev)) {
  399. dev_err(&pdev->dev, "Failed to register cooling device\n");
  400. return PTR_ERR(fan->cdev);
  401. }
  402. }
  403. return 0;
  404. }
  405. static int mlxreg_fan_remove(struct platform_device *pdev)
  406. {
  407. struct mlxreg_fan *fan = platform_get_drvdata(pdev);
  408. if (IS_REACHABLE(CONFIG_THERMAL))
  409. thermal_cooling_device_unregister(fan->cdev);
  410. return 0;
  411. }
  412. static struct platform_driver mlxreg_fan_driver = {
  413. .driver = {
  414. .name = "mlxreg-fan",
  415. },
  416. .probe = mlxreg_fan_probe,
  417. .remove = mlxreg_fan_remove,
  418. };
  419. module_platform_driver(mlxreg_fan_driver);
  420. MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
  421. MODULE_DESCRIPTION("Mellanox FAN driver");
  422. MODULE_LICENSE("GPL");
  423. MODULE_ALIAS("platform:mlxreg-fan");