aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c68
-rw-r--r--drivers/input/touchscreen/ti_am335x_tsc.c4
-rw-r--r--drivers/mfd/ti_am335x_tscadc.c71
-rw-r--r--include/linux/mfd/ti_am335x_tscadc.h8
4 files changed, 117 insertions, 34 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index d4d748214e4b..31e786e3999b 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -60,6 +60,24 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
60 return step_en; 60 return step_en;
61} 61}
62 62
63static u32 get_adc_chan_step_mask(struct tiadc_device *adc_dev,
64 struct iio_chan_spec const *chan)
65{
66 int i;
67
68 for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
69 if (chan->channel == adc_dev->channel_line[i]) {
70 u32 step;
71
72 step = adc_dev->channel_step[i];
73 /* +1 for the charger */
74 return 1 << (step + 1);
75 }
76 }
77 WARN_ON(1);
78 return 0;
79}
80
63static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan) 81static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
64{ 82{
65 return 1 << adc_dev->channel_step[chan]; 83 return 1 << adc_dev->channel_step[chan];
@@ -181,7 +199,7 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
181 enb |= (get_adc_step_bit(adc_dev, bit) << 1); 199 enb |= (get_adc_step_bit(adc_dev, bit) << 1);
182 adc_dev->buffer_en_ch_steps = enb; 200 adc_dev->buffer_en_ch_steps = enb;
183 201
184 am335x_tsc_se_set(adc_dev->mfd_tscadc, enb); 202 am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, enb);
185 203
186 tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES 204 tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES
187 | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW); 205 | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
@@ -199,6 +217,7 @@ static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
199 tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES | 217 tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
200 IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW)); 218 IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
201 am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps); 219 am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
220 adc_dev->buffer_en_ch_steps = 0;
202 221
203 /* Flush FIFO of leftover data in the time it takes to disable adc */ 222 /* Flush FIFO of leftover data in the time it takes to disable adc */
204 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); 223 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
@@ -328,34 +347,43 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
328 unsigned int fifo1count, read, stepid; 347 unsigned int fifo1count, read, stepid;
329 bool found = false; 348 bool found = false;
330 u32 step_en; 349 u32 step_en;
331 unsigned long timeout = jiffies + usecs_to_jiffies 350 unsigned long timeout;
332 (IDLE_TIMEOUT * adc_dev->channels);
333 351
334 if (iio_buffer_enabled(indio_dev)) 352 if (iio_buffer_enabled(indio_dev))
335 return -EBUSY; 353 return -EBUSY;
336 354
337 step_en = get_adc_step_mask(adc_dev); 355 step_en = get_adc_chan_step_mask(adc_dev, chan);
338 am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); 356 if (!step_en)
357 return -EINVAL;
358
359 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
360 while (fifo1count--)
361 tiadc_readl(adc_dev, REG_FIFO1);
362
363 am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en);
339 364
340 /* Wait for ADC sequencer to complete sampling */ 365 timeout = jiffies + usecs_to_jiffies
341 while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) { 366 (IDLE_TIMEOUT * adc_dev->channels);
342 if (time_after(jiffies, timeout)) 367 /* Wait for Fifo threshold interrupt */
368 while (1) {
369 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
370 if (fifo1count)
371 break;
372
373 if (time_after(jiffies, timeout)) {
374 am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
343 return -EAGAIN; 375 return -EAGAIN;
344 } 376 }
377 }
345 map_val = chan->channel + TOTAL_CHANNELS; 378 map_val = chan->channel + TOTAL_CHANNELS;
346 379
347 /* 380 /*
348 * When the sub-system is first enabled, 381 * We check the complete FIFO. We programmed just one entry but in case
349 * the sequencer will always start with the 382 * something went wrong we left empty handed (-EAGAIN previously) and
350 * lowest step (1) and continue until step (16). 383 * then the value apeared somehow in the FIFO we would have two entries.
351 * For ex: If we have enabled 4 ADC channels and 384 * Therefore we read every item and keep only the latest version of the
352 * currently use only 1 out of them, the 385 * requested channel.
353 * sequencer still configures all the 4 steps,
354 * leading to 3 unwanted data.
355 * Hence we need to flush out this data.
356 */ 386 */
357
358 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
359 for (i = 0; i < fifo1count; i++) { 387 for (i = 0; i < fifo1count; i++) {
360 read = tiadc_readl(adc_dev, REG_FIFO1); 388 read = tiadc_readl(adc_dev, REG_FIFO1);
361 stepid = read & FIFOREAD_CHNLID_MASK; 389 stepid = read & FIFOREAD_CHNLID_MASK;
@@ -367,6 +395,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
367 *val = (u16) read; 395 *val = (u16) read;
368 } 396 }
369 } 397 }
398 am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
370 399
371 if (found == false) 400 if (found == false)
372 return -EBUSY; 401 return -EBUSY;
@@ -494,7 +523,8 @@ static int tiadc_resume(struct device *dev)
494 tiadc_writel(adc_dev, REG_CTRL, restore); 523 tiadc_writel(adc_dev, REG_CTRL, restore);
495 524
496 tiadc_step_config(indio_dev); 525 tiadc_step_config(indio_dev);
497 526 am335x_tsc_se_set_cache(adc_dev->mfd_tscadc,
527 adc_dev->buffer_en_ch_steps);
498 return 0; 528 return 0;
499} 529}
500 530
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 68beadaabceb..2ca5a7bee04e 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -198,7 +198,7 @@ static void titsc_step_config(struct titsc *ts_dev)
198 /* The steps1 … end and bit 0 for TS_Charge */ 198 /* The steps1 … end and bit 0 for TS_Charge */
199 stepenable = (1 << (end_step + 2)) - 1; 199 stepenable = (1 << (end_step + 2)) - 1;
200 ts_dev->step_mask = stepenable; 200 ts_dev->step_mask = stepenable;
201 am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask); 201 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
202} 202}
203 203
204static void titsc_read_coordinates(struct titsc *ts_dev, 204static void titsc_read_coordinates(struct titsc *ts_dev,
@@ -322,7 +322,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
322 322
323 if (irqclr) { 323 if (irqclr) {
324 titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); 324 titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
325 am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask); 325 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
326 return IRQ_HANDLED; 326 return IRQ_HANDLED;
327 } 327 }
328 return IRQ_NONE; 328 return IRQ_NONE;
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index 88718abfb9ba..d4e860413bb5 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -24,6 +24,7 @@
24#include <linux/pm_runtime.h> 24#include <linux/pm_runtime.h>
25#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/sched.h>
27 28
28#include <linux/mfd/ti_am335x_tscadc.h> 29#include <linux/mfd/ti_am335x_tscadc.h>
29 30
@@ -48,32 +49,79 @@ static const struct regmap_config tscadc_regmap_config = {
48 .val_bits = 32, 49 .val_bits = 32,
49}; 50};
50 51
51void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc) 52void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val)
52{ 53{
53 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache); 54 unsigned long flags;
55
56 spin_lock_irqsave(&tsadc->reg_lock, flags);
57 tsadc->reg_se_cache = val;
58 if (tsadc->adc_waiting)
59 wake_up(&tsadc->reg_se_wait);
60 else if (!tsadc->adc_in_use)
61 tscadc_writel(tsadc, REG_SE, val);
62
63 spin_unlock_irqrestore(&tsadc->reg_lock, flags);
64}
65EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache);
66
67static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc)
68{
69 DEFINE_WAIT(wait);
70 u32 reg;
71
72 /*
73 * disable TSC steps so it does not run while the ADC is using it. If
74 * write 0 while it is running (it just started or was already running)
75 * then it completes all steps that were enabled and stops then.
76 */
77 tscadc_writel(tsadc, REG_SE, 0);
78 reg = tscadc_readl(tsadc, REG_ADCFSM);
79 if (reg & SEQ_STATUS) {
80 tsadc->adc_waiting = true;
81 prepare_to_wait(&tsadc->reg_se_wait, &wait,
82 TASK_UNINTERRUPTIBLE);
83 spin_unlock_irq(&tsadc->reg_lock);
84
85 schedule();
86
87 spin_lock_irq(&tsadc->reg_lock);
88 finish_wait(&tsadc->reg_se_wait, &wait);
89
90 reg = tscadc_readl(tsadc, REG_ADCFSM);
91 WARN_ON(reg & SEQ_STATUS);
92 tsadc->adc_waiting = false;
93 }
94 tsadc->adc_in_use = true;
95}
96
97void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val)
98{
99 spin_lock_irq(&tsadc->reg_lock);
100 am335x_tscadc_need_adc(tsadc);
101
102 tscadc_writel(tsadc, REG_SE, val);
103 spin_unlock_irq(&tsadc->reg_lock);
54} 104}
55EXPORT_SYMBOL_GPL(am335x_tsc_se_update); 105EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
56 106
57void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val) 107void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc)
58{ 108{
59 unsigned long flags; 109 unsigned long flags;
60 110
61 spin_lock_irqsave(&tsadc->reg_lock, flags); 111 spin_lock_irqsave(&tsadc->reg_lock, flags);
62 tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE); 112 tsadc->adc_in_use = false;
63 tsadc->reg_se_cache |= val; 113 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
64 am335x_tsc_se_update(tsadc);
65 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 114 spin_unlock_irqrestore(&tsadc->reg_lock, flags);
66} 115}
67EXPORT_SYMBOL_GPL(am335x_tsc_se_set); 116EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done);
68 117
69void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val) 118void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
70{ 119{
71 unsigned long flags; 120 unsigned long flags;
72 121
73 spin_lock_irqsave(&tsadc->reg_lock, flags); 122 spin_lock_irqsave(&tsadc->reg_lock, flags);
74 tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE);
75 tsadc->reg_se_cache &= ~val; 123 tsadc->reg_se_cache &= ~val;
76 am335x_tsc_se_update(tsadc); 124 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
77 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 125 spin_unlock_irqrestore(&tsadc->reg_lock, flags);
78} 126}
79EXPORT_SYMBOL_GPL(am335x_tsc_se_clr); 127EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
@@ -181,6 +229,8 @@ static int ti_tscadc_probe(struct platform_device *pdev)
181 } 229 }
182 230
183 spin_lock_init(&tscadc->reg_lock); 231 spin_lock_init(&tscadc->reg_lock);
232 init_waitqueue_head(&tscadc->reg_se_wait);
233
184 pm_runtime_enable(&pdev->dev); 234 pm_runtime_enable(&pdev->dev);
185 pm_runtime_get_sync(&pdev->dev); 235 pm_runtime_get_sync(&pdev->dev);
186 236
@@ -302,7 +352,6 @@ static int tscadc_resume(struct device *dev)
302 352
303 if (tscadc_dev->tsc_cell != -1) 353 if (tscadc_dev->tsc_cell != -1)
304 tscadc_idle_config(tscadc_dev); 354 tscadc_idle_config(tscadc_dev);
305 am335x_tsc_se_update(tscadc_dev);
306 restore = tscadc_readl(tscadc_dev, REG_CTRL); 355 restore = tscadc_readl(tscadc_dev, REG_CTRL);
307 tscadc_writel(tscadc_dev, REG_CTRL, 356 tscadc_writel(tscadc_dev, REG_CTRL,
308 (restore | CNTRLREG_TSCSSENB)); 357 (restore | CNTRLREG_TSCSSENB));
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index d498d98f0c2c..fb96c84dada5 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -159,6 +159,9 @@ struct ti_tscadc_dev {
159 int adc_cell; /* -1 if not used */ 159 int adc_cell; /* -1 if not used */
160 struct mfd_cell cells[TSCADC_CELLS]; 160 struct mfd_cell cells[TSCADC_CELLS];
161 u32 reg_se_cache; 161 u32 reg_se_cache;
162 bool adc_waiting;
163 bool adc_in_use;
164 wait_queue_head_t reg_se_wait;
162 spinlock_t reg_lock; 165 spinlock_t reg_lock;
163 unsigned int clk_div; 166 unsigned int clk_div;
164 167
@@ -176,8 +179,9 @@ static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
176 return *tscadc_dev; 179 return *tscadc_dev;
177} 180}
178 181
179void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc); 182void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val);
180void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val); 183void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val);
181void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val); 184void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val);
185void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc);
182 186
183#endif 187#endif