mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 06:25:52 +02:00
input: Add IR decode driver
Change-Id: I7e6f36b70fd1f5356ad64cad9a0b9f2aab18c2b1 Signed-off-by: Zhangbin Tong <zebulun.tong@rock-chips.com>
This commit is contained in:
parent
d25b2edaca
commit
e36814cb28
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
9
drivers/input/remotectl/Kconfig
Executable file → Normal file
9
drivers/input/remotectl/Kconfig
Executable file → Normal file
|
|
@ -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
|
||||
|
|
|
|||
6
drivers/input/remotectl/Makefile
Executable file → Normal file
6
drivers/input/remotectl/Makefile
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Makefile for the touchscreen drivers.
|
||||
# Makefile for the input remotectl drivers.
|
||||
#
|
||||
|
||||
# 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
|
||||
|
|
|
|||
129
drivers/input/remotectl/rockchip_pwm_remotectl.c
Executable file → Normal file
129
drivers/input/remotectl/rockchip_pwm_remotectl.c
Executable file → Normal file
|
|
@ -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;
|
||||
int temp_hpr;
|
||||
int temp_lpr;
|
||||
int temp_period;
|
||||
unsigned int id = ddata->remote_pwm_id;
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
32
drivers/input/remotectl/rockchip_pwm_remotectl.h
Executable file → Normal file
32
drivers/input/remotectl/rockchip_pwm_remotectl.h
Executable file → Normal file
|
|
@ -92,24 +92,30 @@ enum pwm_div {
|
|||
/********************************************************************
|
||||
** 宏定义 *
|
||||
********************************************************************/
|
||||
#define RK_PWM_TIME_PRE_MIN 19 /*4500*/
|
||||
#define RK_PWM_TIME_PRE_MAX 30 /*5500*/ /*PreLoad 4.5+0.56 = 5.06ms*/
|
||||
#define RK_PWM_TIME_PRE_MIN 4000
|
||||
#define RK_PWM_TIME_PRE_MAX 5000
|
||||
|
||||
#define RK_PWM_TIME_BIT0_MIN 1 /*Bit0 1.125ms*/
|
||||
#define RK_PWM_TIME_BIT0_MAX 5
|
||||
#define RK_PWM_TIME_BIT0_MIN 480
|
||||
#define RK_PWM_TIME_BIT0_MAX 700
|
||||
|
||||
#define RK_PWM_TIME_BIT1_MIN 7 /*Bit1 2.25ms*/
|
||||
#define RK_PWM_TIME_BIT1_MAX 15
|
||||
#define RK_PWM_TIME_BIT1_MIN 1300
|
||||
#define RK_PWM_TIME_BIT1_MAX 2000
|
||||
|
||||
#define RK_PWM_TIME_RPT_MIN 0x215 /*101000*/
|
||||
#define RK_PWM_TIME_RPT_MAX 0x235 /*103000*/ /*Repeat 105-2.81=102.19ms*/ //110-9-2.25-0.56=98.19ms
|
||||
#define RK_PWM_TIME_RPT_MIN 2000
|
||||
#define RK_PWM_TIME_RPT_MAX 2500
|
||||
|
||||
#define RK_PWM_TIME_SEQ1_MIN 2 /*2650*/
|
||||
#define RK_PWM_TIME_SEQ1_MAX 0x20 /*3000*/ /*sequence 2.25+0.56=2.81ms*/ //11.25ms
|
||||
|
||||
#define RK_PWM_TIME_SEQ2_MIN 0xDE /*101000*/
|
||||
#define RK_PWM_TIME_SEQ2_MAX 0x120 /*103000*/ /*Repeat 105-2.81=102.19ms*/ //110-9-2.25-0.56=98.19ms
|
||||
#define RK_PWM_TIME_SEQ1_MIN 95000
|
||||
#define RK_PWM_TIME_SEQ1_MAX 98000
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** 结构定义 *
|
||||
********************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user