static irqreturn_t ts_handler(int irq, void *dev_id) { struct stmp3xxx_ts_info *info = dev_id; u16 x_plus, y_plus; int pressure = 0; if (irq == info->touch_irq) __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ, REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR); else if (irq == info->device_irq) __raw_writel(BM_LRADC_CTRL1_LRADC5_IRQ, REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR); /* get x, y values */ x_plus = __raw_readl(REGS_LRADC_BASE + HW_LRADC_CHn(LRADC_TOUCH_X_PLUS)) & BM_LRADC_CHn_VALUE; y_plus = __raw_readl(REGS_LRADC_BASE + HW_LRADC_CHn(LRADC_TOUCH_Y_PLUS)) & BM_LRADC_CHn_VALUE; /* pressed? */ if (__raw_readl(REGS_LRADC_BASE + HW_LRADC_STATUS) & BM_LRADC_STATUS_TOUCH_DETECT_RAW) pressure = 1; pr_debug("%s: irq %d, x_plus %d, y_plus %d, pressure %d\n", __func__, irq, x_plus, y_plus, pressure); process_lradc(info, x_plus, y_plus, pressure); return IRQ_HANDLED; }
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 void jack_process(struct mxskbd_data *d) { int pin; int in; int jack; static int amp_on_cnt; static int amp; pin = !!mxs_audio_jack_gpio_get(); if (pin) amp_on_cnt = 10; else if (amp_on_cnt > 0) amp_on_cnt--; if (amp_on_cnt > 0) { if (!amp) { mxs_audio_headset_mic_detect_amp_gpio_set(1); amp = 1; } } else { if (amp) { mxs_audio_headset_mic_detect_amp_gpio_set(0); amp = 0; } } if (!!d->jack_last == pin) { d->jack_cnt = 0; return; } if (++d->jack_cnt <= 6) return; if (pin == 0) { /* eject */ in = 0; jack = d->jack_last; d->jack_last = 0; } else { /* insert */ int i = __raw_readl(d->base + HW_LRADC_CHn(d->chan[MAX_CH-1])) & BM_LRADC_CHn_VALUE; d->jack_last = (i > MIC_DET_THRESHOLD) ? SW_MICROPHONE_INSERT : SW_HEADPHONE_INSERT; in = 1; jack = d->jack_last; } input_report_switch(GET_INPUT_DEV(d), jack, in); }
u32 hw_lradc_vddio(void) { /* Clear the Soft Reset and Clock Gate for normal operation */ __raw_writel(BM_LRADC_CTRL0_SFTRST | BM_LRADC_CTRL0_CLKGATE, mxs_lradc.base + HW_LRADC_CTRL0_CLR); /* * Clear the divide by two for channel 6 since * it has a HW divide-by-two built in. */ __raw_writel(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1 << VDDIO_VOLTAGE_CH), mxs_lradc.base + HW_LRADC_CTRL2_CLR); /* Clear the accumulator & NUM_SAMPLES */ __raw_writel(0xFFFFFFFF, mxs_lradc.base + HW_LRADC_CHn_CLR(VDDIO_VOLTAGE_CH)); /* Clear the interrupt flag */ __raw_writel(BM_LRADC_CTRL1_LRADC6_IRQ, mxs_lradc.base + HW_LRADC_CTRL1_CLR); /* * Get VddIO; this is the max scale value for the button resistor * ladder. * schedule ch 6: */ __raw_writel(BF_LRADC_CTRL0_SCHEDULE(1 << VDDIO_VOLTAGE_CH), mxs_lradc.base + HW_LRADC_CTRL0_SET); /* wait for completion */ while ((__raw_readl(mxs_lradc.base + HW_LRADC_CTRL1) & BM_LRADC_CTRL1_LRADC6_IRQ) != BM_LRADC_CTRL1_LRADC6_IRQ) cpu_relax(); /* Clear the interrupt flag */ __raw_writel(BM_LRADC_CTRL1_LRADC6_IRQ, mxs_lradc.base + HW_LRADC_CTRL1_CLR); /* read ch 6 value. */ return __raw_readl(mxs_lradc.base + HW_LRADC_CHn(VDDIO_VOLTAGE_CH)) & BM_LRADC_CHn_VALUE; }
/* * Use the the lradc1 channel * get the die temperature from on-chip sensor. */ int MeasureInternalDieTemperature(void) { uint32_t ch8Value, ch9Value; /* power up internal tep sensor block */ __raw_writel(BM_LRADC_CTRL2_TEMPSENSE_PWD, REGS_LRADC_BASE + HW_LRADC_CTRL2_CLR); /* mux to the lradc 8th temp channel */ __raw_writel(BF(0xF, LRADC_CTRL4_LRADC1SELECT), REGS_LRADC_BASE + HW_LRADC_CTRL4_CLR); __raw_writel(BF(8, LRADC_CTRL4_LRADC1SELECT), REGS_LRADC_BASE + HW_LRADC_CTRL4_SET); /* Clear the interrupt flag */ __raw_writel(BM_LRADC_CTRL1_LRADC1_IRQ, REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR); __raw_writel(BF(1 << LRADC_CH1, LRADC_CTRL0_SCHEDULE), REGS_LRADC_BASE + HW_LRADC_CTRL0_SET); /* Wait for conversion complete*/ while (!(__raw_readl(REGS_LRADC_BASE + HW_LRADC_CTRL1) & BM_LRADC_CTRL1_LRADC1_IRQ)) cpu_relax(); /* Clear the interrupt flag again */ __raw_writel(BM_LRADC_CTRL1_LRADC1_IRQ, REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR); /* read temperature value and clr lradc */ ch8Value = __raw_readl(REGS_LRADC_BASE + HW_LRADC_CHn(LRADC_CH1)) & BM_LRADC_CHn_VALUE; __raw_writel(BM_LRADC_CHn_VALUE, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(LRADC_CH1)); /* mux to the lradc 9th temp channel */ __raw_writel(BF(0xF, LRADC_CTRL4_LRADC1SELECT), REGS_LRADC_BASE + HW_LRADC_CTRL4_CLR); __raw_writel(BF(9, LRADC_CTRL4_LRADC1SELECT), REGS_LRADC_BASE + HW_LRADC_CTRL4_SET); /* Clear the interrupt flag */ __raw_writel(BM_LRADC_CTRL1_LRADC1_IRQ, REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR); __raw_writel(BF(1 << LRADC_CH1, LRADC_CTRL0_SCHEDULE), REGS_LRADC_BASE + HW_LRADC_CTRL0_SET); /* Wait for conversion complete */ while (!(__raw_readl(REGS_LRADC_BASE + HW_LRADC_CTRL1) & BM_LRADC_CTRL1_LRADC1_IRQ)) cpu_relax(); /* Clear the interrupt flag */ __raw_writel(BM_LRADC_CTRL1_LRADC1_IRQ, REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR); /* read temperature value */ ch9Value = __raw_readl(REGS_LRADC_BASE + HW_LRADC_CHn(LRADC_CH1)) & BM_LRADC_CHn_VALUE; __raw_writel(BM_LRADC_CHn_VALUE, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(LRADC_CH1)); /* power down temp sensor block */ __raw_writel(BM_LRADC_CTRL2_TEMPSENSE_PWD, REGS_LRADC_BASE + HW_LRADC_CTRL2_SET); return ((ch9Value-ch8Value)*GAIN_CORRECTION/4 - KELVIN_TO_CELSIUS_CONST); }
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; }