Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #5
0
/*
 * 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);
}
Beispiel #6
0
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;
}