input: Add IR decode driver
authorZhangbin Tong <zebulun.tong@rock-chips.com>
Wed, 15 Jun 2016 03:07:58 +0000 (11:07 +0800)
committerZhangbin Tong <zebulun.tong@rock-chips.com>
Wed, 15 Jun 2016 06:46:49 +0000 (14:46 +0800)
Change-Id: I7e6f36b70fd1f5356ad64cad9a0b9f2aab18c2b1
Signed-off-by: Zhangbin Tong <zebulun.tong@rock-chips.com>
drivers/input/Kconfig
drivers/input/Makefile
drivers/input/remotectl/Kconfig [changed mode: 0755->0644]
drivers/input/remotectl/Makefile [changed mode: 0755->0644]
drivers/input/remotectl/rockchip_pwm_remotectl.c [changed mode: 0755->0644]
drivers/input/remotectl/rockchip_pwm_remotectl.h [changed mode: 0755->0644]

index 2557dcda7621a1dbe58ae54caef6bc85025207f3..d6ae5fb197cf7286b63a16691211472944c541d4 100644 (file)
@@ -212,6 +212,8 @@ source "drivers/input/tablet/Kconfig"
 
 source "drivers/input/touchscreen/Kconfig"
 
+source "drivers/input/remotectl/Kconfig"
+
 source "drivers/input/misc/Kconfig"
 
 endif
index 2a6d05ab9170fc6bce9f0f97de5e135e3d29706c..0dce1d8912424eac70ee20310d6c5c9f211d984c 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_MOUSE)     += mouse/
 obj-$(CONFIG_INPUT_JOYSTICK)   += joystick/
 obj-$(CONFIG_INPUT_TABLET)     += tablet/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)        += touchscreen/
+obj-$(CONFIG_ROCKCHIP_REMOTECTL)+= remotectl/
 obj-$(CONFIG_INPUT_MISC)       += misc/
 
 obj-$(CONFIG_INPUT_APMPOWER)   += apm-power.o
old mode 100755 (executable)
new mode 100644 (file)
index eb8f7bd..7879c6e
@@ -1,5 +1,5 @@
 #
-# Touchscreen driver configuration
+# Input remotectl driver configuration
 #
 menuconfig ROCKCHIP_REMOTECTL
        bool "rockchip remotectl"
@@ -8,10 +8,11 @@ menuconfig ROCKCHIP_REMOTECTL
          Say Y here, will suport rk remotectl.
          This option doesn't affect the kernel.
          If unsure, say Y.
-         
-if ROCKCHIP_REMOTECTL  
+
+if ROCKCHIP_REMOTECTL
 
 config ROCKCHIP_REMOTECTL_PWM
-    bool "rockchip remoctrl pwm capture"
+       bool "rockchip remoctrl pwm capture"
        default n
+
 endif
old mode 100755 (executable)
new mode 100644 (file)
index 3b6f4e2..f84b641
@@ -1,7 +1,7 @@
 #
-# Makefile for the touchscreen drivers.
+# Makefile for the input remotectl drivers.
 #
-# Each configuration option enables a list of files.
 
+# Each configuration option enables a list of files.
 
