Merge tag 'JH7110_515_SDK_v4.0.0-rc2' into vf2-515-devel
[platform/kernel/linux-starfive.git] / drivers / hwmon / sfctemp.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
4  * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
5  */
6 #include <linux/clk.h>
7 #include <linux/completion.h>
8 #include <linux/delay.h>
9 #include <linux/hwmon.h>
10 #include <linux/interrupt.h>
11 #include <linux/io.h>
12 #include <linux/module.h>
13 #include <linux/mutex.h>
14 #include <linux/of.h>
15 #include <linux/platform_device.h>
16 #include <linux/reset.h>
17 #include <linux/pm_runtime.h>
18
19 /*
20  * TempSensor reset. The RSTN can be de-asserted once the analog core has
21  * powered up. Trst(min 100ns)
22  * 0:reset  1:de-assert
23  */
24 #define SFCTEMP_RSTN    BIT(0)
25
26 /*
27  * TempSensor analog core power down. The analog core will be powered up
28  * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
29  * analog core is powered up.
30  * 0:power up  1:power down
31  */
32 #define SFCTEMP_PD      BIT(1)
33
34 /*
35  * TempSensor start conversion enable.
36  * 0:disable  1:enable
37  */
38 #define SFCTEMP_RUN     BIT(2)
39
40 /*
41  * TempSensor conversion value output.
42  * Temp(C)=DOUT*Y/4094 - K
43  */
44 #define SFCTEMP_DOUT_POS        16
45 #define SFCTEMP_DOUT_MSK        GENMASK(27, 16)
46
47 /* DOUT to Celcius conversion constants */
48 #define SFCTEMP_Y1000   237500L
49 #define SFCTEMP_Z       4094L
50 #define SFCTEMP_K1000   81100L
51
52 struct sfctemp {
53         /* serialize access to hardware register and enabled below */
54         struct mutex lock;
55         struct completion conversion_done;
56         void __iomem *regs;
57         struct clk *clk_sense;
58         struct clk *clk_bus;
59         struct reset_control *rst_sense;
60         struct reset_control *rst_bus;
61         bool enabled;
62 };
63
64 static irqreturn_t sfctemp_isr(int irq, void *data)
65 {
66         struct sfctemp *sfctemp = data;
67
68         complete(&sfctemp->conversion_done);
69         return IRQ_HANDLED;
70 }
71
72 static void sfctemp_power_up(struct sfctemp *sfctemp)
73 {
74         /* make sure we're powered down first */
75         writel(SFCTEMP_PD, sfctemp->regs);
76         udelay(1);
77
78         writel(0, sfctemp->regs);
79         /* wait t_pu(50us) + t_rst(100ns) */
80         usleep_range(60, 200);
81
82         /* de-assert reset */
83         writel(SFCTEMP_RSTN, sfctemp->regs);
84         udelay(1); /* wait t_su(500ps) */
85 }
86
87 static void sfctemp_power_down(struct sfctemp *sfctemp)
88 {
89         writel(SFCTEMP_PD, sfctemp->regs);
90 }
91
92 static void sfctemp_run_single(struct sfctemp *sfctemp)
93 {
94         writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
95         udelay(1);
96         writel(SFCTEMP_RSTN, sfctemp->regs);
97 }
98
99 static int sfctemp_enable(struct sfctemp *sfctemp)
100 {
101         int ret = 0;
102
103         mutex_lock(&sfctemp->lock);
104         if (sfctemp->enabled)
105                 goto done;
106
107         ret = clk_prepare_enable(sfctemp->clk_bus);
108         if (ret)
109                 goto err;
110         ret = reset_control_deassert(sfctemp->rst_bus);
111         if (ret)
112                 goto err_disable_bus;
113
114         ret = clk_prepare_enable(sfctemp->clk_sense);
115         if (ret)
116                 goto err_assert_bus;
117         ret = reset_control_deassert(sfctemp->rst_sense);
118         if (ret)
119                 goto err_disable_sense;
120
121         sfctemp_power_up(sfctemp);
122         sfctemp->enabled = true;
123 done:
124         mutex_unlock(&sfctemp->lock);
125         return ret;
126
127 err_disable_sense:
128         clk_disable_unprepare(sfctemp->clk_sense);
129 err_assert_bus:
130         reset_control_assert(sfctemp->rst_bus);
131 err_disable_bus:
132         clk_disable_unprepare(sfctemp->clk_bus);
133 err:
134         mutex_unlock(&sfctemp->lock);
135         return ret;
136 }
137
138 static int sfctemp_disable(struct sfctemp *sfctemp)
139 {
140         mutex_lock(&sfctemp->lock);
141         if (!sfctemp->enabled)
142                 goto done;
143
144         sfctemp_power_down(sfctemp);
145         reset_control_assert(sfctemp->rst_sense);
146         clk_disable_unprepare(sfctemp->clk_sense);
147         reset_control_assert(sfctemp->rst_bus);
148         clk_disable_unprepare(sfctemp->clk_bus);
149         sfctemp->enabled = false;
150 done:
151         mutex_unlock(&sfctemp->lock);
152         return 0;
153 }
154
155 static void sfctemp_disable_action(void *data)
156 {
157         sfctemp_disable(data);
158 }
159
160 static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
161 {
162         int ret;
163
164         mutex_lock(&sfctemp->lock);
165         if (!sfctemp->enabled) {
166                 ret = -ENODATA;
167                 goto out;
168         }
169
170         sfctemp_run_single(sfctemp);
171
172         ret = wait_for_completion_interruptible_timeout(&sfctemp->conversion_done,
173                                                         msecs_to_jiffies(10));
174         if (ret <= 0) {
175                 if (ret == 0)
176                         ret = -ETIMEDOUT;
177                 goto out;
178         }
179
180         /* calculate temperature in milli Celcius */
181         *val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
182                 * SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
183
184         ret = 0;
185 out:
186         mutex_unlock(&sfctemp->lock);
187         return ret;
188 }
189
190 static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
191                                   u32 attr, int channel)
192 {
193         switch (type) {
194         case hwmon_temp:
195                 switch (attr) {
196                 case hwmon_temp_enable:
197                         return 0644;
198                 case hwmon_temp_input:
199                         return 0444;
200                 }
201                 return 0;
202         default:
203                 return 0;
204         }
205 }
206
207 static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
208                         u32 attr, int channel, long *val)
209 {
210         struct sfctemp *sfctemp = dev_get_drvdata(dev);
211         int ret;
212
213         ret = pm_runtime_get_sync(dev);
214
215         switch (type) {
216         case hwmon_temp:
217                 switch (attr) {
218                 case hwmon_temp_enable:
219                         *val = sfctemp->enabled;
220                         pm_runtime_put(dev);
221                         return 0;
222                 case hwmon_temp_input:
223                         ret = sfctemp_convert(sfctemp, val);
224                         pm_runtime_put(dev);
225                         return ret;
226                 }
227                 pm_runtime_put(dev);
228                 return -EINVAL;
229         default:
230                 pm_runtime_put(dev);
231                 return -EINVAL;
232         }
233 }
234
235 static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
236                          u32 attr, int channel, long val)
237 {
238         struct sfctemp *sfctemp = dev_get_drvdata(dev);
239
240         switch (type) {
241         case hwmon_temp:
242                 switch (attr) {
243                 case hwmon_temp_enable:
244                         if (val == 0)
245                                 return sfctemp_disable(sfctemp);
246                         if (val == 1)
247                                 return sfctemp_enable(sfctemp);
248                         break;
249                 }
250                 return -EINVAL;
251         default:
252                 return -EINVAL;
253         }
254 }
255
256 static const struct hwmon_channel_info *sfctemp_info[] = {
257         HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
258         HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
259         NULL
260 };
261
262 static const struct hwmon_ops sfctemp_hwmon_ops = {
263         .is_visible = sfctemp_is_visible,
264         .read = sfctemp_read,
265         .write = sfctemp_write,
266 };
267
268 static const struct hwmon_chip_info sfctemp_chip_info = {
269         .ops = &sfctemp_hwmon_ops,
270         .info = sfctemp_info,
271 };
272
273 static int sfctemp_probe(struct platform_device *pdev)
274 {
275         struct device *dev = &pdev->dev;
276         struct device *hwmon_dev;
277         struct sfctemp *sfctemp;
278         int ret;
279
280         sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
281         if (!sfctemp)
282                 return -ENOMEM;
283
284         dev_set_drvdata(dev, sfctemp);
285         mutex_init(&sfctemp->lock);
286         init_completion(&sfctemp->conversion_done);
287
288         sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
289         if (IS_ERR(sfctemp->regs))
290                 return PTR_ERR(sfctemp->regs);
291
292         sfctemp->clk_sense = devm_clk_get(dev, "sense");
293         if (IS_ERR(sfctemp->clk_sense))
294                 return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
295                                      "error getting sense clock\n");
296
297         sfctemp->clk_bus = devm_clk_get(dev, "bus");
298         if (IS_ERR(sfctemp->clk_bus))
299                 return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
300                                      "error getting bus clock\n");
301
302         sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
303         if (IS_ERR(sfctemp->rst_sense))
304                 return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
305                                      "error getting sense reset\n");
306
307         sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
308         if (IS_ERR(sfctemp->rst_bus))
309                 return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
310                                      "error getting busreset\n");
311
312         ret = reset_control_assert(sfctemp->rst_sense);
313         if (ret)
314                 return dev_err_probe(dev, ret, "error asserting sense reset\n");
315
316         ret = reset_control_assert(sfctemp->rst_bus);
317         if (ret)
318                 return dev_err_probe(dev, ret, "error asserting bus reset\n");
319
320         ret = platform_get_irq(pdev, 0);
321         if (ret < 0)
322                 return ret;
323
324         ret = devm_request_irq(dev, ret, sfctemp_isr, 0, pdev->name, sfctemp);
325         if (ret)
326                 return dev_err_probe(dev, ret, "error requesting irq\n");
327
328         ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
329         if (ret)
330                 return ret;
331
332         ret = sfctemp_enable(sfctemp);
333         if (ret)
334                 return dev_err_probe(dev, ret, "error enabling temperature sensor: %d\n", ret);
335
336         hwmon_dev = devm_hwmon_device_register_with_info(dev, pdev->name, sfctemp,
337                                                          &sfctemp_chip_info, NULL);
338
339         pm_runtime_enable(hwmon_dev);
340         pm_runtime_enable(dev);
341
342         sfctemp_disable(sfctemp);
343
344         return PTR_ERR_OR_ZERO(hwmon_dev);
345 }
346
347 #ifdef CONFIG_PM
348
349 static int starfive_temp_suspend(struct device *dev)
350 {
351         struct sfctemp *sfctemp = dev_get_drvdata(dev);
352
353         dev_dbg(dev, "starfive temp runtime suspend");
354
355         return sfctemp_disable(sfctemp);
356 }
357
358 static int starfive_temp_resume(struct device *dev)
359 {
360         struct sfctemp *sfctemp = dev_get_drvdata(dev);
361
362         dev_dbg(dev, "starfive temp runtime resume");
363
364         return sfctemp_enable(sfctemp);
365 }
366 #endif /* CONFIG_PM */
367
368 static const struct dev_pm_ops sfctemp_dev_pm_ops = {
369         SET_RUNTIME_PM_OPS(starfive_temp_suspend, starfive_temp_resume, NULL)
370         SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
371 };
372
373 static const struct of_device_id sfctemp_of_match[] = {
374         { .compatible = "starfive,jh7100-temp" },
375         { .compatible = "starfive,jh7110-temp" },
376         { /* sentinel */ }
377 };
378 MODULE_DEVICE_TABLE(of, sfctemp_of_match);
379
380 static struct platform_driver sfctemp_driver = {
381         .probe  = sfctemp_probe,
382         .driver = {
383                 .name = "sfctemp",
384                 .of_match_table = sfctemp_of_match,
385                 .pm   = &sfctemp_dev_pm_ops,
386         },
387 };
388 module_platform_driver(sfctemp_driver);
389
390 MODULE_AUTHOR("Emil Renner Berthing");
391 MODULE_DESCRIPTION("StarFive JH7100 temperature sensor driver");
392 MODULE_LICENSE("GPL");