ARM64: DTS: Add rk3399-firefly uart4 device, node as /dev/ttyS1
[firefly-linux-kernel-4.4.55.git] / tsadc.c
1 /*
2  * Copyright (C) 2012 ROCKCHIP, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License.
7 */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/device.h>
13 #include <linux/platform_device.h>
14 #include <linux/err.h>
15 #include <linux/clk.h>
16 #include <linux/interrupt.h>
17 #include <linux/io.h>
18 #include <linux/delay.h>
19 #include <linux/slab.h>
20
21 #define TSADC_DATA              0x00
22 #define TSADC_DATA_MASK         0xfff
23
24 #define TSADC_STAS              0x04
25 #define TSADC_STAS_BUSY         (1 << 0)
26 #define TSADC_STAS_BUSY_MASK    (1 << 0)
27
28 #define TSADC_CTRL              0x08
29 #define TSADC_CTRL_CH(ch)       ((ch) << 0)
30 #define TSADC_CTRL_POWER_UP     (1 << 3)
31 #define TSADC_CTRL_START        (1 << 4)
32 #define TSADC_CTRL_IRQ_ENABLE   (1 << 5)
33 #define TSADC_CTRL_IRQ_STATUS   (1 << 6)
34
35 #define TSADC_DLY_PU_SOC        0x0C
36
37 #define TSADC_CLK_RATE          50000 /* 50KHz */
38
39 struct tsadc_table
40 {
41         int code;
42         int temp;
43 };
44
45 static const struct tsadc_table table[] =
46 {
47         {TSADC_DATA_MASK, -40},
48
49         {3800, -40},
50         {3792, -35},
51         {3783, -30},
52         {3774, -25},
53         {3765, -20},
54         {3756, -15},
55         {3747, -10},
56         {3737, -5},
57         {3728, 0},
58         {3718, 5},
59
60         {3708, 10},
61         {3698, 15},
62         {3688, 20},
63         {3678, 25},
64         {3667, 30},
65         {3656, 35},
66         {3645, 40},
67         {3634, 45},
68         {3623, 50},
69         {3611, 55},
70
71         {3600, 60},
72         {3588, 65},
73         {3575, 70},
74         {3563, 75},
75         {3550, 80},
76         {3537, 85},
77         {3524, 90},
78         {3510, 95},
79         {3496, 100},
80         {3482, 105},
81
82         {3467, 110},
83         {3452, 115},
84         {3437, 120},
85         {3421, 125},
86
87         {0, 125},
88 };
89
90 struct rk30_tsadc_device {
91         void __iomem            *regs;
92         struct clk              *clk;
93         struct clk              *pclk;
94         struct resource         *ioarea;
95 };
96
97 static struct rk30_tsadc_device *g_dev;
98
99 static u32 tsadc_readl(u32 offset)
100 {
101         return readl_relaxed(g_dev->regs + offset);
102 }
103
104 static void tsadc_writel(u32 val, u32 offset)
105 {
106         writel_relaxed(val, g_dev->regs + offset);
107 }
108
109 static DEFINE_MUTEX(tsadc_mutex);
110 static void rk30_tsadc_get(unsigned int chn, int *temp, int *code)
111 {
112         *temp = 0;
113         *code = 0;
114
115         if (!g_dev || chn > 1)
116                 return;
117
118         mutex_lock(&tsadc_mutex);
119
120         clk_enable(g_dev->pclk);
121         clk_enable(g_dev->clk);
122
123         msleep(10);
124         tsadc_writel(0, TSADC_CTRL);
125         tsadc_writel(TSADC_CTRL_POWER_UP | TSADC_CTRL_CH(chn), TSADC_CTRL);
126         msleep(10);
127         if ((tsadc_readl(TSADC_STAS) & TSADC_STAS_BUSY_MASK) != TSADC_STAS_BUSY) {
128                 int i;
129                 *code = tsadc_readl(TSADC_DATA) & TSADC_DATA_MASK;
130                 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
131                         if ((*code) <= table[i].code && (*code) > table[i + 1].code) {
132                                 *temp = table[i].temp + (table[i + 1].temp - table[i].temp) * (table[i].code - (*code)) / (table[i].code - table[i + 1].code);
133                         }
134                 }
135         }
136         tsadc_writel(0, TSADC_CTRL);
137
138         clk_disable(g_dev->clk);
139         clk_disable(g_dev->pclk);
140
141         mutex_unlock(&tsadc_mutex);
142 }
143
144 int rk30_tsadc_get_temp(unsigned int chn)
145 {
146         int temp, code;
147
148         rk30_tsadc_get(chn, &temp, &code);
149         return temp;
150 }
151 EXPORT_SYMBOL(rk30_tsadc_get_temp);
152
153 static int rk30_tsadc_get_temp0(char *buffer, struct kernel_param *kp)
154 {
155         int temp, code;
156         rk30_tsadc_get(0, &temp, &code);
157         return sprintf(buffer, "temp: %d code: %d", temp, code);
158 }
159 module_param_call(temp0, NULL, rk30_tsadc_get_temp0, NULL, S_IRUGO);
160
161 static int rk30_tsadc_get_temp1(char *buffer, struct kernel_param *kp)
162 {
163         int temp, code;
164         rk30_tsadc_get(1, &temp, &code);
165         return sprintf(buffer, "temp: %d code: %d", temp, code);
166 }
167 module_param_call(temp1, NULL, rk30_tsadc_get_temp1, NULL, S_IRUGO);
168
169 static int __init rk30_tsadc_probe(struct platform_device *pdev)
170 {
171         struct rk30_tsadc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
172         struct resource *res;
173         int ret;
174
175         if (!dev) {
176                 dev_err(&pdev->dev, "failed to alloc mem\n");
177                 return -ENOMEM;
178         }
179
180         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
181         if (!res) {
182                 dev_err(&pdev->dev, "cannot find IO resource\n");
183                 ret = -ENOENT;
184                 goto err1;
185         }
186
187         dev->ioarea = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name);
188         if (!dev->ioarea) {
189                 dev_err(&pdev->dev, "cannot request IO\n");
190                 ret = -ENXIO;
191                 goto err1;
192         }
193
194         dev->regs = ioremap(res->start, (res->end - res->start) + 1);
195         if (!dev->regs) {
196                 dev_err(&pdev->dev, "cannot map IO\n");
197                 ret = -ENXIO;
198                 goto err2;
199         }
200
201         dev->clk = clk_get(NULL, "tsadc");
202         if (IS_ERR(dev->clk)) {
203                 dev_err(&pdev->dev, "failed to get clk\n");
204                 ret = PTR_ERR(dev->clk);
205                 goto err3;
206         }
207
208         ret = clk_set_rate(dev->clk, TSADC_CLK_RATE);
209         if (ret < 0) {
210                 dev_err(&pdev->dev, "failed to set clk\n");
211                 goto err4;
212         }
213
214         dev->pclk = clk_get(NULL, "pclk_tsadc");
215         if (IS_ERR(dev->pclk)) {
216                 dev_err(&pdev->dev, "failed to get pclk\n");
217                 ret = PTR_ERR(dev->clk);
218                 goto err4;
219         }
220
221         platform_set_drvdata(pdev, dev);
222         g_dev = dev;
223
224         dev_info(&pdev->dev, "initialized\n");
225
226         return 0;
227
228 err4:
229         clk_put(dev->clk);
230 err3:
231         iounmap(dev->regs);
232 err2:
233         release_resource(dev->ioarea);
234 err1:
235         kfree(dev);
236         return ret;
237 }
238
239 static struct platform_driver rk30_tsadc_driver = {
240         .driver         = {
241                 .name   = "rk30-tsadc",
242                 .owner  = THIS_MODULE,
243         },
244 };
245
246 static int __init rk30_tsadc_init(void)
247 {
248         return platform_driver_probe(&rk30_tsadc_driver, rk30_tsadc_probe);
249 }
250 rootfs_initcall(rk30_tsadc_init);
251
252 MODULE_DESCRIPTION("Driver for TSADC");
253 MODULE_AUTHOR("lw, lw@rock-chips.com");
254 MODULE_LICENSE("GPL");