diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 10:58:17 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 10:58:17 -0800 |
commit | ac26663572db5b64522b92f3941a58678a832a36 (patch) | |
tree | 3a8d27153de37cb3f3fb0ff6843a1e727c961005 /drivers/iio/adc | |
parent | d4371f94bc003e912d4825f5c4bdf57959857073 (diff) | |
parent | 02915661dbb91b25b621ab3f387ab55311bded7f (diff) | |
download | linux-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.c | 68 |
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; } |