static irqreturn_t mxskbd_irq_handler(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct mxskbd_data *devdata = platform_get_drvdata(pdev); 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(); BUG_ON(vddio == 0); normalized_button = (raw_button * TARGET_VDDIO_LRADC_VALUE) / vddio; if (normalized_button < BUTTON_PRESS_THRESHOLD && devdata->last_button < 0) { btn = mxskbd_decode_button(devdata->keycodes, normalized_button); if (btn < KEY_MAX) { devdata->last_button = btn; input_report_key(GET_INPUT_DEV(devdata), devdata->last_button, !0); } else dev_err(&pdev->dev, "Invalid button: raw = %d, " "normalized = %d, vddio = %d\n", raw_button, normalized_button, vddio); } else if (devdata->last_button > 0 && normalized_button >= BUTTON_PRESS_THRESHOLD) { 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, devdata->base + HW_LRADC_CTRL1_CLR); return IRQ_HANDLED; }
static irqreturn_t mxskbd_irq_handler(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct mxskbd_data *d = platform_get_drvdata(pdev); int i, key, f_key = -1; u32 vddio; jack_process(d); /* end key process */ i = (__raw_readl(REGS_POWER_BASE + HW_POWER_STS) & BF_POWER_STS_PSWITCH(0x1)) ? KEY_END : -1; if (i == KEY_END) { if (i == d->last_button) goto _end; f_key = i; } if (f_key < 0 && d->jack_cnt == 0 && d->jack_last == SW_MICROPHONE_INSERT) { i = __raw_readl(d->base + HW_LRADC_CHn(d->chan[MAX_CH-1])) & BM_LRADC_CHn_VALUE; if (i <= MIC_DET_THRESHOLD) { if (d->last_button == KEY_KPENTER) { d->jack_push_cnt = 0; goto _end; } if (++d->jack_push_cnt > 4) f_key = KEY_KPENTER; } else d->jack_push_cnt = 0; } else d->jack_push_cnt = 0; /* adc key process */ vddio = __raw_readl(d->base + HW_LRADC_CHn(VDDIO_VOLTAGE_CH)) & BM_LRADC_CHn_VALUE; BUG_ON(vddio == 0); #ifdef DUMP_KEY_ADC static int val[MAX_CH]; printk("KEY=0x%03x(%4d), 0x%03x(%4d), 0x%03x(%4d), 0x%03x(%4d)\n", val[0], val[0], val[1], val[1], val[2], val[2], val[3], val[3]); #endif for (i = 0; i < MAX_CH-1; i++) { int raw, norm; raw = __raw_readl(d->base + HW_LRADC_CHn(d->chan[i])) & BM_LRADC_CHn_VALUE; norm = (raw * TARGET_VDDIO_LRADC_VALUE) / vddio; key = mxskbd_decode_button(d->keycodes + d->keycodes_offset*i, norm); key = unjitter_key(i, key); #ifdef DUMP_KEY_ADC val[i] = raw; #endif if (key >= 0) { if (key == d->last_button) goto _end; if (f_key < 0) f_key = key; } } key = volume_key_process(d); if (key > 0) { if (key == d->last_button) goto _end; if (f_key < 0) f_key = key; } if (d->last_button >= 0) { input_report_key(GET_INPUT_DEV(d), d->last_button, 0); d->last_button = -1; } if (f_key >= 0 && f_key != d->last_button) { input_report_key(GET_INPUT_DEV(d), f_key, !0); #ifdef ENABLE_BACKLIGHT_GPIO_CONTROL _keypad_set_backlight(1); #endif #ifdef CONFIG_HAS_WAKELOCK wake_lock_timeout(&key_wake_lock, 5*HZ); #endif d->last_button = f_key; } _end: __raw_writel((BM_LRADC_CTRL1_LRADC0_IRQ << d->chan[0]) + (BM_LRADC_CTRL1_LRADC0_IRQ << d->chan[1]) + (BM_LRADC_CTRL1_LRADC0_IRQ << d->chan[2]) + (BM_LRADC_CTRL1_LRADC0_IRQ << d->chan[3]) + (BM_LRADC_CTRL1_LRADC0_IRQ << VDDIO_VOLTAGE_CH), d->base + HW_LRADC_CTRL1_CLR); return IRQ_HANDLED; }