summaryrefslogtreecommitdiffstats
path: root/drivers/iio/adc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 10:58:17 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 10:58:17 -0800
commitac26663572db5b64522b92f3941a58678a832a36 (patch)
tree3a8d27153de37cb3f3fb0ff6843a1e727c961005 /drivers/iio/adc
parentd4371f94bc003e912d4825f5c4bdf57959857073 (diff)
parent02915661dbb91b25b621ab3f387ab55311bded7f (diff)
downloadlinux-ac26663572db5b64522b92f3941a58678a832a36.tar.bz2
Merge tag 'mfd-3.14-1' of git://git.linaro.org/people/ljones/mfd
Pull MFD changes from Lee Jones: "New drivers - Samsung Maxim 14577; Micro USB, Regulator, IRQ Controller and Battery Charger - TI/National Semiconductor LP3943 I2C GPIO Expander and PWM Generator Existing driver adaptions - Expansion of Wolfson Arizona DSP and High-Pass filter controls - TI TWL6040 default Regmap support and Regcache addition/bypass - Some nice Smatch catch fixes - Conversion of TI OMAP-USB and TI TWL6030 to endian neutralness - ChromeOS EC timing (delay) adaptions and added dependency on OF - Many constifications of 'struct {mfd_cell,regmap_irq,et.al}' - Watchdog support added for NVIDIA AS3722 - Convert functions to static in TI AM335x - Realigned previously defeated functionality in TI AM335x - IIO ADC-TSC concurrency dead-lock/timeout resolution - Addition of Power Management and Clock support for Samsung core - DEFINE_PCI_DEVICE_TABLE macro removal from MFD Subsystem - Greater use of irqdomain functionality in ST-E AB8500 - Removal of 'include/linux/mfd/abx500/ab8500-gpio.h' - Wolfson WM831x PMIC Power Management changes s/poweroff/shutdown/ - Device Tree documentation added for TI/Nat Semi LP3943 - Version detection and voltage tables for TI TPS6586x PMIC devices - Simplification of Freescale MC13XXX (de-)initialisation routines - Clean-up and simplification of the Realtek parent driver - Added support for RTL8402 Realtek PCI-Express card reader - Resource leak fix for Maxim 77686 - Possible suspend BUG() fix in OMAP USB TLL - Support for new Wolfson WM5110 Revision (D) - Testing of automatic assignment of of_node in mfd_add_device() - Reversion of the above when it started to cause issues - Remove legacy Platform Data from; TI TWL Core, Qualcomm SSBI and ST-E ABx500 Pinctrl - Clean-ups; tabbing issues, function name changes, 'drvdata = NULL' removal, unused uninitialised warning mitigation, error message clarity, removal of redundant/duplicate checks, licensing (GPL -> GPL2), coding consistency, duplicate function declaration, ret checks, commit corrections, redundant of_match_ptr() helper removal, spelling, #if-deffery removal and header guards name changes" * tag 'mfd-3.14-1' of git://git.linaro.org/people/ljones/mfd: (78 commits) mfd: wm5110: Add register patch for rev D chip mfd: omap-usb-tll: Don't hold lock during pm_runtime_get/put_sync() gpio: lp3943: Remove redundant of_match_ptr helper mfd: sta2x11-mfd: Use named constants for pci_power_t values Documentation: mfd: Fix LDO index in s2mps11.txt mfd: Cleanup mfd-mcp-sa11x0.h header mfd: max8997: Use "IS_ENABLED(CONFIG_OF)" for DT code. mfd: twl6030: Fix endianness problem in IRQ handler mfd: sec-core: Add cells for S5M8767-clocks mfd: max14577: Remove redundant of_match_ptr helper mfd: twl6040: Fix sparse non static symbol warning mfd: Revert "mfd: Always assign of_node in mfd_add_device()" mfd: rtsx: Fix sparse non static symbol warning mfd: max77693: Set proper maximum register for MUIC regmap mfd: max77686: Fix regmap resource leak on driver remove mfd: Represent correct filenames in file headers mfd: rtsx: Add support for card reader rtl8402 mfd: rtsx: Add set pull control macro and simplify rtl8411 mfd: max8997: Enforce mfd_add_devices() return value check mfd: mc13xxx: Simplify probe() & remove() ...
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c68
1 files changed, 49 insertions, 19 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)
return step_en;
}
+static u32 get_adc_chan_step_mask(struct tiadc_device *adc_dev,
+ struct iio_chan_spec const *chan)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
+ if (chan->channel == adc_dev->channel_line[i]) {
+ u32 step;
+
+ step = adc_dev->channel_step[i];
+ /* +1 for the charger */
+ return 1 << (step + 1);
+ }
+ }
+ WARN_ON(1);
+ return 0;
+}
+
static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
{
return 1 << adc_dev->channel_step[chan];
@@ -181,7 +199,7 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
enb |= (get_adc_step_bit(adc_dev, bit) << 1);
adc_dev->buffer_en_ch_steps = enb;
- am335x_tsc_se_set(adc_dev->mfd_tscadc, enb);
+ am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, enb);
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES
| IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
@@ -199,6 +217,7 @@ static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
+ adc_dev->buffer_en_ch_steps = 0;
/* Flush FIFO of leftover data in the time it takes to disable adc */
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
@@ -328,34 +347,43 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
unsigned int fifo1count, read, stepid;
bool found = false;
u32 step_en;
- unsigned long timeout = jiffies + usecs_to_jiffies
- (IDLE_TIMEOUT * adc_dev->channels);
+ unsigned long timeout;
if (iio_buffer_enabled(indio_dev))
return -EBUSY;
- step_en = get_adc_step_mask(adc_dev);
- am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+ step_en = get_adc_chan_step_mask(adc_dev, chan);
+ if (!step_en)
+ return -EINVAL;
+
+ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+ while (fifo1count--)
+ tiadc_readl(adc_dev, REG_FIFO1);
+
+ 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) {
- if (time_after(jiffies, timeout))
+ timeout = jiffies + usecs_to_jiffies
+ (IDLE_TIMEOUT * adc_dev->channels);
+ /* Wait for Fifo threshold interrupt */
+ while (1) {
+ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+ if (fifo1count)
+ break;
+
+ if (time_after(jiffies, timeout)) {
+ am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
return -EAGAIN;
}
+ }
map_val = chan->channel + TOTAL_CHANNELS;
/*
- * When the sub-system is first enabled,
- * the sequencer will always start with the
- * lowest step (1) and continue until step (16).
- * For ex: If we have enabled 4 ADC channels and
- * currently use only 1 out of them, the
- * sequencer still configures all the 4 steps,
- * leading to 3 unwanted data.
- * Hence we need to flush out this data.
+ * We check the complete FIFO. We programmed just one entry but in case
+ * something went wrong we left empty handed (-EAGAIN previously) and
+ * then the value apeared somehow in the FIFO we would have two entries.
+ * Therefore we read every item and keep only the latest version of the
+ * requested channel.
*/
-
- fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (i = 0; i < fifo1count; i++) {
read = tiadc_readl(adc_dev, REG_FIFO1);
stepid = read & FIFOREAD_CHNLID_MASK;
@@ -367,6 +395,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
*val = (u16) read;
}
}
+ am335x_tsc_se_adc_done(adc_dev->mfd_tscadc);
if (found == false)
return -EBUSY;
@@ -494,7 +523,8 @@ static int tiadc_resume(struct device *dev)
tiadc_writel(adc_dev, REG_CTRL, restore);
tiadc_step_config(indio_dev);
-
+ am335x_tsc_se_set_cache(adc_dev->mfd_tscadc,
+ adc_dev->buffer_en_ch_steps);
return 0;
}