Merge branch 'develop-3.10' of ssh://10.10.10.29/rk/kernel into my_wifi
[firefly-linux-kernel-4.4.55.git] / drivers / input / remotectl / rockchip_pwm_remotectl.c
1 #include <linux/clk.h>
2 #include <linux/io.h>
3 #include <linux/module.h>
4 #include <linux/of.h>
5 #include <linux/platform_device.h>
6 #include <linux/module.h>
7 #include <linux/init.h>
8 #include <linux/interrupt.h>
9 #include <linux/platform_device.h>
10 #include <linux/input.h>
11 #include <linux/workqueue.h>
12 #include <linux/wakelock.h>
13 #include "rockchip_pwm_remotectl.h"
14
15
16
17 /*sys/module/rk_pwm_remotectl/parameters,
18 modify code_print to change the value*/
19
20 static int rk_remote_print_code;
21 module_param_named(code_print, rk_remote_print_code, int, 0644);
22 #define DBG_CODE(args...) \
23         do { \
24                 if (rk_remote_print_code) { \
25                         pr_info(args); \
26                 } \
27         } while (0)
28
29 static int rk_remote_pwm_dbg_level;
30 module_param_named(dbg_level, rk_remote_pwm_dbg_level, int, 0644);
31 #define DBG(args...) \
32         do { \
33                 if (rk_remote_pwm_dbg_level) { \
34                         pr_info(args); \
35                 } \
36         } while (0)
37
38
39 struct rkxx_remote_key_table {
40         int scancode;
41         int keycode;
42 };
43
44 struct rkxx_remotectl_button {
45         int usercode;
46         int nbuttons;
47         struct rkxx_remote_key_table *key_table;
48 };
49
50 struct rkxx_remotectl_drvdata {
51         void __iomem *base;
52         int state;
53         int nbuttons;
54         int result;
55         int scandata;
56         int count;
57         int keynum;
58         int keycode;
59         int press;
60         int pre_press;
61         int period;
62         int irq;
63         int wakeup;
64         struct input_dev *input;
65         struct timer_list timer;
66         struct tasklet_struct remote_tasklet;
67         struct wake_lock remotectl_wake_lock;
68 };
69
70
71 static struct rkxx_remote_key_table remote_key_table_meiyu_4040[] = {
72         {0xf2, KEY_REPLY},
73         {0xba, KEY_BACK},
74         {0xf4, KEY_UP},
75         {0xf1, KEY_DOWN},
76         {0xef, KEY_LEFT},
77         {0xee, KEY_RIGHT},
78         {0xbd, KEY_HOME},
79         {0xea, KEY_VOLUMEUP},
80         {0xe3, KEY_VOLUMEDOWN},
81         {0xe2, KEY_SEARCH},
82         {0xb2, KEY_POWER},
83         {0xbc, KEY_MUTE},
84         {0xec, KEY_MENU},
85 /*lay pause*/
86         {0xbf, 0x190},
87 /*pre*/
88         {0xe0, 0x191},
89 /*next*/
90         {0xe1, 0x192},
91 /*pic,rorate left*/
92         {0xe9, 183},
93 /*rorate right*/
94         {0xe6, 248},
95 /*zoom out*/
96         {0xe8, 185},
97 /*zoom in*/
98         {0xe7, 186},
99 /*mouse switch*/
100         {0xb8, 388},
101 /*zoom outdisplay switch*/
102         {0xbe, 0x175},
103 };
104
105
106 static struct rkxx_remote_key_table remote_key_table_sunchip_ff00[] = {
107         {0xf9, KEY_HOME},
108         {0xbf, KEY_BACK},
109         {0xfb, KEY_MENU},
110         {0xaa, KEY_REPLY},
111         {0xb9, KEY_UP},
112         {0xe9, KEY_DOWN},
113         {0xb8, KEY_LEFT},
114         {0xea, KEY_RIGHT},
115         {0xeb, KEY_VOLUMEDOWN},
116         {0xef, KEY_VOLUMEUP},
117         {0xf7, KEY_MUTE},
118         {0xe7, KEY_POWER},
119         {0xfc, KEY_POWER},
120         {0xa9, KEY_VOLUMEDOWN},
121         {0xa8, KEY_VOLUMEDOWN},
122         {0xe0, KEY_VOLUMEDOWN},
123         {0xa5, KEY_VOLUMEDOWN},
124         {0xab, 183},
125         {0xb7, 388},
126         {0xf8, 184},
127         {0xaf, 185},
128         {0xed, KEY_VOLUMEDOWN},
129         {0xee, 186},
130         {0xb3, KEY_VOLUMEDOWN},
131         {0xf1, KEY_VOLUMEDOWN},
132         {0xf2, KEY_VOLUMEDOWN},
133         {0xf3, KEY_SEARCH},
134         {0xb4, KEY_VOLUMEDOWN},
135         {0xbe, KEY_SEARCH},
136 };
137
138
139
140 static struct rkxx_remote_key_table remote_key_table_0x1dcc[] = {
141         {0xee, KEY_REPLY},
142         {0xf0, KEY_BACK},
143         {0xf8, KEY_UP},
144         {0xbb, KEY_DOWN},
145         {0xef, KEY_LEFT},
146         {0xed, KEY_RIGHT},
147         {0xfc, KEY_HOME},
148         {0xf1, KEY_VOLUMEUP},
149         {0xfd, KEY_VOLUMEDOWN},
150         {0xb7, KEY_SEARCH},
151         {0xff, KEY_POWER},
152         {0xf3, KEY_MUTE},
153         {0xbf, KEY_MENU},
154         {0xf9, 0x191},
155         {0xf5, 0x192},
156         {0xb3, 388},
157         {0xbe, KEY_1},
158         {0xba, KEY_2},
159         {0xb2, KEY_3},
160         {0xbd, KEY_4},
161         {0xf9, KEY_5},
162         {0xb1, KEY_6},
163         {0xfc, KEY_7},
164         {0xf8, KEY_8},
165         {0xb0, KEY_9},
166         {0xb6, KEY_0},
167         {0xb5, KEY_BACKSPACE},
168 };
169
170
171 static struct rkxx_remotectl_button remotectl_button[] = {
172         {
173                 .usercode = 0xff00,
174                 .nbuttons =  29,
175                 .key_table = &remote_key_table_sunchip_ff00[0],
176         },
177         {
178                 .usercode = 0x4040,
179                 .nbuttons =  22,
180                 .key_table = &remote_key_table_meiyu_4040[0],
181         },
182         {
183                 .usercode = 0x1dcc,
184                 .nbuttons =  27,
185                 .key_table = &remote_key_table_0x1dcc[0],
186         },
187 };
188
189
190 static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata)
191 {
192         int i;
193         int num;
194
195         num =  sizeof(remotectl_button)/sizeof(struct rkxx_remotectl_button);
196         for (i = 0; i < num; i++) {
197                 if (remotectl_button[i].usercode == (ddata->scandata&0xFFFF)) {
198                         ddata->keynum = i;
199                         return 1;
200                 }
201         }
202         return 0;
203 }
204
205
206 static int remotectl_keycode_lookup(struct rkxx_remotectl_drvdata *ddata)
207 {
208         int i;
209         unsigned char keydata = (unsigned char)((ddata->scandata >> 8) & 0xff);
210
211         for (i = 0; i < remotectl_button[ddata->keynum].nbuttons; i++) {
212                 if (remotectl_button[ddata->keynum].key_table[i].scancode ==
213                     keydata) {
214                         ddata->keycode =
215                         remotectl_button[ddata->keynum].key_table[i].keycode;
216                         return 1;
217                 }
218         }
219         return 0;
220 }
221
222
223 static void rk_pwm_remotectl_do_something(unsigned long  data)
224 {
225         struct rkxx_remotectl_drvdata *ddata;
226
227         ddata = (struct rkxx_remotectl_drvdata *)data;
228         switch (ddata->state) {
229         case RMC_IDLE: {
230                 ;
231                 break;
232         }
233         case RMC_PRELOAD: {
234                 mod_timer(&ddata->timer, jiffies + msecs_to_jiffies(130));
235                 if ((RK_PWM_TIME_PRE_MIN < ddata->period) &&
236                     (ddata->period < RK_PWM_TIME_PRE_MAX)) {
237                         ddata->scandata = 0;
238                         ddata->count = 0;
239                         ddata->state = RMC_USERCODE;
240                 } else {
241                         ddata->state = RMC_PRELOAD;
242                 }
243                 break;
244         }
245         case RMC_USERCODE: {
246                 if ((RK_PWM_TIME_BIT1_MIN < ddata->period) &&
247                     (ddata->period < RK_PWM_TIME_BIT1_MAX))
248                         ddata->scandata |= (0x01 << ddata->count);
249                 ddata->count++;
250                 if (ddata->count == 0x10) {
251                         DBG_CODE("USERCODE=0x%x\n", ddata->scandata);
252                         if (remotectl_keybd_num_lookup(ddata)) {
253                                 ddata->state = RMC_GETDATA;
254                                 ddata->scandata = 0;
255                                 ddata->count = 0;
256                         } else {
257                                 ddata->state = RMC_PRELOAD;
258                         }
259                 }
260         }
261         break;
262         case RMC_GETDATA: {
263                 if ((RK_PWM_TIME_BIT1_MIN < ddata->period) &&
264                     (ddata->period < RK_PWM_TIME_BIT1_MAX))
265                         ddata->scandata |= (0x01<<ddata->count);
266                 ddata->count++;
267                 if (ddata->count < 0x10)
268                         return;
269                 DBG_CODE("RMC_GETDATA=%x\n", (ddata->scandata>>8));
270                 if ((ddata->scandata&0x0ff) ==
271                     ((~ddata->scandata >> 8) & 0x0ff)) {
272                         if (remotectl_keycode_lookup(ddata)) {
273                                 ddata->press = 1;
274                                 input_event(ddata->input, EV_KEY,
275                                             ddata->keycode, 1);
276                                 input_sync(ddata->input);
277                                 ddata->state = RMC_SEQUENCE;
278                         } else {
279                                 ddata->state = RMC_PRELOAD;
280                         }
281                 } else {
282                         ddata->state = RMC_PRELOAD;
283                 }
284         }
285         break;
286         case RMC_SEQUENCE:{
287                 DBG("S=%d\n", ddata->period);
288                 if ((RK_PWM_TIME_RPT_MIN < ddata->period) &&
289                     (ddata->period < RK_PWM_TIME_RPT_MAX)) {
290                         DBG("S1\n");
291                         mod_timer(&ddata->timer, jiffies
292                                   + msecs_to_jiffies(130));
293                 } else if ((RK_PWM_TIME_SEQ1_MIN < ddata->period) &&
294                            (ddata->period < RK_PWM_TIME_SEQ1_MAX)) {
295                         DBG("S2\n");
296                         mod_timer(&ddata->timer, jiffies
297                                   + msecs_to_jiffies(130));
298                 } else if ((RK_PWM_TIME_SEQ2_MIN < ddata->period) &&
299                           (ddata->period < RK_PWM_TIME_SEQ2_MAX)) {
300                         DBG("S3\n");
301                         mod_timer(&ddata->timer, jiffies
302                                   + msecs_to_jiffies(130));
303                 } else {
304                         DBG("S4\n");
305                         input_event(ddata->input, EV_KEY,
306                                     ddata->keycode, 0);
307                         input_sync(ddata->input);
308                         ddata->state = RMC_PRELOAD;
309                         ddata->press = 0;
310                 }
311         }
312         break;
313         default:
314         break;
315         }
316 }
317
318 static void rk_pwm_remotectl_timer(unsigned long _data)
319 {
320         struct rkxx_remotectl_drvdata *ddata;
321
322         ddata =  (struct rkxx_remotectl_drvdata *)_data;
323         if (ddata->press != ddata->pre_press) {
324                 ddata->pre_press = 0;
325                 ddata->press = 0;
326                 input_event(ddata->input, EV_KEY, ddata->keycode, 0);
327                 input_sync(ddata->input);
328         }
329         ddata->state = RMC_PRELOAD;
330 }
331
332
333 static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id)
334 {
335         struct rkxx_remotectl_drvdata *ddata;
336         int val;
337
338         ddata = (struct rkxx_remotectl_drvdata *)dev_id;
339         val = readl_relaxed(ddata->base + PWM_REG_INTSTS);
340         if (val&PWM_CH3_INT) {
341                 if ((val & PWM_CH3_POL) == 0) {
342                         val = readl_relaxed(ddata->base + PWM_REG_HPR);
343                         ddata->period = val;
344                         tasklet_hi_schedule(&ddata->remote_tasklet);
345                         DBG("hpr=0x%x\n", val);
346                 } else {
347                         val = readl_relaxed(ddata->base + PWM_REG_LPR);
348                         DBG("lpr=0x%x\n", val);
349                 }
350                 writel_relaxed(PWM_CH3_INT, ddata->base + PWM_REG_INTSTS);
351                 if (ddata->state == RMC_PRELOAD)
352                         wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
353                 return IRQ_HANDLED;
354         }
355         return IRQ_NONE;
356 }
357
358 static int rk_pwm_remotectl_hw_init(struct rkxx_remotectl_drvdata *ddata)
359 {
360         int val;
361
362         val = readl_relaxed(ddata->base + PWM_REG_CTRL);
363         val = (val & 0xFFFFFFFE) | PWM_DISABLE;
364         writel_relaxed(val, ddata->base + PWM_REG_CTRL);
365         val = readl_relaxed(ddata->base + PWM_REG_CTRL);
366         val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE;
367         writel_relaxed(val, ddata->base + PWM_REG_CTRL);
368         val = readl_relaxed(ddata->base + PWM_REG_CTRL);
369         val = (val & 0xFF008DFF) | 0x00646200;
370         writel_relaxed(val, ddata->base + PWM_REG_CTRL);
371         val = readl_relaxed(ddata->base + PWM_REG_INT_EN);
372         val = (val & 0xFFFFFFF7) | PWM_CH3_INT_ENABLE;
373         writel_relaxed(val, ddata->base + PWM_REG_INT_EN);
374         val = readl_relaxed(ddata->base + PWM_REG_CTRL);
375         val = (val & 0xFFFFFFFE) | PWM_ENABLE;
376         writel_relaxed(val, ddata->base + PWM_REG_CTRL);
377         return 0;
378 }
379
380
381
382 static int rk_pwm_probe(struct platform_device *pdev)
383 {
384         struct rkxx_remotectl_drvdata *ddata;
385         struct resource *r;
386         struct input_dev *input;
387         struct clk *clk;
388         int num;
389         int irq;
390         int ret;
391         int i, j;
392
393         DBG(".. rk pwm remotectl v1.1 init\n");
394         r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
395         if (!r) {
396                 dev_err(&pdev->dev, "no memory resources defined\n");
397                 return -ENODEV;
398         }
399         ddata = devm_kzalloc(&pdev->dev, sizeof(struct rkxx_remotectl_drvdata),
400                              GFP_KERNEL);
401         if (!ddata) {
402                 dev_err(&pdev->dev, "failed to allocate memory\n");
403                 return -ENOMEM;
404         }
405         ddata->state = RMC_PRELOAD;
406         ddata->base = devm_ioremap_resource(&pdev->dev, r);
407         if (IS_ERR(ddata->base))
408                 return PTR_ERR(ddata->base);
409         clk = devm_clk_get(&pdev->dev, "pclk_pwm");
410         if (IS_ERR(clk))
411                 return PTR_ERR(clk);
412         platform_set_drvdata(pdev, ddata);
413         input = input_allocate_device();
414         input->name = pdev->name;
415         input->phys = "gpio-keys/remotectl";
416         input->dev.parent = &pdev->dev;
417         input->id.bustype = BUS_HOST;
418         input->id.vendor = 0x0001;
419         input->id.product = 0x0001;
420         input->id.version = 0x0100;
421         ddata->input = input;
422         ddata->input = input;
423         wake_lock_init(&ddata->remotectl_wake_lock,
424                        WAKE_LOCK_SUSPEND, "rk29_pwm_remote");
425         ret = clk_prepare_enable(clk);
426         if (ret)
427                 return ret;
428         irq = platform_get_irq(pdev, 0);
429         if (ret < 0) {
430                 dev_err(&pdev->dev, "cannot find IRQ\n");
431                 return ret;
432         }
433         ddata->irq = irq;
434         ddata->wakeup = 1;
435         tasklet_init(&ddata->remote_tasklet, rk_pwm_remotectl_do_something,
436                      (unsigned long)ddata);
437         num =  sizeof(remotectl_button)/sizeof(struct rkxx_remotectl_button);
438         for (j = 0; j < num; j++) {
439                 DBG("remotectl probe j = 0x%x\n", j);
440                 for (i = 0; i < remotectl_button[j].nbuttons; i++) {
441                         unsigned int type = EV_KEY;
442
443                         input_set_capability(input, type, remotectl_button[j].
444                                              key_table[i].keycode);
445                 }
446         }
447         ret = input_register_device(input);
448         if (ret)
449                 pr_err("remotectl: register input device err, ret: %d\n", ret);
450         input_set_capability(input, EV_KEY, KEY_WAKEUP);
451         device_init_wakeup(&pdev->dev, 1);
452         ret = devm_request_irq(&pdev->dev, irq, rockchip_pwm_irq,
453                                0, "rk_pwm_irq", ddata);
454         if (ret) {
455                 dev_err(&pdev->dev, "cannot claim IRQ %d\n", irq);
456                 return ret;
457         }
458         enable_irq_wake(irq);
459         setup_timer(&ddata->timer, rk_pwm_remotectl_timer,
460                     (unsigned long)ddata);
461         mod_timer(&ddata->timer, jiffies + msecs_to_jiffies(1000));
462         rk_pwm_remotectl_hw_init(ddata);
463         return ret;
464 }
465
466 static int rk_pwm_remove(struct platform_device *pdev)
467 {
468         return 0;
469 }
470
471
472 static const struct of_device_id rk_pwm_of_match[] = {
473         { .compatible =  "rockchip,remotectl-pwm"},
474         { }
475 };
476
477 MODULE_DEVICE_TABLE(of, rk_pwm_of_match);
478
479 static struct platform_driver rk_pwm_driver = {
480         .driver = {
481                 .name = "remotectl-pwm",
482                 .of_match_table = rk_pwm_of_match,
483         },
484         .probe = rk_pwm_probe,
485         .remove = rk_pwm_remove,
486 };
487
488 module_platform_driver(rk_pwm_driver);
489
490 MODULE_LICENSE("GPL");