Example #1
0
static inline void enter_state_touch_detect(struct stmp3xxx_ts_info *info)
{
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(2));
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(3));
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(4));
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(5));
	__raw_writel(BM_LRADC_CTRL1_LRADC5_IRQ,
		REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR);
	__raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ,
		REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR);
	/*
	 * turn off the yplus and yminus pullup and pulldown, and turn off touch
	 * detect (enables yminus, and xplus through a resistor.On a press,
	 * xplus is pulled down)
	 */
	__raw_writel(BM_LRADC_CTRL0_YMINUS_ENABLE,
		REGS_LRADC_BASE + HW_LRADC_CTRL0_CLR);
	__raw_writel(BM_LRADC_CTRL0_YPLUS_ENABLE,
		REGS_LRADC_BASE + HW_LRADC_CTRL0_CLR);
	__raw_writel(BM_LRADC_CTRL0_XMINUS_ENABLE,
		REGS_LRADC_BASE + HW_LRADC_CTRL0_CLR);
	__raw_writel(BM_LRADC_CTRL0_XPLUS_ENABLE,
		REGS_LRADC_BASE + HW_LRADC_CTRL0_CLR);
	__raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
		REGS_LRADC_BASE + HW_LRADC_CTRL0_SET);

	hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 0);
	info->state = TS_STATE_TOUCH_DETECT;
	info->sample_count = 0;
}
Example #2
0
static void lradc_keypad_hwinit ()
{
	/* Clear the Clock Gate and SFTRST for normal operation */
	HW_LRADC_CTRL0_CLR(BM_LRADC_CTRL0_SFTRST);
	HW_LRADC_CTRL0_CLR(BM_LRADC_CTRL0_CLKGATE);

	/* Disable on-chip ground reference */
	HW_LRADC_CTRL0_CLR(BM_LRADC_CTRL0_ONCHIP_GROUNDREF);

	/* Configure 6Mhz frequency */
	HW_LRADC_CTRL3_CLR(BM_LRADC_CTRL3_CYCLE_TIME);
	HW_LRADC_CTRL3_SET(BF_LRADC_CTRL3_CYCLE_TIME(LRADC_CLOCK_6MHZ));

	/* Select VddIO input on channel 6 */
	HW_LRADC_CTRL4_CLR(BM_LRADC_CTRL4_LRADC6SELECT);
	HW_LRADC_CTRL4_SET(BF_LRADC_CTRL4_LRADC6SELECT(lradc_vddio_ch));

	/*
	 * Clear the divide by two for channel 6 since it has a HW
	 * divide-by-two built in, and enable this feature for the
	 * button channel
	 */
	HW_LRADC_CTRL2_CLR(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1<<VDDIO_VOLTAGE_CH));
	HW_LRADC_CTRL2_SET(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1<<lradc_keypad_ch));

	/* Clear the accumulator & NUM_SAMPLES */
	HW_LRADC_CHn_CLR(VDDIO_VOLTAGE_CH, 0xFFFFFFFF);
	HW_LRADC_CHn_CLR(lradc_keypad_ch, 0xFFFFFFFF);
}
void hw_lradc_configure_channel(int channel, int enable_div2,
				int enable_acc, int samples)
{
	if (enable_div2)
		__raw_writel(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1 << channel),
			     mxs_lradc.base + HW_LRADC_CTRL2_SET);
	else
		__raw_writel(BF_LRADC_CTRL2_DIVIDE_BY_TWO(1 << channel),
			     mxs_lradc.base + HW_LRADC_CTRL2_CLR);

	/* Clear the accumulator & NUM_SAMPLES */
	__raw_writel(0xFFFFFFFF, mxs_lradc.base + HW_LRADC_CHn_CLR(channel));

	/* Sets NUM_SAMPLES bitfield of HW_LRADC_CHn register. */
	__raw_writel(BM_LRADC_CHn_NUM_SAMPLES,
		     mxs_lradc.base + HW_LRADC_CHn_CLR(channel));
	__raw_writel(BF_LRADC_CHn_NUM_SAMPLES(samples),
		     mxs_lradc.base + HW_LRADC_CHn_SET(channel));

	if (enable_acc)
		__raw_writel(BM_LRADC_CHn_ACCUMULATE,
			     mxs_lradc.base + HW_LRADC_CHn_SET(channel));
	else
		__raw_writel(BM_LRADC_CHn_ACCUMULATE,
			     mxs_lradc.base + HW_LRADC_CHn_CLR(channel));
}
Example #4
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_lradc_ConfigureChannel( hw_lradc_Channel_t  eChannel,
                                bool                bEnableDivideByTwo,
                                bool                bEnableAccum,
                                uint8_t             u8NumSamples)
{
    // Set the analog divide-by two function
    if(bEnableDivideByTwo)
    {
        // Enable the divide-by-two of a LRADC channel
        BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, (1 << eChannel));
    }
    else
    {
        // Disable the divide-by-two of a LRADC channel
        BF_CLRV(LRADC_CTRL2, DIVIDE_BY_TWO, (1 << eChannel));
    }

    // Clear the accumulator & NUM_SAMPLES
    HW_LRADC_CHn_CLR(eChannel, 0xFFFFFFFF);

    // Sets NUM_SAMPLES bitfield of HW_LRADC_CHn register.
    BF_WRn(LRADC_CHn, eChannel, NUM_SAMPLES, (u8NumSamples & 0x1f));

    // Set ACCUMULATE bit of HW_LRADC_CHn register
    if(bEnableAccum)
    {
        // Enable the accumulation of a LRADC channel
        BF_SETn(LRADC_CHn, eChannel, ACCUMULATE);
    }
    else
    {
        // Disable the accumulation of a LRADC channel
        BF_CLRn(LRADC_CHn, eChannel, ACCUMULATE);
    }
}
Example #5
0
/* only works for channels <=7, always divide by 2, never accumulates */
static inline void __attribute__((always_inline)) setup_lradc(int src)
{
    BF_CLR(LRADC_CTRL0, SFTRST);
    BF_CLR(LRADC_CTRL0, CLKGATE);
    /* don't bother changing the source, we are early enough at boot so that
     * channel x is mapped to source x */
    HW_LRADC_CHn_CLR(src) = BM_OR2(LRADC_CHn, NUM_SAMPLES, ACCUMULATE);
    BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << src);
}
Example #6
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
RtStatus_t hw_lradc_EnableBatteryMeasurement( hw_lradc_DelayTrigger_t eTrigger,
                                              uint16_t u16SamplingInterval)
{
    hw_lradc_Channel_t       eChannel = BATTERY_VOLTAGE_CH;

    //
    // Check if the lradc channel is present in this product
    //
    if( hw_lradc_GetChannelPresent(eChannel) == 0 )
        return (ERROR_HW_LRADC_CH_NOT_PRESENT);

    // Disable the channel interrupt
    hw_lradc_EnableInterrupt(eChannel, FALSE);

    hw_lradc_ClearInterruptFlag(eChannel);

    // Configure the battery conversion register
    BF_WR(LRADC_CONVERSION, SCALE_FACTOR, 2);


    // Enable the automatic update mode of BATT_VALUE field in HW_POWER_MONITOR
    BF_SET(LRADC_CONVERSION, AUTOMATIC);

    hw_lradc_ConfigureChannel(  eChannel,   //Lradc channel
                                    FALSE,      //DIVIDE_BY_TWO
                                    FALSE,      //ACCUMULATE
                                    0);         //NUM_SAMPLES

    // schedule a conversion before the setting up of the delay channel
    // so the user can have a good value right after the function returns
    hw_lradc_ScheduleChannel(eChannel);

    // Setup the trigger loop forever,
    hw_lradc_SetDelayTrigger( eTrigger,         // Trigger Index
                              (1 << eChannel),  // Lradc channels
                              (1 << eTrigger),  // Restart the triggers
                              0,                // No loop count
                              u16SamplingInterval); // 0.5*N msec on 2khz

    // Clear the accumulator & NUM_SAMPLES
    HW_LRADC_CHn_CLR(eChannel, 0xFFFFFFFF);

    // Kick off the LRADC battery measurement
    hw_lradc_SetDelayTriggerKick(eTrigger, TRUE);


    /* Wait for first measurement of battery.  Should occur in 13 LRADC clock
     * cycles from the time of channel kickoff.  Also add some wait time for
     * copy to the power supply BATT_VAL field to occur.
     */
    hw_digctl_MicrosecondWait(10);



    return SUCCESS;
}
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;
}
int hw_lradc_init_ladder(int channel, int trigger, unsigned sampling)
{
	/*
	 * check if the lradc channel is present in this product
	 */
	if (!hw_lradc_present(channel))
		return -ENODEV;

	hw_lradc_configure_channel(channel, !0 /* div2 */ ,
				   0 /* acc */ ,
				   0 /* num_samples */);

	/* Setup the trigger loop forever */
	hw_lradc_set_delay_trigger(trigger, 1 << channel,
				   1 << trigger, 0, sampling);

	/* Clear the accumulator & NUM_SAMPLES */
	__raw_writel(0xFFFFFFFF, mxs_lradc.base + HW_LRADC_CHn_CLR(channel));
	return 0;
}
Example #9
0
static int stmp3xxx_ts_probe(struct platform_device *pdev)
{
	struct input_dev *idev;
	struct stmp3xxx_ts_info *info;
	int ret = 0;
	struct resource *res;

	idev = input_allocate_device();
	info = kzalloc(sizeof(struct stmp3xxx_ts_info), GFP_KERNEL);
	if (idev == NULL || info == NULL) {
		ret = -ENOMEM;
		goto out_nomem;
	}

	idev->name = "STMP3XXX touchscreen";
	idev->evbit[0] = BIT(EV_ABS);
	input_set_abs_params(idev, ABS_X, 0, 0xFFF, 0, 0);
	input_set_abs_params(idev, ABS_Y, 0, 0xFFF, 0, 0);
	input_set_abs_params(idev, ABS_PRESSURE, 0, 1, 0, 0);

	ret = input_register_device(idev);
	if (ret)
		goto out_nomem;

	info->idev = idev;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		printk(KERN_ERR "%s: couldn't get IRQ resource\n", __func__);
		ret = -ENODEV;
		goto out_nodev;
	}
	info->touch_irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (!res) {
		printk(KERN_ERR "%s: couldn't get IRQ resource\n", __func__);
		ret = -ENODEV;
		goto out_nodev;
	}
	info->device_irq = res->start;

	ret = request_irq(info->touch_irq, ts_handler, IRQF_DISABLED,
				"stmp3xxx_ts_touch", info);
	if (ret)
		goto out_nodev;

	ret = request_irq(info->device_irq, ts_handler, IRQF_DISABLED,
				"stmp3xxx_ts_dev", info);
	if (ret) {
		free_irq(info->touch_irq, info);
		goto out_nodev;
	}
	enter_state_touch_detect(info);

	hw_lradc_use_channel(LRADC_CH2);
	hw_lradc_use_channel(LRADC_CH3);
	hw_lradc_use_channel(LRADC_CH5);
	hw_lradc_configure_channel(LRADC_CH2, 0, 0, 0);
	hw_lradc_configure_channel(LRADC_CH3, 0, 0, 0);
	hw_lradc_configure_channel(LRADC_CH5, 0, 0, 0);

	/* Clear the accumulator & NUM_SAMPLES for the channels */
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(LRADC_CH2));
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(LRADC_CH3));
	__raw_writel(0xFFFFFFFF, REGS_LRADC_BASE + HW_LRADC_CHn_CLR(LRADC_CH5));

	hw_lradc_set_delay_trigger(LRADC_DELAY_TRIGGER_TOUCHSCREEN,
			0x3c, 0, 0, 8);

	__raw_writel(BM_LRADC_CTRL1_LRADC5_IRQ,
		REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR);
	__raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ,
		REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR);

	__raw_writel(BM_LRADC_CTRL1_LRADC5_IRQ_EN,
		REGS_LRADC_BASE + HW_LRADC_CTRL1_SET);
	__raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
		REGS_LRADC_BASE + HW_LRADC_CTRL1_SET);

	platform_set_drvdata(pdev, info);
	device_init_wakeup(&pdev->dev, 1);
	goto out;

out_nodev:
	input_free_device(idev);
out_nomem:
	kfree(idev);
	kfree(info);
out:
	return ret;
}
Example #10
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);
}