This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

A/D conversion interfering with touch display?

Other Parts Discussed in Thread: AM3352

Hello,

I am working on an embedded project using the AM3352 processor. I have been having an issue where the touch display seems to get "confused" and stops working after i perform reads from: "/sys/bus/iio/devices/iio:device0/in_voltage7_raw" and "/sys/bus/iio/devices/iio:device0/in_voltage5_raw". Once the touch is "confused" stopping the application and restarting it does not help. Even other applications such as ti's demo matrix program also do not respond correctly to touch input. The only way I've been able to recover is to reboot the system.

A few more details about the sytem... There are several Qt processes running (only one server -qws). One process does the A/D reading and another handles all the display updates.

Any help would be appreciated. thanks.

  • Hi Michael,

    Which Linux version are you using? The new SDK 7.0 has TS issues which are known and under investigation by the software team.

  • Thank you for you quick reply.

    I am using the sdk 7.0 and the output of uname -a is: Linux am335x-evm 3.12.10-ti2013.12.01 #8 Fri Jun 13 11:02:27 CDT 2014 armv7l GNU/Linux

    Have these issues been documented as of yet?

  • Release notes can be found here: http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Kernel_Release_Notes but from what I see the page hasn't been updated recently.

  • Yeah I do not see anything on that list that would match the issue I am seeing. Do you have additional information or know where I can obtain it on any touchscreen issues?

  • No, I only know that this is being investigated by the Linux team, but I don't have information on progress/timelines.

  • Try applying the below patch to the kernel and rebuilding the kernel and modules and installing them onto the filesystem.

    6558.0001-Touchscreen-lockout-issue-You-can-not-read-the-step-.diff
    From 80babba12ea617988058ceee3fe2094e63768799 Mon Sep 17 00:00:00 2001
    From: Jeff Lance <j-lance1@ti.com>
    Date: Sat, 2 Nov 2013 16:17:19 -0500
    Subject: [PATCH] Touchscreen lockout issue: You can not read the step Enable
     register unless the sequencer is idle.  Modify the code to
     only write to the step enable register. Break
     am335x_tsc_se_set into two functions. One to set one time
     steps. One to set continuous steps Use the reg_se_cache to
     store continuous steps.
    
    ---
     drivers/iio/adc/ti_am335x_adc.c           |    2 +-
     drivers/input/touchscreen/ti_am335x_tsc.c |    4 ++--
     drivers/mfd/ti_am335x_tscadc.c            |   26 +++++++++++++++++---------
     include/linux/mfd/ti_am335x_tscadc.h      |    5 +++--
     4 files changed, 23 insertions(+), 14 deletions(-)
    
    diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
    index 58f1d4b..4a8607e 100644
    --- a/drivers/iio/adc/ti_am335x_adc.c
    +++ b/drivers/iio/adc/ti_am335x_adc.c
    @@ -148,7 +148,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
     	unsigned long timeout = jiffies + usecs_to_jiffies
     				(IDLE_TIMEOUT * adc_dev->channels);
     	step_en = get_adc_step_mask(adc_dev);
    -	am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
    +	am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en);
     
     	/* Wait for ADC sequencer to complete sampling */
     	while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
    diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
    index b61df9d..05576d4 100644
    --- a/drivers/input/touchscreen/ti_am335x_tsc.c
    +++ b/drivers/input/touchscreen/ti_am335x_tsc.c
    @@ -196,7 +196,7 @@ static void titsc_step_config(struct titsc *ts_dev)
     
     	/* The steps1 … end and bit 0 for TS_Charge */
     	stepenable = (1 << (end_step + 2)) - 1;
    -	am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
    +	am335x_tsc_se_set_cont(ts_dev->mfd_tscadc, stepenable);
     }
     
     static void titsc_read_coordinates(struct titsc *ts_dev,
    @@ -316,7 +316,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
     
     	if (irqclr) {
     		titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
    -		am335x_tsc_se_update(ts_dev->mfd_tscadc);
    +		am335x_tsc_se_update(ts_dev->mfd_tscadc, 0);
     		return IRQ_HANDLED;
     	}
     	return IRQ_NONE;
    diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
    index 912a41f..c4c1a1a 100644
    --- a/drivers/mfd/ti_am335x_tscadc.c
    +++ b/drivers/mfd/ti_am335x_tscadc.c
    @@ -48,32 +48,40 @@ static const struct regmap_config tscadc_regmap_config = {
     	.val_bits = 32,
     };
     
    -void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc)
    +void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc, u32 val)
     {
    -	tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
    +	tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache | val);
     }
     EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
     
    -void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
    +void am335x_tsc_se_set_cont(struct ti_tscadc_dev *tsadc, u32 val)
     {
     	unsigned long flags;
     
     	spin_lock_irqsave(&tsadc->reg_lock, flags);
    -	tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
     	tsadc->reg_se_cache |= val;
    -	am335x_tsc_se_update(tsadc);
    +	am335x_tsc_se_update(tsadc, 0);
     	spin_unlock_irqrestore(&tsadc->reg_lock, flags);
     }
    -EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
    +EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cont);
    +
    +void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val)
    +{
    +	unsigned long flags;
    +
    +	spin_lock_irqsave(&tsadc->reg_lock, flags);
    +	am335x_tsc_se_update(tsadc, val);
    +	spin_unlock_irqrestore(&tsadc->reg_lock, flags);
    +}
    +EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
     
     void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
     {
     	unsigned long flags;
     
     	spin_lock_irqsave(&tsadc->reg_lock, flags);
    -	tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
     	tsadc->reg_se_cache &= ~val;
    -	am335x_tsc_se_update(tsadc);
    +	am335x_tsc_se_update(tsadc, 0);
     	spin_unlock_irqrestore(&tsadc->reg_lock, flags);
     }
     EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
    @@ -302,7 +310,7 @@ static int tscadc_resume(struct device *dev)
     
     	if (tscadc_dev->tsc_cell != -1)
     		tscadc_idle_config(tscadc_dev);
    -	am335x_tsc_se_update(tscadc_dev);
    +	am335x_tsc_se_update(tscadc_dev, 0);
     	restore = tscadc_readl(tscadc_dev, REG_CTRL);
     	tscadc_writel(tscadc_dev, REG_CTRL,
     			(restore | CNTRLREG_TSCSSENB));
    diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
    index 25f2c61..3ed6613 100644
    --- a/include/linux/mfd/ti_am335x_tscadc.h
    +++ b/include/linux/mfd/ti_am335x_tscadc.h
    @@ -161,8 +161,9 @@ static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
     	return *tscadc_dev;
     }
     
    -void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc);
    -void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val);
    +void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc, u32 val);
    +void am335x_tsc_se_set_cont(struct ti_tscadc_dev *tsadc, u32 val);
    +void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val);
     void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val);
     
     #endif
    -- 
    1.7.9.5
    
    

    If your unsure how to perform any of the below steps let me know and I can point  you to some documentation.