diff options
author | Fred Fan <r01011@freescale.com> | 2010-02-22 22:55:37 +0800 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-05-25 11:17:15 +0200 |
commit | 7af8336861b3867852950b137bd1781fd9c2d5e4 (patch) | |
tree | 827a6b79e74a6ec24f74a200a527d664b6bd5312 | |
parent | 76309264b507e341de035685e8c0f3510c2dcc09 (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.c | 8 | ||||
-rw-r--r-- | arch/arm/plat-mxs/include/mach/device.h | 3 | ||||
-rw-r--r-- | drivers/input/keyboard/mxs-kbd.c | 48 |
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); |