-obj-$(CONFIG_ROCKCHIP_REMOTECTL_PWM)      += rockchip_pwm_remotectl.o
+obj-$(CONFIG_ROCKCHIP_REMOTECTL_PWM)   += rockchip_pwm_remotectl.o
old mode 100755 (executable)
new mode 100644 (file)
index d474bed..831d46c
@@ -60,11 +60,14 @@ struct rkxx_remotectl_drvdata {
        int keycode;
        int press;
        int pre_press;
-       int period;
        int irq;
        int remote_pwm_id;
        int handle_cpu_id;
        int wakeup;
+       int clk_rate;
+       unsigned long period;
+       unsigned long temp_period;
+       int pwm_freq_nstime;
        struct input_dev *input;
        struct timer_list timer;
        struct tasklet_struct remote_tasklet;
@@ -73,7 +76,6 @@ struct rkxx_remotectl_drvdata {
 
 static struct rkxx_remotectl_button *remotectl_button;
 
-
 static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata)
 {
        int i;
@@ -242,7 +244,7 @@ static void rk_pwm_remotectl_do_something(unsigned long  data)
        }
        break;
        case RMC_SEQUENCE:{
-               DBG("S=%d\n", ddata->period);
+               DBG("S=%ld\n", ddata->period);
                if ((RK_PWM_TIME_RPT_MIN < ddata->period) &&
                    (ddata->period < RK_PWM_TIME_RPT_MAX)) {
                        DBG("S1\n");
@@ -290,93 +292,43 @@ static void rk_pwm_remotectl_timer(unsigned long _data)
 
 static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id)
 {
-       struct rkxx_remotectl_drvdata *ddata;
+       struct rkxx_remotectl_drvdata *ddata = dev_id;
        int val;
-
-       ddata = (struct rkxx_remotectl_drvdata *)dev_id;
-       switch (ddata->remote_pwm_id) {
-       case 0: {
-               val = readl_relaxed(ddata->base + PWM0_REG_INTSTS);
-               if (val & PWM_CH0_INT) {
-                       if ((val & PWM_CH0_POL) == 0) {
-                               val = readl_relaxed(ddata->base + PWM_REG_HPR);
-                               ddata->period = val;
-                               tasklet_hi_schedule(&ddata->remote_tasklet);
-                               DBG("hpr=0x%x\n", val);
-                       } else {
-                               val = readl_relaxed(ddata->base + PWM_REG_LPR);
-                               DBG("lpr=0x%x\n", val);
-                       }
-                       writel_relaxed(PWM_CH0_INT, ddata->base + PWM0_REG_INTSTS);
-                       if (ddata->state == RMC_PRELOAD)
-                               wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
-                       return IRQ_HANDLED;
-               }
-       }
-       break;
-       case 1: {
-               val = readl_relaxed(ddata->base + PWM1_REG_INTSTS);
-               if (val & PWM_CH1_INT) {
-                       if ((val & PWM_CH1_POL) == 0) {
-                               val = readl_relaxed(ddata->base + PWM_REG_HPR);
-                               ddata->period = val;
-                               tasklet_hi_schedule(&ddata->remote_tasklet);
-                               DBG("hpr=0x%x\n", val);
-                       } else {
-                               val = readl_relaxed(ddata->base + PWM_REG_LPR);
-                               DBG("lpr=0x%x\n", val);
-                       }
-                       writel_relaxed(PWM_CH1_INT, ddata->base + PWM1_REG_INTSTS);
-                       if (ddata->state == RMC_PRELOAD)
-                               wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
-                       return IRQ_HANDLED;
-               }
-       }
-       break;
-       case 2: {
-               val = readl_relaxed(ddata->base + PWM2_REG_INTSTS);
-               if (val & PWM_CH2_INT) {
-                       if ((val & PWM_CH2_POL) == 0) {
-                               val = readl_relaxed(ddata->base + PWM_REG_HPR);
-                               ddata->period = val;
-                               tasklet_hi_schedule(&ddata->remote_tasklet);
-                               DBG("hpr=0x%x\n", val);
-                       } else {
-                               val = readl_relaxed(ddata->base + PWM_REG_LPR);
-                               DBG("lpr=0x%x\n", val);
-                       }
-                       writel_relaxed(PWM_CH2_INT, ddata->base + PWM2_REG_INTSTS);
-                       if (ddata->state == RMC_PRELOAD)
-                               wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
-                       return IRQ_HANDLED;
-               }
-       }
-       break;
-       case 3: {
-               val = readl_relaxed(ddata->base + PWM3_REG_INTSTS);
-               if (val & PWM_CH3_INT) {
-                       if ((val & PWM_CH3_POL) == 0) {
-                               val = readl_relaxed(ddata->base + PWM_REG_HPR);
-                               ddata->period = val;
-                               tasklet_hi_schedule(&ddata->remote_tasklet);
-                               DBG("hpr=0x%x\n", val);
-                       } else {
-                               val = readl_relaxed(ddata->base + PWM_REG_LPR);
-                               DBG("lpr=0x%x\n", val);
-                       }
-                       writel_relaxed(PWM_CH3_INT, ddata->base + PWM3_REG_INTSTS);
-                       if (ddata->state == RMC_PRELOAD)
-                               wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
-                       return IRQ_HANDLED;
+       int temp_hpr;
+       int temp_lpr;
+       int temp_period;
+       unsigned int id = ddata->remote_pwm_id;
+
+       if (id > 3)
+               return IRQ_NONE;
+       val = readl_relaxed(ddata->base + PWM_REG_INTSTS(id));
+       if ((val & PWM_CH_INT(id)) == 0)
+               return IRQ_NONE;
+       if ((val & PWM_CH_POL(id)) == 0) {
+               temp_hpr = readl_relaxed(ddata->base + PWM_REG_HPR);
+               DBG("hpr=%d\n", temp_hpr);
+               temp_lpr = readl_relaxed(ddata->base + PWM_REG_LPR);
+               DBG("lpr=%d\n", temp_lpr);
+               temp_period = ddata->pwm_freq_nstime * temp_lpr / 1000;
+               if (temp_period > RK_PWM_TIME_BIT0_MIN) {
+                       ddata->period = ddata->temp_period
+                           + ddata->pwm_freq_nstime * temp_hpr / 1000;
+                       tasklet_hi_schedule(&ddata->remote_tasklet);
+                       ddata->temp_period = 0;
+                       DBG("period+ =%ld\n", ddata->period);
+               } else {
+                       ddata->temp_period += ddata->pwm_freq_nstime
+                           * (temp_hpr + temp_lpr) / 1000;
                }
        }
-       break;
-       default:
-       break;
-       }
-       return IRQ_NONE;
+       writel_relaxed(PWM_CH_INT(id), ddata->base + PWM_REG_INTSTS(id));
+       if (ddata->state == RMC_PRELOAD)
+               wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
+       return IRQ_HANDLED;
 }
 
+
+
 static int rk_pwm_remotectl_hw_init(struct rkxx_remotectl_drvdata *ddata)
 {
        int val;
@@ -388,7 +340,7 @@ static int rk_pwm_remotectl_hw_init(struct rkxx_remotectl_drvdata *ddata)
        val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE;
        writel_relaxed(val, ddata->base + PWM_REG_CTRL);
        val = readl_relaxed(ddata->base + PWM_REG_CTRL);
-       val = (val & 0xFF008DFF) | 0x00646200;
+       val = (val & 0xFF008DFF) | 0x0006000;
        writel_relaxed(val, ddata->base + PWM_REG_CTRL);
        switch (ddata->remote_pwm_id) {
        case 0: {
@@ -425,7 +377,6 @@ static int rk_pwm_remotectl_hw_init(struct rkxx_remotectl_drvdata *ddata)
 }
 
 
-
 static int rk_pwm_probe(struct platform_device *pdev)
 {
        struct rkxx_remotectl_drvdata *ddata;
@@ -440,6 +391,7 @@ static int rk_pwm_probe(struct platform_device *pdev)
        int i, j;
        int cpu_id;
        int pwm_id;
+       int pwm_freq;
 
        pr_err(".. rk pwm remotectl v1.1 init\n");
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -454,10 +406,11 @@ static int rk_pwm_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        ddata->state = RMC_PRELOAD;
+       ddata->temp_period = 0;
        ddata->base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(ddata->base))
                return PTR_ERR(ddata->base);
-       clk = devm_clk_get(&pdev->dev, "pclk_pwm");
+       clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
        platform_set_drvdata(pdev, ddata);
@@ -533,6 +486,8 @@ static int rk_pwm_probe(struct platform_device *pdev)
                return ret;
        }
        rk_pwm_remotectl_hw_init(ddata);
+       pwm_freq = clk_get_rate(clk) / 64;
+       ddata->pwm_freq_nstime = 1000000000 / pwm_freq;
        return ret;
 }
 
old mode 100755 (executable)
new mode 100644 (file)
index 99b9039..d1228d0
@@ -92,24 +92,30 @@ enum pwm_div {
 /********************************************************************\r
 **                            ºê¶¨Òå                                *\r
 ********************************************************************/\r
-#define RK_PWM_TIME_PRE_MIN      19   /*4500*/\r
-#define RK_PWM_TIME_PRE_MAX      30   /*5500*/           /*PreLoad 4.5+0.56 = 5.06ms*/\r
-\r
-#define RK_PWM_TIME_BIT0_MIN     1  /*Bit0  1.125ms*/\r
-#define RK_PWM_TIME_BIT0_MAX     5\r
-\r
-#define RK_PWM_TIME_BIT1_MIN     7  /*Bit1  2.25ms*/\r
-#define RK_PWM_TIME_BIT1_MAX     15\r
-\r
-#define RK_PWM_TIME_RPT_MIN      0x215   /*101000*/\r
-#define RK_PWM_TIME_RPT_MAX      0x235   /*103000*/         /*Repeat  105-2.81=102.19ms*/  //110-9-2.25-0.56=98.19ms\r
-\r
-#define RK_PWM_TIME_SEQ1_MIN     2   /*2650*/\r
-#define RK_PWM_TIME_SEQ1_MAX     0x20   /*3000*/           /*sequence  2.25+0.56=2.81ms*/ //11.25ms\r
-\r
-#define RK_PWM_TIME_SEQ2_MIN     0xDE   /*101000*/\r
-#define RK_PWM_TIME_SEQ2_MAX     0x120   /*103000*/         /*Repeat  105-2.81=102.19ms*/  //110-9-2.25-0.56=98.19ms\r
-\r
+#define RK_PWM_TIME_PRE_MIN    4000
+#define RK_PWM_TIME_PRE_MAX    5000
+\r
+#define RK_PWM_TIME_BIT0_MIN   480
+#define RK_PWM_TIME_BIT0_MAX   700
+\r
+#define RK_PWM_TIME_BIT1_MIN   1300
+#define RK_PWM_TIME_BIT1_MAX   2000
+\r
+#define RK_PWM_TIME_RPT_MIN    2000
+#define RK_PWM_TIME_RPT_MAX    2500
+\r
+#define RK_PWM_TIME_SEQ1_MIN   95000
+#define RK_PWM_TIME_SEQ1_MAX   98000
+\r
+#define RK_PWM_TIME_SEQ2_MIN   30000
+#define RK_PWM_TIME_SEQ2_MAX   55000
+
+
+#define PWM_REG_INTSTS(n)       ((4 - (n)) * 0x10)
+#define PWM_CH_INT(n)   BIT(n)
+#define PWM_CH_POL(n)   BIT(n+8)
+
+
 /********************************************************************\r
 **                          ½á¹¹¶¨Òå                                *\r
 ********************************************************************/\r