diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-04-04 12:31:05 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-04-04 12:31:05 -0700 |
commit | eb7bfed901b9fea6e48bec10009dc8c8641e36e7 (patch) | |
tree | e03df0b64ecdfc3c51bf0bbdd2f96cd2a6348a7a /drivers/iio/adc/at91-sama5d2_adc.c | |
parent | 56d118c243fbc62d95a79183bb6bcfc38a398da5 (diff) | |
parent | 486294f184c05cff116160bb731cbb679f047621 (diff) |
Merge tag 'iio-for-4.7a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
First round of IIO new device support, features and cleanups for the 4.7 cycle.
New core support
* UV light modifier (for intensity)
* UV light index channel type.
New device support
* hp206c barometer and altimeter
- new driver.
* mcp4131 potentiometer
- new driver supporting lots of parts from Microchip.
* mma8452
- FXLS8471Q support
- NXP LPC18XX SOC ADC
- new driver.
- NXP LPC18XX SOC DAC
- new driver.
- rockchip_saradc
- support rk3399
* st accel
- h3lis331dl support
Staging driver removals
* adis16204
- obsolete part making it hard to get parts to test the driver in order
to clean it up.
* adis16220
- obsolete part making it hard to get the parts test the driver in order
to clean it up.
Features
* core
- convenience functions to claim / release direct access to the device.
Makes more consistent handling of this corner easier. Used in ad7192 driver.
* ak8975
- power regulator support.
* at91-sama5d2
- differential channel support.
* mma8452
- runtime pm support
- drop device specific autosleep and use the runtime pm one instead.
* ms5611
- DT bindings
- oversampling ratio support
Cleanups and minor fixes
* MAINTAINERS
- Peter got married - hence name change!
* Documentation
- Fix a typo in in_proximity_raw description.
- Add some missing docs for iio_buffer_access_funcs.
* Tools
- update iio_event_monitor names to match new stuff.
- make generic_buffer look for triggers ending in -trigger as we let these in
for a number of drivers a long time back and now it is a fairly common
option.
Drivers
* staging wide
- convert bare unsigned usage to unsigned int to comply with coding style.
* non staging wide:
- since boiler plate gpio handling of interrupts has been moved into the
ACPI core we don't need to include gpio/consumer.h in a load of drivers so
drop it.
* ad7606
- fix an endian casting sparse warning.
* ak8975
- fix a possible unitialized warning from gcc.
- drop and unused field left over from earlier cleanups
- fix a missing regulator_disable on exit.
* at91-sama5d2
- typo and indentation
- missing IOMEM dependency.
- cleanup mode register usage by avoidling erasing whole thing when changing
the sampling frequency.
* bmc150
- use the core demux and available_scan_masks to simplify buffer handling
- optimize the transfers in the trigger handler now we have a magic function
to emulate bulk reads (under circumstances met here). This matters with some
rather dumb i2c adapters in particular.
- use a single regmap_conf for all bus types as they were all the same.
* bmg160
- use the core demux and available_scan_masks to simplify the buffer handling
- optimize the transfers in the trigger handler now we have a magic funciton
to emulate bulk rads (under circumstances met here).
- drop gpio interrupt probing from the driver (ACPI) as now handled by the
ACPI core.
* ina2xx-adc
- update the CALIB register when RShunt changes.
- fix scale for VShunt - in reality this error canceled out when used.
* isl29028
- use regmap to retrieve the struct device instead of carrying a second
copy of it around.
* kxcjk-1013
- use core demux
- optimize i2c transfers in the trigger handler.
* mcp4531
- refactor to use a pointer to access model parameters instead of indexing
into the array each time.
* mma8452
- style fixes
- avoid swtiching to active whenever the config changes
- add missin i2c_device_id for mma8451
* mpu6050
- fix possible NULL dereference.
- fix the name / chip_id used when ACPI used (otherwise reports as NULL).
* ms5611
- fix a missing regulator_disable that left the regulator on during removal.
* mxc4005
- drop gpio interrupt handling for ACPI case from driver as the core now
handles this case.
* st-sensors
- note that there are only ever a maximum of 3 axis on current st-sensors
so just allocate a fixed sized buffer big enough for that.
* tpl0102
- change the i2c_check_functionality condition to bring it inline with other
IIO users as EOPNOTSUPP.
* tsl2563
- replace deprecated flush_scheduled_work
Diffstat (limited to 'drivers/iio/adc/at91-sama5d2_adc.c')
-rw-r--r-- | drivers/iio/adc/at91-sama5d2_adc.c | 102 |
1 files changed, 74 insertions, 28 deletions
diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index dbee13ad33a3..07adb1070fc2 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -66,8 +66,10 @@ #define AT91_SAMA5D2_MR_PRESCAL(v) ((v) << AT91_SAMA5D2_MR_PRESCAL_OFFSET) #define AT91_SAMA5D2_MR_PRESCAL_OFFSET 8 #define AT91_SAMA5D2_MR_PRESCAL_MAX 0xff +#define AT91_SAMA5D2_MR_PRESCAL_MASK GENMASK(15, 8) /* Startup Time */ #define AT91_SAMA5D2_MR_STARTUP(v) ((v) << 16) +#define AT91_SAMA5D2_MR_STARTUP_MASK GENMASK(19, 16) /* Analog Change */ #define AT91_SAMA5D2_MR_ANACH BIT(23) /* Tracking Time */ @@ -92,13 +94,13 @@ /* Last Converted Data Register */ #define AT91_SAMA5D2_LCDR 0x20 /* Interrupt Enable Register */ -#define AT91_SAMA5D2_IER 0x24 +#define AT91_SAMA5D2_IER 0x24 /* Interrupt Disable Register */ -#define AT91_SAMA5D2_IDR 0x28 +#define AT91_SAMA5D2_IDR 0x28 /* Interrupt Mask Register */ -#define AT91_SAMA5D2_IMR 0x2c +#define AT91_SAMA5D2_IMR 0x2c /* Interrupt Status Register */ -#define AT91_SAMA5D2_ISR 0x30 +#define AT91_SAMA5D2_ISR 0x30 /* Last Channel Trigger Mode Register */ #define AT91_SAMA5D2_LCTMR 0x34 /* Last Channel Compare Window Register */ @@ -106,17 +108,20 @@ /* Overrun Status Register */ #define AT91_SAMA5D2_OVER 0x3c /* Extended Mode Register */ -#define AT91_SAMA5D2_EMR 0x40 +#define AT91_SAMA5D2_EMR 0x40 /* Compare Window Register */ -#define AT91_SAMA5D2_CWR 0x44 +#define AT91_SAMA5D2_CWR 0x44 /* Channel Gain Register */ -#define AT91_SAMA5D2_CGR 0x48 +#define AT91_SAMA5D2_CGR 0x48 + /* Channel Offset Register */ -#define AT91_SAMA5D2_COR 0x4c +#define AT91_SAMA5D2_COR 0x4c +#define AT91_SAMA5D2_COR_DIFF_OFFSET 16 + /* Channel Data Register 0 */ #define AT91_SAMA5D2_CDR0 0x50 /* Analog Control Register */ -#define AT91_SAMA5D2_ACR 0x94 +#define AT91_SAMA5D2_ACR 0x94 /* Touchscreen Mode Register */ #define AT91_SAMA5D2_TSMR 0xb0 /* Touchscreen X Position Register */ @@ -130,7 +135,7 @@ /* Correction Select Register */ #define AT91_SAMA5D2_COSR 0xd0 /* Correction Value Register */ -#define AT91_SAMA5D2_CVR 0xd4 +#define AT91_SAMA5D2_CVR 0xd4 /* Channel Error Correction Register */ #define AT91_SAMA5D2_CECR 0xd8 /* Write Protection Mode Register */ @@ -140,7 +145,7 @@ /* Version Register */ #define AT91_SAMA5D2_VERSION 0xfc -#define AT91_AT91_SAMA5D2_CHAN(num, addr) \ +#define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \ { \ .type = IIO_VOLTAGE, \ .channel = num, \ @@ -156,6 +161,24 @@ .indexed = 1, \ } +#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr) \ + { \ + .type = IIO_VOLTAGE, \ + .differential = 1, \ + .channel = num, \ + .channel2 = num2, \ + .address = addr, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ + .datasheet_name = "CH"#num"-CH"#num2, \ + .indexed = 1, \ + } + #define at91_adc_readl(st, reg) readl_relaxed(st->base + reg) #define at91_adc_writel(st, reg, val) writel_relaxed(val, st->base + reg) @@ -185,18 +208,24 @@ struct at91_adc_state { }; static const struct iio_chan_spec at91_adc_channels[] = { - AT91_AT91_SAMA5D2_CHAN(0, 0x50), - AT91_AT91_SAMA5D2_CHAN(1, 0x54), - AT91_AT91_SAMA5D2_CHAN(2, 0x58), - AT91_AT91_SAMA5D2_CHAN(3, 0x5c), - AT91_AT91_SAMA5D2_CHAN(4, 0x60), - AT91_AT91_SAMA5D2_CHAN(5, 0x64), - AT91_AT91_SAMA5D2_CHAN(6, 0x68), - AT91_AT91_SAMA5D2_CHAN(7, 0x6c), - AT91_AT91_SAMA5D2_CHAN(8, 0x70), - AT91_AT91_SAMA5D2_CHAN(9, 0x74), - AT91_AT91_SAMA5D2_CHAN(10, 0x78), - AT91_AT91_SAMA5D2_CHAN(11, 0x7c), + AT91_SAMA5D2_CHAN_SINGLE(0, 0x50), + AT91_SAMA5D2_CHAN_SINGLE(1, 0x54), + AT91_SAMA5D2_CHAN_SINGLE(2, 0x58), + AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c), + AT91_SAMA5D2_CHAN_SINGLE(4, 0x60), + AT91_SAMA5D2_CHAN_SINGLE(5, 0x64), + AT91_SAMA5D2_CHAN_SINGLE(6, 0x68), + AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c), + AT91_SAMA5D2_CHAN_SINGLE(8, 0x70), + AT91_SAMA5D2_CHAN_SINGLE(9, 0x74), + AT91_SAMA5D2_CHAN_SINGLE(10, 0x78), + AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c), + AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50), + AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58), + AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60), + AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68), + AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70), + AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78), }; static unsigned at91_adc_startup_time(unsigned startup_time_min, @@ -226,7 +255,7 @@ static unsigned at91_adc_startup_time(unsigned startup_time_min, static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) { struct iio_dev *indio_dev = iio_priv_to_dev(st); - unsigned f_per, prescal, startup; + unsigned f_per, prescal, startup, mr; f_per = clk_get_rate(st->per_clk); prescal = (f_per / (2 * freq)) - 1; @@ -234,10 +263,11 @@ static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) startup = at91_adc_startup_time(st->soc_info.startup_time, freq / 1000); - at91_adc_writel(st, AT91_SAMA5D2_MR, - AT91_SAMA5D2_MR_TRANSFER(2) - | AT91_SAMA5D2_MR_STARTUP(startup) - | AT91_SAMA5D2_MR_PRESCAL(prescal)); + mr = at91_adc_readl(st, AT91_SAMA5D2_MR); + mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK); + mr |= AT91_SAMA5D2_MR_STARTUP(startup); + mr |= AT91_SAMA5D2_MR_PRESCAL(prescal); + at91_adc_writel(st, AT91_SAMA5D2_MR, mr); dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n", freq, startup, prescal); @@ -278,6 +308,7 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct at91_adc_state *st = iio_priv(indio_dev); + u32 cor = 0; int ret; switch (mask) { @@ -286,6 +317,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, st->chan = chan; + if (chan->differential) + cor = (BIT(chan->channel) | BIT(chan->channel2)) << + AT91_SAMA5D2_COR_DIFF_OFFSET; + + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel)); at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START); @@ -298,6 +334,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, if (ret > 0) { *val = st->conversion_value; + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, 11); ret = IIO_VAL_INT; st->conversion_done = false; } @@ -310,6 +348,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: *val = st->vref_uv / 1000; + if (chan->differential) + *val *= 2; *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; @@ -444,6 +484,12 @@ static int at91_adc_probe(struct platform_device *pdev) at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); + /* + * Transfer field must be set to 2 according to the datasheet and + * allows different analog settings for each channel. + */ + at91_adc_writel(st, AT91_SAMA5D2_MR, + AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); |