Merge branch 'develop-3.10-next' of ssh://10.10.10.29/rk/kernel into develop-3.10...
[firefly-linux-kernel-4.4.55.git] / drivers / hwmon / rockchip_tsadc.c
1 /*
2  * Copyright (C) ST-Ericsson 2010 - 2013
3  * Author: Martin Persson <martin.persson@stericsson.com>
4  *         Hongbo Zhang <hongbo.zhang@linaro.org>
5  * License Terms: GNU General Public License v2
6  *
7  * When the AB8500 thermal warning temperature is reached (threshold cannot
8  * be changed by SW), an interrupt is set, and if no further action is taken
9  * within a certain time frame, pm_power off will be called.
10  *
11  * When AB8500 thermal shutdown temperature is reached a hardware shutdown of
12  * the AB8500 will occur.
13  */
14
15  #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/device.h>
19 #include <linux/platform_device.h>
20 #include <linux/err.h>
21 #include <linux/clk.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/io.h>
25 #include <linux/delay.h>
26 #include <linux/slab.h>
27 #include <linux/workqueue.h>
28 #include <linux/ioport.h>
29
30 #include <linux/err.h>
31 #include <linux/hwmon.h>
32 #include <linux/hwmon-sysfs.h>
33 #include <linux/module.h>
34 #include <linux/slab.h>
35 #include <linux/sysfs.h>
36
37 #include <linux/timer.h>
38 #include <linux/completion.h>
39 #include <linux/of_irq.h>
40 #include <linux/regulator/consumer.h>
41 #include <linux/of_platform.h>
42 #include <linux/of.h>
43 #include <linux/of_device.h>
44 #include "hwmon-rockchip.h"
45
46
47 #define DEFAULT_POWER_OFF_DELAY (HZ * 10)
48 /* Number of monitored sensors should not greater than NUM_SENSORS */
49 #define NUM_MONITORED_SENSORS   4
50
51 #define TSADC_USER_CON  0x00
52 #define TSADC_AUTO_CON  0x04
53
54 #define TSADC_CTRL_CH(ch)       ((ch) << 0)
55 #define TSADC_CTRL_POWER_UP     (1 << 3)
56 #define TSADC_CTRL_START        (1 << 4)
57
58 #define TSADC_STAS_BUSY         (1 << 12)
59 #define TSADC_STAS_BUSY_MASK    (1 << 12)
60 #define TSADC_AUTO_STAS_BUSY            (1 << 16)
61 #define TSADC_AUTO_STAS_BUSY_MASK       (1 << 16)
62 #define TSADC_SAMPLE_DLY_SEL  (1 << 17)
63 #define TSADC_SAMPLE_DLY_SEL_MASK  (1 << 17)
64
65 #define TSADC_INT_EN  0x08
66 #define TSADC_INT_PD  0x0c
67
68 #define TSADC_DATA0  0x20
69 #define TSADC_DATA1  0x24
70 #define TSADC_DATA2  0x28
71 #define TSADC_DATA3  0x2c
72 #define TSADC_DATA_MASK         0xfff
73
74 #define TSADC_COMP0_INT  0x30
75 #define TSADC_COMP1_INT  0x34
76 #define TSADC_COMP2_INT  0x38
77 #define TSADC_COMP3_INT  0x3c
78
79 #define TSADC_COMP0_SHUT  0x40
80 #define TSADC_COMP1_SHUT  0x44
81 #define TSADC_COMP2_SHUT  0x48
82 #define TSADC_COMP3_SHUT  0x4c
83
84 #define TSADC_HIGHT_INT_DEBOUNCE  0x60
85 #define TSADC_HIGHT_TSHUT_DEBOUNCE  0x64
86 #define TSADC_HIGHT_INT_DEBOUNCE_TIME 0x0a
87 #define TSADC_HIGHT_TSHUT_DEBOUNCE_TIME 0x0a
88
89 #define TSADC_AUTO_PERIOD  0x68
90 #define TSADC_AUTO_PERIOD_HT  0x6c
91 #define TSADC_AUTO_PERIOD_TIME  0x03e8
92 #define TSADC_AUTO_PERIOD_HT_TIME  0x64
93
94 #define TSADC_AUTO_EVENT_NAME           "tsadc"
95
96 #define TSADC_COMP_INT_DATA             80
97 #define TSADC_COMP_INT_DATA_MASK                0xfff
98 #define TSADC_COMP_SHUT_DATA_MASK               0xfff
99 #define TSADC_TEMP_INT_EN 0
100 #define TSADC_TEMP_SHUT_EN 1
101 static int tsadc_ht_temp;
102 static int tsadc_ht_reset_cru;
103 static int tsadc_ht_pull_gpio;
104
105 struct tsadc_port {
106         struct pinctrl          *pctl;
107         struct pinctrl_state    *pins_default;
108         struct pinctrl_state    *pins_tsadc_int;
109 };
110
111 struct rockchip_tsadc_temp {
112         struct delayed_work power_off_work;
113         struct rockchip_temp *rockchip_data;
114         void __iomem            *regs;
115         struct clk              *clk;
116         struct clk              *pclk;
117         int irq;
118         struct resource         *ioarea;
119         struct tsadc_host               *tsadc;
120         struct work_struct      auto_ht_irq_work;
121         struct workqueue_struct  *workqueue;
122         struct workqueue_struct  *tsadc_workqueue;
123 };
124 struct tsadc_table
125 {
126         int code;
127         int temp;
128 };
129
130 static const struct tsadc_table table[] =
131 {
132         {TSADC_DATA_MASK, -40},
133
134         {3800, -40},
135         {3792, -35},
136         {3783, -30},
137         {3774, -25},
138         {3765, -20},
139         {3756, -15},
140         {3747, -10},
141         {3737, -5},
142         {3728, 0},
143         {3718, 5},
144
145         {3708, 10},
146         {3698, 15},
147         {3688, 20},
148         {3678, 25},
149         {3667, 30},
150         {3656, 35},
151         {3645, 40},
152         {3634, 45},
153         {3623, 50},
154         {3611, 55},
155
156         {3600, 60},
157         {3588, 65},
158         {3575, 70},
159         {3563, 75},
160         {3550, 80},
161         {3537, 85},
162         {3524, 90},
163         {3510, 95},
164         {3496, 100},
165         {3482, 105},
166
167         {3467, 110},
168         {3452, 115},
169         {3437, 120},
170         {3421, 125},
171
172         {0, 125},
173 };
174
175 static struct rockchip_tsadc_temp *g_dev;
176
177 static DEFINE_MUTEX(tsadc_mutex);
178
179 static u32 tsadc_readl(u32 offset)
180 {
181         return readl_relaxed(g_dev->regs + offset);
182 }
183
184 static void tsadc_writel(u32 val, u32 offset)
185 {
186         writel_relaxed(val, g_dev->regs + offset);
187 }
188
189 void rockchip_tsadc_auto_ht_work(struct work_struct *work)
190 {
191         int ret,val;
192
193 //      printk("%s,line=%d\n", __func__,__LINE__);
194
195         mutex_lock(&tsadc_mutex);
196
197         val = tsadc_readl(TSADC_INT_PD);
198         tsadc_writel(val &(~ (1 <<8) ), TSADC_INT_PD);
199         ret = tsadc_readl(TSADC_INT_PD);
200         tsadc_writel(ret | 0xff, TSADC_INT_PD);       //clr irq status
201         if ((val & 0x0f) != 0){
202                 printk("rockchip tsadc is over temp . %s,line=%d\n", __func__,__LINE__);
203                 pm_power_off();                                 //power_off
204         }
205         mutex_unlock(&tsadc_mutex);
206 }
207
208 static irqreturn_t rockchip_tsadc_auto_ht_interrupt(int irq, void *data)
209 {
210         struct rockchip_tsadc_temp *dev = data;
211
212         printk("%s,line=%d\n", __func__,__LINE__);
213         
214         queue_work(dev->workqueue, &dev->auto_ht_irq_work);
215         
216         return IRQ_HANDLED;
217 }
218
219 static void rockchip_tsadc_set_cmpn_int_vale( int chn, int temp)
220 {
221         u32 code = 0;
222         int i;
223
224         for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
225                 if (temp <= table[i].temp && temp > table[i -1].temp) {
226                         code = table[i].code;
227                 }
228         }
229         tsadc_writel((code & TSADC_COMP_INT_DATA_MASK), (TSADC_COMP0_INT + chn*4));
230
231 }
232
233 static void rockchip_tsadc_set_cmpn_shut_vale( int chn, int temp)
234 {
235         u32 code=0;
236         int i;
237
238         for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
239                 if (temp <= table[i].temp && temp > table[i -1].temp) {
240                         code = table[i].code;
241                 }
242         }
243
244         tsadc_writel((code & TSADC_COMP_SHUT_DATA_MASK), (TSADC_COMP0_SHUT + chn*4));
245 }
246
247 static void rockchip_tsadc_set_auto_int_en( int chn, int ht_int_en,int tshut_en)
248 {
249         u32 ret;
250         tsadc_writel(0, TSADC_INT_EN);
251         if (ht_int_en){
252                 ret = tsadc_readl(TSADC_INT_EN);
253                 tsadc_writel( ret | (1 << chn), TSADC_INT_EN);
254         }
255         if (tshut_en){
256                 ret = tsadc_readl(TSADC_INT_EN);
257                 if (tsadc_ht_pull_gpio)
258                         tsadc_writel(ret | (0xf << (chn + 4)), TSADC_INT_EN);
259                 else if (tsadc_ht_reset_cru)
260                         tsadc_writel(ret | (0xf << (chn + 8)), TSADC_INT_EN);
261         }       
262
263 }
264 static void rockchip_tsadc_auto_mode_set(int chn, int int_temp,
265         int shut_temp, int int_en, int shut_en)
266 {
267         u32 ret;
268         
269         if (!g_dev || chn > 4)
270                 return;
271         
272         mutex_lock(&tsadc_mutex);
273         
274         clk_enable(g_dev->pclk);
275         clk_enable(g_dev->clk);
276         
277         msleep(10);
278         tsadc_writel(0, TSADC_AUTO_CON);
279         tsadc_writel(1 << (4+chn), TSADC_AUTO_CON);
280         msleep(10);
281         if ((tsadc_readl(TSADC_AUTO_CON) & TSADC_AUTO_STAS_BUSY_MASK) != TSADC_AUTO_STAS_BUSY) {
282                 rockchip_tsadc_set_cmpn_int_vale(chn,int_temp);
283                 rockchip_tsadc_set_cmpn_shut_vale(chn,shut_temp),
284
285                 tsadc_writel(TSADC_AUTO_PERIOD_TIME, TSADC_AUTO_PERIOD);
286                 tsadc_writel(TSADC_AUTO_PERIOD_HT_TIME, TSADC_AUTO_PERIOD_HT);
287
288                 tsadc_writel(TSADC_HIGHT_INT_DEBOUNCE_TIME,
289                         TSADC_HIGHT_INT_DEBOUNCE);
290                 tsadc_writel(TSADC_HIGHT_TSHUT_DEBOUNCE_TIME,
291                         TSADC_HIGHT_TSHUT_DEBOUNCE);
292                 
293                 rockchip_tsadc_set_auto_int_en(chn,int_en,shut_en);     
294         }
295
296         msleep(10);
297
298         ret = tsadc_readl(TSADC_AUTO_CON);
299         tsadc_writel(ret | (1 <<0) , TSADC_AUTO_CON);
300         
301         mutex_unlock(&tsadc_mutex);
302                 
303 }
304
305 int rockchip_tsadc_set_auto_temp(int chn)
306 {
307         rockchip_tsadc_auto_mode_set(chn, TSADC_COMP_INT_DATA,
308                 tsadc_ht_temp, TSADC_TEMP_INT_EN, TSADC_TEMP_SHUT_EN);
309         return 0;
310 }
311 EXPORT_SYMBOL(rockchip_tsadc_set_auto_temp);
312
313 static void rockchip_tsadc_get(int chn, int *temp, int *code)
314 {
315         int i;
316         *temp = 0;
317         *code = 0;
318
319         if (!g_dev || chn > 4){
320                 *temp = 150;
321                 return ;
322         }
323 #if 0
324         mutex_lock(&tsadc_mutex);
325
326         clk_enable(g_dev->pclk);
327         clk_enable(g_dev->clk);
328
329         msleep(10);
330         tsadc_writel(0, TSADC_USER_CON);
331         tsadc_writel(TSADC_CTRL_POWER_UP | TSADC_CTRL_CH(chn), TSADC_USER_CON);
332         msleep(20);
333         if ((tsadc_readl(TSADC_USER_CON) & TSADC_STAS_BUSY_MASK) != TSADC_STAS_BUSY) {
334                 *code = tsadc_readl((TSADC_DATA0 + chn*4)) & TSADC_DATA_MASK;
335                 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
336                         if ((*code) <= table[i].code && (*code) > table[i + 1].code) {
337                                 *temp = table[i].temp + (table[i + 1].temp - table[i].temp) * (table[i].code - (*code)) / (table[i].code - table[i + 1].code);
338                         }
339                 }
340         }
341         
342         tsadc_writel(0, TSADC_USER_CON);
343
344         clk_disable(g_dev->clk);
345         clk_disable(g_dev->pclk);
346
347         mutex_unlock(&tsadc_mutex);
348 #else
349         *code = tsadc_readl((TSADC_DATA0 + chn*4)) & TSADC_DATA_MASK;
350         for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
351                 if ((*code) <= table[i].code && (*code) > table[i + 1].code)
352                         *temp = table[i].temp + (table[i + 1].temp
353                         - table[i].temp) * (table[i].code - (*code))
354                         / (table[i].code - table[i + 1].code);
355         }
356 #endif
357 }
358
359  int rockchip_tsadc_get_temp(int chn)
360 {
361         int temp, code;
362         
363         rockchip_tsadc_get(chn, &temp, &code);
364
365         return temp;
366 }
367 EXPORT_SYMBOL(rockchip_tsadc_get_temp);
368
369 static ssize_t rockchip_show_name(struct device *dev,
370                 struct device_attribute *devattr, char *buf)
371 {
372         return sprintf(buf, "rockchip-tsadc\n");
373 }
374
375 static ssize_t rockchip_show_label(struct device *dev,
376                 struct device_attribute *devattr, char *buf)
377 {
378         char *label;
379         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
380         int index = attr->index;
381
382         switch (index) {
383         case 0:
384                 label = "tsadc0";
385                 break;
386         case 1:
387                 label = "tsadc1";
388                 break;
389         case 2:
390                 label = "tsadc2";
391                 break;
392         case 3:
393                 label = "tsadc3";
394                 break;
395         default:
396                 return -EINVAL;
397         }
398
399         return sprintf(buf, "%s\n", label);
400 }
401
402 int rockchip_hwmon_init(struct rockchip_temp *data)
403 {
404         struct rockchip_tsadc_temp *rockchip_tsadc_data;
405         struct resource *res;
406         struct device_node *np = data->pdev->dev.of_node;
407         int ret,irq;
408         u32 rate;
409         struct tsadc_port *uap;
410         
411         rockchip_tsadc_data = devm_kzalloc(&data->pdev->dev, sizeof(*rockchip_tsadc_data),
412                 GFP_KERNEL);
413         if (!rockchip_tsadc_data)
414                 return -ENOMEM;
415
416         res = platform_get_resource(data->pdev, IORESOURCE_MEM, 0);
417         rockchip_tsadc_data->regs = devm_request_and_ioremap(&data->pdev->dev, res);
418         if (!rockchip_tsadc_data->regs) {
419                 dev_err(&data->pdev->dev, "cannot map IO\n");
420                 return -ENXIO;
421         } 
422
423         //irq request   
424         irq = platform_get_irq(data->pdev, 0);
425         if (irq < 0) {
426                 dev_err(&data->pdev->dev, "no irq resource?\n");
427                 return -EPERM;
428         }
429         rockchip_tsadc_data->irq = irq;
430         ret = request_threaded_irq(rockchip_tsadc_data->irq, NULL, rockchip_tsadc_auto_ht_interrupt, IRQF_ONESHOT, TSADC_AUTO_EVENT_NAME, rockchip_tsadc_data);
431         if (ret < 0) {
432                 dev_err(&data->pdev->dev, "failed to attach tsadc irq\n");
433                 return -EPERM;
434         }       
435
436         rockchip_tsadc_data->workqueue = create_singlethread_workqueue("rockchip_tsadc");
437         INIT_WORK(&rockchip_tsadc_data->auto_ht_irq_work, rockchip_tsadc_auto_ht_work);
438         
439         //clk enable
440         rockchip_tsadc_data->clk = devm_clk_get(&data->pdev->dev, "tsadc");
441         if (IS_ERR(rockchip_tsadc_data->clk)) {
442             dev_err(&data->pdev->dev, "failed to get tsadc clock\n");
443             ret = PTR_ERR(rockchip_tsadc_data->clk);
444             return -EPERM;
445         }
446
447         if(of_property_read_u32(np, "clock-frequency", &rate)) {
448           dev_err(&data->pdev->dev, "Missing clock-frequency property in the DT.\n");
449           return -EPERM;
450         }
451
452         ret = clk_set_rate(rockchip_tsadc_data->clk, rate);
453             if(ret < 0) {
454             dev_err(&data->pdev->dev, "failed to set adc clk\n");
455             return -EPERM;
456         }
457         clk_prepare_enable(rockchip_tsadc_data->clk);
458
459         rockchip_tsadc_data->pclk = devm_clk_get(&data->pdev->dev, "pclk_tsadc");
460         if (IS_ERR(rockchip_tsadc_data->pclk)) {
461             dev_err(&data->pdev->dev, "failed to get tsadc pclk\n");
462             ret = PTR_ERR(rockchip_tsadc_data->pclk);
463             return -EPERM;
464         }
465         clk_prepare_enable(rockchip_tsadc_data->pclk);
466
467         platform_set_drvdata(data->pdev, rockchip_tsadc_data);
468         g_dev = rockchip_tsadc_data;
469         data->plat_data = rockchip_tsadc_data;
470
471         ret = tsadc_readl(TSADC_AUTO_CON);
472         tsadc_writel(ret | (1 << 8) , TSADC_AUTO_CON);/*gpio0_b2 = 0 shutdown*/
473
474         if (of_property_read_u32(np, "tsadc-ht-temp",
475                 &tsadc_ht_temp)) {
476                 dev_err(&data->pdev->dev, "Missing  tsadc_ht_temp in the DT.\n");
477                 return -EPERM;
478         }
479         if (of_property_read_u32(np, "tsadc-ht-reset-cru",
480                 &tsadc_ht_reset_cru)) {
481                 dev_err(&data->pdev->dev, "Missing tsadc_ht_reset_cru in the DT.\n");
482                 return -EPERM;
483         }
484         if (of_property_read_u32(np, "tsadc-ht-pull-gpio",
485                 &tsadc_ht_pull_gpio)) {
486                 dev_err(&data->pdev->dev, "Missing tsadc_ht_pull_gpio in the DT.\n");
487                 return -EPERM;
488         }
489
490         uap = devm_kzalloc(&data->pdev->dev, sizeof(struct tsadc_port),
491                            GFP_KERNEL);
492         if (uap == NULL)
493                 dev_err(&data->pdev->dev,
494                 "uap is not set %s,line=%d\n", __func__, __LINE__);
495         uap->pctl = devm_pinctrl_get(&data->pdev->dev);
496         uap->pins_default = pinctrl_lookup_state(uap->pctl, "default");
497         uap->pins_tsadc_int = pinctrl_lookup_state(uap->pctl, "tsadc_int");
498         pinctrl_select_state(uap->pctl, uap->pins_tsadc_int);
499
500         rockchip_tsadc_set_auto_temp(1);
501
502         data->monitored_sensors = NUM_MONITORED_SENSORS;
503         data->ops.read_sensor = rockchip_tsadc_get_temp;
504         data->ops.show_name = rockchip_show_name;
505         data->ops.show_label = rockchip_show_label;
506         data->ops.is_visible = NULL;
507
508         dev_info(&data->pdev->dev, "initialized\n");
509         return 0;
510 }
511 EXPORT_SYMBOL(rockchip_hwmon_init);
512
513 MODULE_LICENSE("GPL");
514 MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
515 MODULE_DESCRIPTION("Driver for TSADC");