3 #include <linux/module.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"
17 /*sys/module/rk_pwm_remotectl/parameters,
18 modify code_print to change the value*/
20 static int rk_remote_print_code;
21 module_param_named(code_print, rk_remote_print_code, int, 0644);
22 #define DBG_CODE(args...) \
24 if (rk_remote_print_code) { \
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...) \
33 if (rk_remote_pwm_dbg_level) { \
39 struct rkxx_remote_key_table {
44 struct rkxx_remotectl_button {
47 struct rkxx_remote_key_table *key_table;
50 struct rkxx_remotectl_drvdata {
64 struct input_dev *input;
65 struct timer_list timer;
66 struct tasklet_struct remote_tasklet;
67 struct wake_lock remotectl_wake_lock;
71 static struct rkxx_remote_key_table remote_key_table_meiyu_4040[] = {
80 {0xe3, KEY_VOLUMEDOWN},
101 /*zoom outdisplay switch*/
106 static struct rkxx_remote_key_table remote_key_table_sunchip_ff00[] = {
115 {0xeb, KEY_VOLUMEDOWN},
116 {0xef, KEY_VOLUMEUP},
120 {0xa9, KEY_VOLUMEDOWN},
121 {0xa8, KEY_VOLUMEDOWN},
122 {0xe0, KEY_VOLUMEDOWN},
123 {0xa5, KEY_VOLUMEDOWN},
128 {0xed, KEY_VOLUMEDOWN},
130 {0xb3, KEY_VOLUMEDOWN},
131 {0xf1, KEY_VOLUMEDOWN},
132 {0xf2, KEY_VOLUMEDOWN},
134 {0xb4, KEY_VOLUMEDOWN},
140 static struct rkxx_remote_key_table remote_key_table_0x1dcc[] = {
148 {0xf1, KEY_VOLUMEUP},
149 {0xfd, KEY_VOLUMEDOWN},
167 {0xb5, KEY_BACKSPACE},
171 static struct rkxx_remotectl_button remotectl_button[] = {
175 .key_table = &remote_key_table_sunchip_ff00[0],
180 .key_table = &remote_key_table_meiyu_4040[0],
185 .key_table = &remote_key_table_0x1dcc[0],
190 static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata)
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)) {
206 static int remotectl_keycode_lookup(struct rkxx_remotectl_drvdata *ddata)
209 unsigned char keydata = (unsigned char)((ddata->scandata >> 8) & 0xff);
211 for (i = 0; i < remotectl_button[ddata->keynum].nbuttons; i++) {
212 if (remotectl_button[ddata->keynum].key_table[i].scancode ==
215 remotectl_button[ddata->keynum].key_table[i].keycode;
223 static void rk_pwm_remotectl_do_something(unsigned long data)
225 struct rkxx_remotectl_drvdata *ddata;
227 ddata = (struct rkxx_remotectl_drvdata *)data;
228 switch (ddata->state) {
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)) {
239 ddata->state = RMC_USERCODE;
241 ddata->state = RMC_PRELOAD;
246 if ((RK_PWM_TIME_BIT1_MIN < ddata->period) &&
247 (ddata->period < RK_PWM_TIME_BIT1_MAX))
248 ddata->scandata |= (0x01 << 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;
257 ddata->state = RMC_PRELOAD;
263 if ((RK_PWM_TIME_BIT1_MIN < ddata->period) &&
264 (ddata->period < RK_PWM_TIME_BIT1_MAX))
265 ddata->scandata |= (0x01<<ddata->count);
267 if (ddata->count < 0x10)
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)) {
274 input_event(ddata->input, EV_KEY,
276 input_sync(ddata->input);
277 ddata->state = RMC_SEQUENCE;
279 ddata->state = RMC_PRELOAD;
282 ddata->state = RMC_PRELOAD;
287 DBG("S=%d\n", ddata->period);
288 if ((RK_PWM_TIME_RPT_MIN < ddata->period) &&
289 (ddata->period < RK_PWM_TIME_RPT_MAX)) {
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)) {
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)) {
301 mod_timer(&ddata->timer, jiffies
302 + msecs_to_jiffies(130));
305 input_event(ddata->input, EV_KEY,
307 input_sync(ddata->input);
308 ddata->state = RMC_PRELOAD;
318 static void rk_pwm_remotectl_timer(unsigned long _data)
320 struct rkxx_remotectl_drvdata *ddata;
322 ddata = (struct rkxx_remotectl_drvdata *)_data;
323 if (ddata->press != ddata->pre_press) {
324 ddata->pre_press = 0;
326 input_event(ddata->input, EV_KEY, ddata->keycode, 0);
327 input_sync(ddata->input);
329 ddata->state = RMC_PRELOAD;
333 static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id)
335 struct rkxx_remotectl_drvdata *ddata;
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);
344 tasklet_hi_schedule(&ddata->remote_tasklet);
345 DBG("hpr=0x%x\n", val);
347 val = readl_relaxed(ddata->base + PWM_REG_LPR);
348 DBG("lpr=0x%x\n", val);
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);
358 static int rk_pwm_remotectl_hw_init(struct rkxx_remotectl_drvdata *ddata)
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);
382 static int rk_pwm_probe(struct platform_device *pdev)
384 struct rkxx_remotectl_drvdata *ddata;
386 struct input_dev *input;
393 DBG(".. rk pwm remotectl v1.1 init\n");
394 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
396 dev_err(&pdev->dev, "no memory resources defined\n");
399 ddata = devm_kzalloc(&pdev->dev, sizeof(struct rkxx_remotectl_drvdata),
402 dev_err(&pdev->dev, "failed to allocate memory\n");
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");
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);
428 irq = platform_get_irq(pdev, 0);
430 dev_err(&pdev->dev, "cannot find IRQ\n");
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;
443 input_set_capability(input, type, remotectl_button[j].
444 key_table[i].keycode);
447 ret = input_register_device(input);
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);
455 dev_err(&pdev->dev, "cannot claim IRQ %d\n", irq);
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);
466 static int rk_pwm_remove(struct platform_device *pdev)
472 static const struct of_device_id rk_pwm_of_match[] = {
473 { .compatible = "rockchip,remotectl-pwm"},
477 MODULE_DEVICE_TABLE(of, rk_pwm_of_match);
479 static struct platform_driver rk_pwm_driver = {
481 .name = "remotectl-pwm",
482 .of_match_table = rk_pwm_of_match,
484 .probe = rk_pwm_probe,
485 .remove = rk_pwm_remove,
488 module_platform_driver(rk_pwm_driver);
490 MODULE_LICENSE("GPL");