Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / hwmon / lan966x-hwmon.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/bitfield.h>
4 #include <linux/clk.h>
5 #include <linux/hwmon.h>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/platform_device.h>
10 #include <linux/polynomial.h>
11 #include <linux/regmap.h>
12
13 /*
14  * The original translation formulae of the temperature (in degrees of Celsius)
15  * are as follows:
16  *
17  *   T = -3.4627e-11*(N^4) + 1.1023e-7*(N^3) + -1.9165e-4*(N^2) +
18  *       3.0604e-1*(N^1) + -5.6197e1
19  *
20  * where [-56.197, 136.402]C and N = [0, 1023].
21  *
22  * They must be accordingly altered to be suitable for the integer arithmetics.
23  * The technique is called 'factor redistribution', which just makes sure the
24  * multiplications and divisions are made so to have a result of the operations
25  * within the integer numbers limit. In addition we need to translate the
26  * formulae to accept millidegrees of Celsius. Here what it looks like after
27  * the alterations:
28  *
29  *   T = -34627e-12*(N^4) + 110230e-9*(N^3) + -191650e-6*(N^2) +
30  *       306040e-3*(N^1) + -56197
31  *
32  * where T = [-56197, 136402]mC and N = [0, 1023].
33  */
34
35 static const struct polynomial poly_N_to_temp = {
36         .terms = {
37                 {4,  -34627, 1000, 1},
38                 {3,  110230, 1000, 1},
39                 {2, -191650, 1000, 1},
40                 {1,  306040, 1000, 1},
41                 {0,  -56197,    1, 1}
42         }
43 };
44
45 #define PVT_SENSOR_CTRL         0x0 /* unused */
46 #define PVT_SENSOR_CFG          0x4
47 #define   SENSOR_CFG_CLK_CFG            GENMASK(27, 20)
48 #define   SENSOR_CFG_TRIM_VAL           GENMASK(13, 9)
49 #define   SENSOR_CFG_SAMPLE_ENA         BIT(8)
50 #define   SENSOR_CFG_START_CAPTURE      BIT(7)
51 #define   SENSOR_CFG_CONTINIOUS_MODE    BIT(6)
52 #define   SENSOR_CFG_PSAMPLE_ENA        GENMASK(1, 0)
53 #define PVT_SENSOR_STAT         0x8
54 #define   SENSOR_STAT_DATA_VALID        BIT(10)
55 #define   SENSOR_STAT_DATA              GENMASK(9, 0)
56
57 #define FAN_CFG                 0x0
58 #define   FAN_CFG_DUTY_CYCLE            GENMASK(23, 16)
59 #define   INV_POL                       BIT(3)
60 #define   GATE_ENA                      BIT(2)
61 #define   PWM_OPEN_COL_ENA              BIT(1)
62 #define   FAN_STAT_CFG                  BIT(0)
63 #define FAN_PWM_FREQ            0x4
64 #define   FAN_PWM_CYC_10US              GENMASK(25, 15)
65 #define   FAN_PWM_FREQ_FREQ             GENMASK(14, 0)
66 #define FAN_CNT                 0xc
67 #define   FAN_CNT_DATA                  GENMASK(15, 0)
68
69 #define LAN966X_PVT_CLK         1200000 /* 1.2 MHz */
70
71 struct lan966x_hwmon {
72         struct regmap *regmap_pvt;
73         struct regmap *regmap_fan;
74         struct clk *clk;
75         unsigned long clk_rate;
76 };
77
78 static int lan966x_hwmon_read_temp(struct device *dev, long *val)
79 {
80         struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
81         unsigned int data;
82         int ret;
83
84         ret = regmap_read(hwmon->regmap_pvt, PVT_SENSOR_STAT, &data);
85         if (ret < 0)
86                 return ret;
87
88         if (!(data & SENSOR_STAT_DATA_VALID))
89                 return -ENODATA;
90
91         *val = polynomial_calc(&poly_N_to_temp,
92                                FIELD_GET(SENSOR_STAT_DATA, data));
93
94         return 0;
95 }
96
97 static int lan966x_hwmon_read_fan(struct device *dev, long *val)
98 {
99         struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
100         unsigned int data;
101         int ret;
102
103         ret = regmap_read(hwmon->regmap_fan, FAN_CNT, &data);
104         if (ret < 0)
105                 return ret;
106
107         /*
108          * Data is given in pulses per second. Assume two pulses
109          * per revolution.
110          */
111         *val = FIELD_GET(FAN_CNT_DATA, data) * 60 / 2;
112
113         return 0;
114 }
115
116 static int lan966x_hwmon_read_pwm(struct device *dev, long *val)
117 {
118         struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
119         unsigned int data;
120         int ret;
121
122         ret = regmap_read(hwmon->regmap_fan, FAN_CFG, &data);
123         if (ret < 0)
124                 return ret;
125
126         *val = FIELD_GET(FAN_CFG_DUTY_CYCLE, data);
127
128         return 0;
129 }
130
131 static int lan966x_hwmon_read_pwm_freq(struct device *dev, long *val)
132 {
133         struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
134         unsigned long tmp;
135         unsigned int data;
136         int ret;
137
138         ret = regmap_read(hwmon->regmap_fan, FAN_PWM_FREQ, &data);
139         if (ret < 0)
140                 return ret;
141
142         /*
143          * Datasheet says it is sys_clk / 256 / pwm_freq. But in reality
144          * it is sys_clk / 256 / (pwm_freq + 1).
145          */
146         data = FIELD_GET(FAN_PWM_FREQ_FREQ, data) + 1;
147         tmp = DIV_ROUND_CLOSEST(hwmon->clk_rate, 256);
148         *val = DIV_ROUND_CLOSEST(tmp, data);
149
150         return 0;
151 }
152
153 static int lan966x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
154                               u32 attr, int channel, long *val)
155 {
156         switch (type) {
157         case hwmon_temp:
158                 return lan966x_hwmon_read_temp(dev, val);
159         case hwmon_fan:
160                 return lan966x_hwmon_read_fan(dev, val);
161         case hwmon_pwm:
162                 switch (attr) {
163                 case hwmon_pwm_input:
164                         return lan966x_hwmon_read_pwm(dev, val);
165                 case hwmon_pwm_freq:
166                         return lan966x_hwmon_read_pwm_freq(dev, val);
167                 default:
168                         return -EOPNOTSUPP;
169                 }
170         default:
171                 return -EOPNOTSUPP;
172         }
173 }
174
175 static int lan966x_hwmon_write_pwm(struct device *dev, long val)
176 {
177         struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
178
179         if (val < 0 || val > 255)
180                 return -EINVAL;
181
182         return regmap_update_bits(hwmon->regmap_fan, FAN_CFG,
183                                   FAN_CFG_DUTY_CYCLE,
184                                   FIELD_PREP(FAN_CFG_DUTY_CYCLE, val));
185 }
186
187 static int lan966x_hwmon_write_pwm_freq(struct device *dev, long val)
188 {
189         struct lan966x_hwmon *hwmon = dev_get_drvdata(dev);
190
191         if (val <= 0)
192                 return -EINVAL;
193
194         val = DIV_ROUND_CLOSEST(hwmon->clk_rate, val);
195         val = DIV_ROUND_CLOSEST(val, 256) - 1;
196         val = clamp_val(val, 0, FAN_PWM_FREQ_FREQ);
197
198         return regmap_update_bits(hwmon->regmap_fan, FAN_PWM_FREQ,
199                                   FAN_PWM_FREQ_FREQ,
200                                   FIELD_PREP(FAN_PWM_FREQ_FREQ, val));
201 }
202
203 static int lan966x_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
204                                u32 attr, int channel, long val)
205 {
206         switch (type) {
207         case hwmon_pwm:
208                 switch (attr) {
209                 case hwmon_pwm_input:
210                         return lan966x_hwmon_write_pwm(dev, val);
211                 case hwmon_pwm_freq:
212                         return lan966x_hwmon_write_pwm_freq(dev, val);
213                 default:
214                         return -EOPNOTSUPP;
215                 }
216         default:
217                 return -EOPNOTSUPP;
218         }
219 }
220
221 static umode_t lan966x_hwmon_is_visible(const void *data,
222                                         enum hwmon_sensor_types type,
223                                         u32 attr, int channel)
224 {
225         umode_t mode = 0;
226
227         switch (type) {
228         case hwmon_temp:
229                 switch (attr) {
230                 case hwmon_temp_input:
231                         mode = 0444;
232                         break;
233                 default:
234                         break;
235                 }
236                 break;
237         case hwmon_fan:
238                 switch (attr) {
239                 case hwmon_fan_input:
240                         mode = 0444;
241                         break;
242                 default:
243                         break;
244                 }
245                 break;
246         case hwmon_pwm:
247                 switch (attr) {
248                 case hwmon_pwm_input:
249                 case hwmon_pwm_freq:
250                         mode = 0644;
251                         break;
252                 default:
253                         break;
254                 }
255                 break;
256         default:
257                 break;
258         }
259
260         return mode;
261 }
262
263 static const struct hwmon_channel_info * const lan966x_hwmon_info[] = {
264         HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
265         HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
266         HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT),
267         HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_FREQ),
268         NULL
269 };
270
271 static const struct hwmon_ops lan966x_hwmon_ops = {
272         .is_visible = lan966x_hwmon_is_visible,
273         .read = lan966x_hwmon_read,
274         .write = lan966x_hwmon_write,
275 };
276
277 static const struct hwmon_chip_info lan966x_hwmon_chip_info = {
278         .ops = &lan966x_hwmon_ops,
279         .info = lan966x_hwmon_info,
280 };
281
282 static void lan966x_hwmon_disable(void *data)
283 {
284         struct lan966x_hwmon *hwmon = data;
285
286         regmap_update_bits(hwmon->regmap_pvt, PVT_SENSOR_CFG,
287                            SENSOR_CFG_SAMPLE_ENA | SENSOR_CFG_CONTINIOUS_MODE,
288                            0);
289 }
290
291 static int lan966x_hwmon_enable(struct device *dev,
292                                 struct lan966x_hwmon *hwmon)
293 {
294         unsigned int mask = SENSOR_CFG_CLK_CFG |
295                             SENSOR_CFG_SAMPLE_ENA |
296                             SENSOR_CFG_START_CAPTURE |
297                             SENSOR_CFG_CONTINIOUS_MODE |
298                             SENSOR_CFG_PSAMPLE_ENA;
299         unsigned int val;
300         unsigned int div;
301         int ret;
302
303         /* enable continuous mode */
304         val = SENSOR_CFG_SAMPLE_ENA | SENSOR_CFG_CONTINIOUS_MODE;
305
306         /* set PVT clock to be between 1.15 and 1.25 MHz */
307         div = DIV_ROUND_CLOSEST(hwmon->clk_rate, LAN966X_PVT_CLK);
308         val |= FIELD_PREP(SENSOR_CFG_CLK_CFG, div);
309
310         ret = regmap_update_bits(hwmon->regmap_pvt, PVT_SENSOR_CFG,
311                                  mask, val);
312         if (ret)
313                 return ret;
314
315         return devm_add_action_or_reset(dev, lan966x_hwmon_disable, hwmon);
316 }
317
318 static struct regmap *lan966x_init_regmap(struct platform_device *pdev,
319                                           const char *name)
320 {
321         struct regmap_config regmap_config = {
322                 .reg_bits = 32,
323                 .reg_stride = 4,
324                 .val_bits = 32,
325         };
326         void __iomem *base;
327
328         base = devm_platform_ioremap_resource_byname(pdev, name);
329         if (IS_ERR(base))
330                 return ERR_CAST(base);
331
332         regmap_config.name = name;
333
334         return devm_regmap_init_mmio(&pdev->dev, base, &regmap_config);
335 }
336
337 static int lan966x_hwmon_probe(struct platform_device *pdev)
338 {
339         struct device *dev = &pdev->dev;
340         struct lan966x_hwmon *hwmon;
341         struct device *hwmon_dev;
342         int ret;
343
344         hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
345         if (!hwmon)
346                 return -ENOMEM;
347
348         hwmon->clk = devm_clk_get_enabled(dev, NULL);
349         if (IS_ERR(hwmon->clk))
350                 return dev_err_probe(dev, PTR_ERR(hwmon->clk),
351                                      "failed to get clock\n");
352
353         hwmon->clk_rate = clk_get_rate(hwmon->clk);
354
355         hwmon->regmap_pvt = lan966x_init_regmap(pdev, "pvt");
356         if (IS_ERR(hwmon->regmap_pvt))
357                 return dev_err_probe(dev, PTR_ERR(hwmon->regmap_pvt),
358                                      "failed to get regmap for PVT registers\n");
359
360         hwmon->regmap_fan = lan966x_init_regmap(pdev, "fan");
361         if (IS_ERR(hwmon->regmap_fan))
362                 return dev_err_probe(dev, PTR_ERR(hwmon->regmap_fan),
363                                      "failed to get regmap for fan registers\n");
364
365         ret = lan966x_hwmon_enable(dev, hwmon);
366         if (ret)
367                 return dev_err_probe(dev, ret, "failed to enable sensor\n");
368
369         hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
370                                 "lan966x_hwmon", hwmon,
371                                 &lan966x_hwmon_chip_info, NULL);
372         if (IS_ERR(hwmon_dev))
373                 return dev_err_probe(dev, PTR_ERR(hwmon_dev),
374                                      "failed to register hwmon device\n");
375
376         return 0;
377 }
378
379 static const struct of_device_id lan966x_hwmon_of_match[] = {
380         { .compatible = "microchip,lan9668-hwmon" },
381         {}
382 };
383 MODULE_DEVICE_TABLE(of, lan966x_hwmon_of_match);
384
385 static struct platform_driver lan966x_hwmon_driver = {
386         .probe = lan966x_hwmon_probe,
387         .driver = {
388                 .name = "lan966x-hwmon",
389                 .of_match_table = lan966x_hwmon_of_match,
390         },
391 };
392 module_platform_driver(lan966x_hwmon_driver);
393
394 MODULE_DESCRIPTION("LAN966x Hardware Monitoring Driver");
395 MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
396 MODULE_LICENSE("GPL");