aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c64
-rw-r--r--drivers/mfd/ti_am335x_tscadc.c63
-rw-r--r--include/linux/mfd/ti_am335x_tscadc.h4
3 files changed, 103 insertions, 28 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index e0dc2d0e7590..dff7343405e2 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];
@@ -326,34 +344,43 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
326 unsigned int fifo1count, read, stepid; 344 unsigned int fifo1count, read, stepid;
327 bool found = false; 345 bool found = false;
328 u32 step_en; 346 u32 step_en;
329 unsigned long timeout = jiffies + usecs_to_jiffies 347 unsigned long timeout;
330 (IDLE_TIMEOUT * adc_dev->channels);
331 348
332 if (iio_buffer_enabled(indio_dev)) 349 if (iio_buffer_enabled(indio_dev))
333 return -EBUSY; 350 return -EBUSY;
334 351
335 step_en = get_adc_step_mask(adc_dev); 352 step_en = get_adc_chan_step_mask(adc_dev, chan);
353 if (!step_en)
354 return -EINVAL;
355
356 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
357 while (fifo1count--)
358 tiadc_readl(adc_dev, REG_FIFO1);
359
336 am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en); 360 am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en);
337 361
338 /* Wait for ADC sequencer to complete sampling */ 362 timeout = jiffies + usecs_to_jiffies
339 while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) { 363 (IDLE_TIMEOUT * adc_dev->channels);
340 if (time_after(jiffies, timeout)) 364 /* Wait for Fifo threshold interrupt */
365 while (1) {
366 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
367 if (fifo1count)
368 break;
369
370 if (time_after(jiffies, timeout)) {
371 am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
341 return -EAGAIN; 372 return -EAGAIN;
373 }
342 } 374 }
343 map_val = chan->channel + TOTAL_CHANNELS; 375 map_val = chan->channel + TOTAL_CHANNELS;
344 376
345 /* 377 /*
346 * When the sub-system is first enabled, 378 * We check the complete FIFO. We programmed just one entry but in case
347 * the sequencer will always start with the 379 * something went wrong we left empty handed (-EAGAIN previously) and
348 * lowest step (1) and continue until step (16). 380 * then the value apeared somehow in the FIFO we would have two entries.
349 * For ex: If we have enabled 4 ADC channels and 381 * Therefore we read every item and keep only the latest version of the
350 * currently use only 1 out of them, the 382 * requested channel.
351 * sequencer still configures all the 4 steps,
352 * leading to 3 unwanted data.
353 * Hence we need to flush out this data.
354 */ 383 */
355
356 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
357 for (i = 0; i < fifo1count; i++) { 384 for (i = 0; i < fifo1count; i++) {
358 read = tiadc_readl(adc_dev, REG_FIFO1); 385 read = tiadc_readl(adc_dev, REG_FIFO1);
359 stepid = read & FIFOREAD_CHNLID_MASK; 386 stepid = read & FIFOREAD_CHNLID_MASK;
@@ -365,6 +392,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
365 *val = (u16) read; 392 *val = (u16) read;
366 } 393 }
367 } 394 }
395 am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
368 396
369 if (found == false) 397 if (found == false)
370 return -EBUSY; 398 return -EBUSY;
@@ -492,8 +520,8 @@ static int tiadc_resume(struct device *dev)
492 tiadc_writel(adc_dev, REG_CTRL, restore); 520 tiadc_writel(adc_dev, REG_CTRL, restore);
493 521
494 tiadc_step_config(indio_dev); 522 tiadc_step_config(indio_dev);
495 am335x_tsc_se_set(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps); 523 am335x_tsc_se_set_cache(adc_dev->mfd_tscadc,
496 524 adc_dev->buffer_en_ch_steps);
497 return 0; 525 return 0;
498} 526}
499 527
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index 157f5699a33c..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,31 +49,71 @@ static const struct regmap_config tscadc_regmap_config = {
48 .val_bits = 32, 49 .val_bits = 32,
49}; 50};
50 51
51static void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc)
52{
53 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
54}
55
56void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val) 52void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val)
57{ 53{
58 unsigned long flags; 54 unsigned long flags;
59 55
60 spin_lock_irqsave(&tsadc->reg_lock, flags); 56 spin_lock_irqsave(&tsadc->reg_lock, flags);
61 tsadc->reg_se_cache |= val; 57 tsadc->reg_se_cache = val;
62 am335x_tsc_se_update(tsadc); 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); 63 spin_unlock_irqrestore(&tsadc->reg_lock, flags);
64} 64}
65EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache); 65EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache);
66 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
67void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val) 97void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val)
68{ 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);
104}
105EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
106
107void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc)
108{
69 unsigned long flags; 109 unsigned long flags;
70 110
71 spin_lock_irqsave(&tsadc->reg_lock, flags); 111 spin_lock_irqsave(&tsadc->reg_lock, flags);
72 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache | val); 112 tsadc->adc_in_use = false;
113 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
73 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 114 spin_unlock_irqrestore(&tsadc->reg_lock, flags);
74} 115}
75EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once); 116EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done);
76 117
77void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val) 118void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
78{ 119{
@@ -80,7 +121,7 @@ void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
80 121
81 spin_lock_irqsave(&tsadc->reg_lock, flags); 122 spin_lock_irqsave(&tsadc->reg_lock, flags);
82 tsadc->reg_se_cache &= ~val; 123 tsadc->reg_se_cache &= ~val;
83 am335x_tsc_se_update(tsadc); 124 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
84 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 125 spin_unlock_irqrestore(&tsadc->reg_lock, flags);
85} 126}
86EXPORT_SYMBOL_GPL(am335x_tsc_se_clr); 127EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
@@ -188,6 +229,8 @@ static int ti_tscadc_probe(struct platform_device *pdev)
188 } 229 }
189 230
190 spin_lock_init(&tscadc->reg_lock); 231 spin_lock_init(&tscadc->reg_lock);
232 init_waitqueue_head(&tscadc->reg_se_wait);
233
191 pm_runtime_enable(&pdev->dev); 234 pm_runtime_enable(&pdev->dev);
192 pm_runtime_get_sync(&pdev->dev); 235 pm_runtime_get_sync(&pdev->dev);
193 236
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index 2fa9c0613da4..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
@@ -179,5 +182,6 @@ static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
179void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val); 182void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val);
180void am335x_tsc_se_set_once(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