summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Fan <r01011@freescale.com>2010-02-22 22:55:37 +0800
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-05-25 11:17:15 +0200
commit7af8336861b3867852950b137bd1781fd9c2d5e4 (patch)
tree827a6b79e74a6ec24f74a200a527d664b6bd5312
parent76309264b507e341de035685e8c0f3510c2dcc09 (diff)
ENGR00121032 i.MX28 EVK kbd button detect support
use button detect irq to control adc irq Signed-off-by: Fred.fan <r01011@freescale.com> Signed-off-by: Alejandro Gonzalez <alex.gonzalez@digi.com>
-rw-r--r--arch/arm/mach-mx28/device.c8
-rw-r--r--arch/arm/plat-mxs/include/mach/device.h3
-rw-r--r--drivers/input/keyboard/mxs-kbd.c48
3 files changed, 53 insertions, 6 deletions
diff --git a/arch/arm/mach-mx28/device.c b/arch/arm/mach-mx28/device.c
index 3faaf172c82c..9b2e98c3e656 100644
--- a/arch/arm/mach-mx28/device.c
+++ b/arch/arm/mach-mx28/device.c
@@ -666,6 +666,9 @@ static struct mxskbd_keypair keyboard_data[] = {
static struct mxs_kbd_plat_data mxs_kbd_data = {
.keypair = keyboard_data,
.channel = LRADC_CH1,
+ .btn_enable = BM_LRADC_CTRL0_BUTTON1_DETECT_ENABLE,
+ .btn_irq_stat = BM_LRADC_CTRL1_BUTTON1_DETECT_IRQ,
+ .btn_irq_ctrl = BM_LRADC_CTRL1_BUTTON1_DETECT_IRQ_EN,
};
static struct resource mx28_kbd_res[] = {
@@ -679,6 +682,11 @@ static struct resource mx28_kbd_res[] = {
.start = IRQ_LRADC_CH1,
.end = IRQ_LRADC_CH1,
},
+ {
+ .flags = IORESOURCE_IRQ,
+ .start = IRQ_LRADC_BUTTON1,
+ .end = IRQ_LRADC_BUTTON1,
+ },
};
static void __init mx28_init_kbd(void)
diff --git a/arch/arm/plat-mxs/include/mach/device.h b/arch/arm/plat-mxs/include/mach/device.h
index b424a69d256d..c5728e1a4ba9 100644
--- a/arch/arm/plat-mxs/include/mach/device.h
+++ b/arch/arm/plat-mxs/include/mach/device.h
@@ -71,6 +71,9 @@ struct mxskbd_keypair {
struct mxs_kbd_plat_data {
struct mxskbd_keypair *keypair;
int channel;
+ unsigned int btn_enable; /* detect enable bits */
+ unsigned int btn_irq_stat; /* detect irq status bits */
+ unsigned int btn_irq_ctrl; /* detect irq enable bits */
};
struct mxs_touchscreen_plat_data {
diff --git a/drivers/input/keyboard/mxs-kbd.c b/drivers/input/keyboard/mxs-kbd.c
index 7161a610271d..99d85e8189a0 100644
--- a/drivers/input/keyboard/mxs-kbd.c
+++ b/drivers/input/keyboard/mxs-kbd.c
@@ -41,9 +41,13 @@ struct mxskbd_data {
struct input_dev *input;
int last_button;
int irq;
+ int btn_irq;
struct mxskbd_keypair *keycodes;
unsigned int base;
int chan;
+ unsigned int btn_enable; /* detect enable bits */
+ unsigned int btn_irq_stat; /* detect irq status bits */
+ unsigned int btn_irq_ctrl; /* detect irq enable bits */
};
static int delay1 = 500;
@@ -137,6 +141,16 @@ static irqreturn_t mxskbd_irq_handler(int irq, void *dev_id)
u16 raw_button, normalized_button, vddio;
unsigned btn;
+ if (devdata->btn_irq == irq) {
+ __raw_writel(devdata->btn_irq_stat,
+ devdata->base + HW_LRADC_CTRL1_CLR);
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << devdata->chan,
+ devdata->base + HW_LRADC_CTRL1_CLR);
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ_EN << devdata->chan,
+ devdata->base + HW_LRADC_CTRL1_SET);
+ return IRQ_HANDLED;
+ }
+
raw_button = __raw_readl(devdata->base + HW_LRADC_CHn(devdata->chan)) &
BM_LRADC_CHn_VALUE;
vddio = hw_lradc_vddio();
@@ -162,6 +176,10 @@ static irqreturn_t mxskbd_irq_handler(int irq, void *dev_id)
input_report_key(GET_INPUT_DEV(devdata),
devdata->last_button, 0);
devdata->last_button = -1;
+ if (devdata->btn_irq > 0)
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ_EN <<
+ devdata->chan,
+ devdata->base + HW_LRADC_CTRL1_CLR);
}
__raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << devdata->chan,
@@ -185,10 +203,15 @@ static void mxskbd_hwinit(struct platform_device *pdev)
struct mxskbd_data *d = platform_get_drvdata(pdev);
hw_lradc_init_ladder(d->chan, LRADC_DELAY_TRIGGER_BUTTON, 200);
- __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << d->chan,
- d->base + HW_LRADC_CTRL1_CLR);
- __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ_EN << d->chan,
- d->base + HW_LRADC_CTRL1_SET);
+ if (d->btn_irq > 0) {
+ __raw_writel(d->btn_enable, d->base + HW_LRADC_CTRL0_SET);
+ __raw_writel(d->btn_irq_ctrl, d->base + HW_LRADC_CTRL1_SET);
+ } else {
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << d->chan,
+ d->base + HW_LRADC_CTRL1_CLR);
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ_EN << d->chan,
+ d->base + HW_LRADC_CTRL1_SET);
+ }
hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_BUTTON, !0);
}
@@ -246,6 +269,10 @@ static int __devinit mxskbd_probe(struct platform_device *pdev)
d->base = (unsigned int)IO_ADDRESS(res->start);
d->chan = plat_data->channel;
d->irq = platform_get_irq(pdev, 0);
+ d->btn_irq = platform_get_irq(pdev, 1);
+ d->btn_enable = plat_data->btn_enable;
+ d->btn_irq_stat = plat_data->btn_irq_stat;
+ d->btn_irq_ctrl = plat_data->btn_irq_ctrl;
platform_set_drvdata(pdev, d);
@@ -256,10 +283,17 @@ static int __devinit mxskbd_probe(struct platform_device *pdev)
goto err_free_dev;
}
+ err = request_irq(d->btn_irq, mxskbd_irq_handler,
+ IRQF_DISABLED, pdev->name, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot request keybad detect IRQ\n");
+ goto err_free_irq;
+ }
+
/* Register the input device */
err = input_register_device(GET_INPUT_DEV(d));
if (err)
- goto err_free_irq;
+ goto err_free_irq2;
/* these two have to be set after registering the input device */
d->input->rep[REP_DELAY] = delay1;
@@ -270,8 +304,10 @@ static int __devinit mxskbd_probe(struct platform_device *pdev)
return 0;
-err_free_irq:
+err_free_irq2:
platform_set_drvdata(pdev, NULL);
+ free_irq(d->btn_irq, pdev);
+err_free_irq:
free_irq(d->irq, pdev);
err_free_dev:
mxskbd_data_free(d);