summaryrefslogtreecommitdiff
path: root/drivers/staging/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Documentation/sysfs-bus-iio-light28
-rw-r--r--drivers/staging/iio/Kconfig1
-rw-r--r--drivers/staging/iio/Makefile1
-rw-r--r--drivers/staging/iio/TODO8
-rw-r--r--drivers/staging/iio/accel/lis3l02dq.h15
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c4
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c3
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c3
-rw-r--r--drivers/staging/iio/adc/Kconfig18
-rw-r--r--drivers/staging/iio/adc/Makefile1
-rw-r--r--drivers/staging/iio/adc/ad7192.c78
-rw-r--r--drivers/staging/iio/adc/ad7280a.c4
-rw-r--r--drivers/staging/iio/adc/ad7606.h10
-rw-r--r--drivers/staging/iio/adc/ad7606_core.c53
-rw-r--r--drivers/staging/iio/adc/ad7606_par.c32
-rw-r--r--drivers/staging/iio/adc/ad7606_spi.c32
-rw-r--r--drivers/staging/iio/adc/ad7816.c4
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c1770
-rw-r--r--drivers/staging/iio/adc/spear_adc.c33
-rw-r--r--drivers/staging/iio/addac/adt7316-i2c.c2
-rw-r--r--drivers/staging/iio/addac/adt7316.c15
-rw-r--r--drivers/staging/iio/cdc/ad7150.c34
-rw-r--r--drivers/staging/iio/cdc/ad7746.c4
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c8
-rw-r--r--drivers/staging/iio/light/isl29018.c75
-rw-r--r--drivers/staging/iio/light/isl29028.c31
-rw-r--r--drivers/staging/iio/light/tsl2583.c92
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c8
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig40
-rw-r--r--drivers/staging/iio/magnetometer/Makefile7
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.h66
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_core.c646
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_i2c.c104
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_spi.c101
-rw-r--r--drivers/staging/iio/meter/ade7754.c5
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c5
-rw-r--r--drivers/staging/iio/meter/ade7854-i2c.c6
-rw-r--r--drivers/staging/iio/meter/ade7854-spi.c7
-rw-r--r--drivers/staging/iio/meter/ade7854.c25
-rw-r--r--drivers/staging/iio/resolver/ad2s1200.c12
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c39
-rw-r--r--drivers/staging/iio/trigger/Kconfig10
-rw-r--r--drivers/staging/iio/trigger/Makefile1
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c216
44 files changed, 313 insertions, 3344 deletions
diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light
index 17e5c9c51..7c7cd8456 100644
--- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light
+++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light
@@ -1,31 +1,3 @@
-
-What: /sys/bus/iio/devices/device[n]/range
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- Hardware dependent ADC Full Scale Range used for some ambient
- light sensors in calculating lux.
-
-What: /sys/bus/iio/devices/device[n]/range_available
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- Hardware dependent supported vales for ADC Full Scale Range.
-
-What: /sys/bus/iio/devices/device[n]/adc_resolution
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- Hardware dependent ADC resolution of the ambient light sensor
- used in calculating the lux.
-
-What: /sys/bus/iio/devices/device[n]/adc_resolution_available
-KernelVersion: 2.6.37
-Contact: linux-iio@vger.kernel.org
-Description:
- Hardware dependent list of possible values supported for the
- adc_resolution of the given sensor.
-
What: /sys/bus/iio/devices/device[n]/in_illuminance0[_input|_raw]
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index 0e044cb0d..8abc1ab3c 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -12,7 +12,6 @@ source "drivers/staging/iio/frequency/Kconfig"
source "drivers/staging/iio/gyro/Kconfig"
source "drivers/staging/iio/impedance-analyzer/Kconfig"
source "drivers/staging/iio/light/Kconfig"
-source "drivers/staging/iio/magnetometer/Kconfig"
source "drivers/staging/iio/meter/Kconfig"
source "drivers/staging/iio/resolver/Kconfig"
source "drivers/staging/iio/trigger/Kconfig"
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
index 3e616b443..0cfd05d5b 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -10,7 +10,6 @@ obj-y += frequency/
obj-y += gyro/
obj-y += impedance-analyzer/
obj-y += light/
-obj-y += magnetometer/
obj-y += meter/
obj-y += resolver/
obj-y += trigger/
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
index c22a0edd1..93a896883 100644
--- a/drivers/staging/iio/TODO
+++ b/drivers/staging/iio/TODO
@@ -58,14 +58,6 @@ different requirements. This one suits mid range
frequencies (100Hz - 4kHz).
2) Lots of testing
-Periodic Timer trigger
-1) Move to a more general hardware periodic timer request
-subsystem. Current approach is abusing purpose of RTC.
-Initial discussions have taken place, but no actual code
-is in place as yet. This topic will be reopened on lkml
-shortly. I don't really envision this patch being merged
-in anything like its current form.
-
GPIO trigger
1) Add control over the type of interrupt etc. This will
necessitate a header that is also visible from arch board
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 3f24c629b..6bd3d4d5b 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -67,7 +67,8 @@
#define LIS3L02DQ_REG_CTRL_2_THREE_WIRE_SPI_MODE 0x02
/* Data alignment, default is 12 bit right justified
- * - option for 16 bit left justified */
+ * - option for 16 bit left justified
+ */
#define LIS3L02DQ_REG_CTRL_2_DATA_ALIGNMENT_16_BIT_LEFT_JUSTIFIED 0x01
/* Interrupt related stuff */
@@ -77,7 +78,8 @@
#define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND 0x80
/* Latch interrupt request,
- * if on ack must be given by reading the ack register */
+ * if on ack must be given by reading the ack register
+ */
#define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC 0x40
/* Z Interrupt on High (above threshold) */
@@ -94,7 +96,8 @@
#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01
/* Register that gives description of what caused interrupt
- * - latched if set in CFG_ADDRES */
+ * - latched if set in CFG_ADDRES
+ */
#define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR 0x24
/* top bit ignored */
/* Interrupt Active */
@@ -123,7 +126,8 @@
#define LIS3L02DQ_REG_STATUS_X_NEW_DATA 0x01
/* The accelerometer readings - low and high bytes.
- * Form of high byte dependent on justification set in ctrl reg */
+ * Form of high byte dependent on justification set in ctrl reg
+ */
#define LIS3L02DQ_REG_OUT_X_L_ADDR 0x28
#define LIS3L02DQ_REG_OUT_X_H_ADDR 0x29
#define LIS3L02DQ_REG_OUT_Y_L_ADDR 0x2A
@@ -132,7 +136,8 @@
#define LIS3L02DQ_REG_OUT_Z_H_ADDR 0x2D
/* Threshold values for all axes and both above and below thresholds
- * - i.e. there is only one value */
+ * - i.e. there is only one value
+ */
#define LIS3L02DQ_REG_THS_L_ADDR 0x2E
#define LIS3L02DQ_REG_THS_H_ADDR 0x2F
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 7939ae637..7a6fed3f2 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -567,7 +567,7 @@ static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
{
u8 val;
int ret;
- u8 mask = (1 << (chan->channel2 * 2 + (dir == IIO_EV_DIR_RISING)));
+ u8 mask = 1 << (chan->channel2 * 2 + (dir == IIO_EV_DIR_RISING));
ret = lis3l02dq_spi_read_reg_8(indio_dev,
LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
@@ -622,7 +622,7 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
u8 val, control;
u8 currentlyset;
bool changed = false;
- u8 mask = (1 << (chan->channel2 * 2 + (dir == IIO_EV_DIR_RISING)));
+ u8 mask = 1 << (chan->channel2 * 2 + (dir == IIO_EV_DIR_RISING));
mutex_lock(&indio_dev->mlock);
/* read current control */
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 02e930c55..a8f533af9 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -216,8 +216,7 @@ static int sca3000_read_ctrl_reg(struct sca3000_state *st,
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_CTRL_DATA, 1);
if (ret)
goto error_ret;
- else
- return st->rx[0];
+ return st->rx[0];
error_ret:
return ret;
}
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 1920dc60c..d1cb9b9cf 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -99,8 +99,7 @@ static int sca3000_read_first_n_hw_rb(struct iio_buffer *r,
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_BUF_COUNT, 1);
if (ret)
goto error_ret;
- else
- num_available = st->rx[0];
+ num_available = st->rx[0];
/*
* num_available is the total number of samples available
* i.e. number of time points * number of channels.
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index b9519be90..deff89973 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -59,12 +59,12 @@ config AD7816
temperature sensors and ADC.
config AD7192
- tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver"
+ tristate "Analog Devices AD7190 AD7192 AD7193 AD7195 ADC driver"
depends on SPI
select AD_SIGMA_DELTA
help
Say yes here to build support for Analog Devices AD7190,
- AD7192 or AD7195 SPI analog to digital converters (ADC).
+ AD7192, AD7193 or AD7195 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
@@ -92,20 +92,6 @@ config LPC32XX_ADC
activate only one via device tree selection. Provides direct access
via sysfs.
-config MXS_LRADC
- tristate "Freescale i.MX23/i.MX28 LRADC"
- depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
- depends on INPUT
- select STMP_DEVICE
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- help
- Say yes here to build support for i.MX23/i.MX28 LRADC convertor
- built into these chips.
-
- To compile this driver as a module, choose M here: the
- module will be called mxs-lradc.
-
config SPEAR_ADC
tristate "ST SPEAr ADC"
depends on PLAT_SPEAR || COMPILE_TEST
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index 0c87ce353..3cdd83cce 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -12,5 +12,4 @@ obj-$(CONFIG_AD7816) += ad7816.o
obj-$(CONFIG_AD7192) += ad7192.o
obj-$(CONFIG_AD7280) += ad7280a.o
obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
-obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 92211039f..f843f19cf 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -1,7 +1,7 @@
/*
- * AD7190 AD7192 AD7195 SPI ADC driver
+ * AD7190 AD7192 AD7193 AD7195 SPI ADC driver
*
- * Copyright 2011-2012 Analog Devices Inc.
+ * Copyright 2011-2015 Analog Devices Inc.
*
* Licensed under the GPL-2.
*/
@@ -92,26 +92,43 @@
#define AD7192_CONF_CHOP BIT(23) /* CHOP enable */
#define AD7192_CONF_REFSEL BIT(20) /* REFIN1/REFIN2 Reference Select */
-#define AD7192_CONF_CHAN(x) (((1 << (x)) & 0xFF) << 8) /* Channel select */
-#define AD7192_CONF_CHAN_MASK (0xFF << 8) /* Channel select mask */
+#define AD7192_CONF_CHAN(x) ((x) << 8) /* Channel select */
+#define AD7192_CONF_CHAN_MASK (0x7FF << 8) /* Channel select mask */
#define AD7192_CONF_BURN BIT(7) /* Burnout current enable */
#define AD7192_CONF_REFDET BIT(6) /* Reference detect enable */
#define AD7192_CONF_BUF BIT(4) /* Buffered Mode Enable */
#define AD7192_CONF_UNIPOLAR BIT(3) /* Unipolar/Bipolar Enable */
#define AD7192_CONF_GAIN(x) ((x) & 0x7) /* Gain Select */
-#define AD7192_CH_AIN1P_AIN2M 0 /* AIN1(+) - AIN2(-) */
-#define AD7192_CH_AIN3P_AIN4M 1 /* AIN3(+) - AIN4(-) */
-#define AD7192_CH_TEMP 2 /* Temp Sensor */
-#define AD7192_CH_AIN2P_AIN2M 3 /* AIN2(+) - AIN2(-) */
-#define AD7192_CH_AIN1 4 /* AIN1 - AINCOM */
-#define AD7192_CH_AIN2 5 /* AIN2 - AINCOM */
-#define AD7192_CH_AIN3 6 /* AIN3 - AINCOM */
-#define AD7192_CH_AIN4 7 /* AIN4 - AINCOM */
+#define AD7192_CH_AIN1P_AIN2M BIT(0) /* AIN1(+) - AIN2(-) */
+#define AD7192_CH_AIN3P_AIN4M BIT(1) /* AIN3(+) - AIN4(-) */
+#define AD7192_CH_TEMP BIT(2) /* Temp Sensor */
+#define AD7192_CH_AIN2P_AIN2M BIT(3) /* AIN2(+) - AIN2(-) */
+#define AD7192_CH_AIN1 BIT(4) /* AIN1 - AINCOM */
+#define AD7192_CH_AIN2 BIT(5) /* AIN2 - AINCOM */
+#define AD7192_CH_AIN3 BIT(6) /* AIN3 - AINCOM */
+#define AD7192_CH_AIN4 BIT(7) /* AIN4 - AINCOM */
+
+#define AD7193_CH_AIN1P_AIN2M 0x000 /* AIN1(+) - AIN2(-) */
+#define AD7193_CH_AIN3P_AIN4M 0x001 /* AIN3(+) - AIN4(-) */
+#define AD7193_CH_AIN5P_AIN6M 0x002 /* AIN5(+) - AIN6(-) */
+#define AD7193_CH_AIN7P_AIN8M 0x004 /* AIN7(+) - AIN8(-) */
+#define AD7193_CH_TEMP 0x100 /* Temp senseor */
+#define AD7193_CH_AIN2P_AIN2M 0x200 /* AIN2(+) - AIN2(-) */
+#define AD7193_CH_AIN1 0x401 /* AIN1 - AINCOM */
+#define AD7193_CH_AIN2 0x402 /* AIN2 - AINCOM */
+#define AD7193_CH_AIN3 0x404 /* AIN3 - AINCOM */
+#define AD7193_CH_AIN4 0x408 /* AIN4 - AINCOM */
+#define AD7193_CH_AIN5 0x410 /* AIN5 - AINCOM */
+#define AD7193_CH_AIN6 0x420 /* AIN6 - AINCOM */
+#define AD7193_CH_AIN7 0x440 /* AIN7 - AINCOM */
+#define AD7193_CH_AIN8 0x480 /* AIN7 - AINCOM */
+#define AD7193_CH_AINCOM 0x600 /* AINCOM - AINCOM */
/* ID Register Bit Designations (AD7192_REG_ID) */
#define ID_AD7190 0x4
#define ID_AD7192 0x0
+#define ID_AD7193 0x2
#define ID_AD7195 0x6
#define AD7192_ID_MASK 0x0F
@@ -236,7 +253,7 @@ static int ad7192_setup(struct ad7192_state *st,
st->mclk = pdata->ext_clk_hz;
else
st->mclk = AD7192_INT_FREQ_MHZ;
- break;
+ break;
default:
ret = -EINVAL;
goto out;
@@ -607,6 +624,24 @@ static const struct iio_chan_spec ad7192_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(8),
};
+static const struct iio_chan_spec ad7193_channels[] = {
+ AD_SD_DIFF_CHANNEL(0, 1, 2, AD7193_CH_AIN1P_AIN2M, 24, 32, 0),
+ AD_SD_DIFF_CHANNEL(1, 3, 4, AD7193_CH_AIN3P_AIN4M, 24, 32, 0),
+ AD_SD_DIFF_CHANNEL(2, 5, 6, AD7193_CH_AIN5P_AIN6M, 24, 32, 0),
+ AD_SD_DIFF_CHANNEL(3, 7, 8, AD7193_CH_AIN7P_AIN8M, 24, 32, 0),
+ AD_SD_TEMP_CHANNEL(4, AD7193_CH_TEMP, 24, 32, 0),
+ AD_SD_SHORTED_CHANNEL(5, 2, AD7193_CH_AIN2P_AIN2M, 24, 32, 0),
+ AD_SD_CHANNEL(6, 1, AD7193_CH_AIN1, 24, 32, 0),
+ AD_SD_CHANNEL(7, 2, AD7193_CH_AIN2, 24, 32, 0),
+ AD_SD_CHANNEL(8, 3, AD7193_CH_AIN3, 24, 32, 0),
+ AD_SD_CHANNEL(9, 4, AD7193_CH_AIN4, 24, 32, 0),
+ AD_SD_CHANNEL(10, 5, AD7193_CH_AIN5, 24, 32, 0),
+ AD_SD_CHANNEL(11, 6, AD7193_CH_AIN6, 24, 32, 0),
+ AD_SD_CHANNEL(12, 7, AD7193_CH_AIN7, 24, 32, 0),
+ AD_SD_CHANNEL(13, 8, AD7193_CH_AIN8, 24, 32, 0),
+ IIO_CHAN_SOFT_TIMESTAMP(14),
+};
+
static int ad7192_probe(struct spi_device *spi)
{
const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev);
@@ -651,8 +686,18 @@ static int ad7192_probe(struct spi_device *spi)
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = ad7192_channels;
- indio_dev->num_channels = ARRAY_SIZE(ad7192_channels);
+
+ switch (st->devid) {
+ case ID_AD7193:
+ indio_dev->channels = ad7193_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ad7193_channels);
+ break;
+ default:
+ indio_dev->channels = ad7192_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ad7192_channels);
+ break;
+ }
+
if (st->devid == ID_AD7195)
indio_dev->info = &ad7195_info;
else
@@ -699,6 +744,7 @@ static int ad7192_remove(struct spi_device *spi)
static const struct spi_device_id ad7192_id[] = {
{"ad7190", ID_AD7190},
{"ad7192", ID_AD7192},
+ {"ad7193", ID_AD7193},
{"ad7195", ID_AD7195},
{}
};
@@ -715,5 +761,5 @@ static struct spi_driver ad7192_driver = {
module_spi_driver(ad7192_driver);
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD7190, AD7192, AD7195 ADC");
+MODULE_DESCRIPTION("Analog Devices AD7190, AD7192, AD7193, AD7195 ADC");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index f45ebedb7..62e5ecacf 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -214,8 +214,8 @@ static int __ad7280_read32(struct ad7280_state *st, unsigned *val)
static int ad7280_write(struct ad7280_state *st, unsigned devaddr,
unsigned addr, bool all, unsigned val)
{
- unsigned reg = (devaddr << 27 | addr << 21 |
- (val & 0xFF) << 13 | all << 12);
+ unsigned reg = devaddr << 27 | addr << 21 |
+ (val & 0xFF) << 13 | all << 12;
reg |= ad7280_calc_crc8(st->crc_tab, reg >> 11) << 3 | 0x2;
st->buf[0] = cpu_to_be32(reg);
diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index ec89d055c..cca946924 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -85,8 +85,6 @@ struct ad7606_bus_ops {
int (*read_block)(struct device *, int, void *);
};
-void ad7606_suspend(struct iio_dev *indio_dev);
-void ad7606_resume(struct iio_dev *indio_dev);
struct iio_dev *ad7606_probe(struct device *dev, int irq,
void __iomem *base_address, unsigned id,
const struct ad7606_bus_ops *bops);
@@ -101,4 +99,12 @@ enum ad7606_supported_device_ids {
int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad7606_ring_cleanup(struct iio_dev *indio_dev);
+
+#ifdef CONFIG_PM_SLEEP
+extern const struct dev_pm_ops ad7606_pm_ops;
+#define AD7606_PM_OPS (&ad7606_pm_ops)
+#else
+#define AD7606_PM_OPS NULL
+#endif
+
#endif /* IIO_ADC_AD7606_H_ */
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 2c9d8b7de..fe6caeee0 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -250,7 +250,8 @@ static const struct attribute_group ad7606_attribute_group_range = {
}, \
}
-static const struct iio_chan_spec ad7606_8_channels[] = {
+static const struct iio_chan_spec ad7606_channels[] = {
+ IIO_CHAN_SOFT_TIMESTAMP(8),
AD7606_CHANNEL(0),
AD7606_CHANNEL(1),
AD7606_CHANNEL(2),
@@ -259,25 +260,6 @@ static const struct iio_chan_spec ad7606_8_channels[] = {
AD7606_CHANNEL(5),
AD7606_CHANNEL(6),
AD7606_CHANNEL(7),
- IIO_CHAN_SOFT_TIMESTAMP(8),
-};
-
-static const struct iio_chan_spec ad7606_6_channels[] = {
- AD7606_CHANNEL(0),
- AD7606_CHANNEL(1),
- AD7606_CHANNEL(2),
- AD7606_CHANNEL(3),
- AD7606_CHANNEL(4),
- AD7606_CHANNEL(5),
- IIO_CHAN_SOFT_TIMESTAMP(6),
-};
-
-static const struct iio_chan_spec ad7606_4_channels[] = {
- AD7606_CHANNEL(0),
- AD7606_CHANNEL(1),
- AD7606_CHANNEL(2),
- AD7606_CHANNEL(3),
- IIO_CHAN_SOFT_TIMESTAMP(4),
};
static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
@@ -287,20 +269,20 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
[ID_AD7606_8] = {
.name = "ad7606",
.int_vref_mv = 2500,
- .channels = ad7606_8_channels,
- .num_channels = 8,
+ .channels = ad7606_channels,
+ .num_channels = 9,
},
[ID_AD7606_6] = {
.name = "ad7606-6",
.int_vref_mv = 2500,
- .channels = ad7606_6_channels,
- .num_channels = 6,
+ .channels = ad7606_channels,
+ .num_channels = 7,
},
[ID_AD7606_4] = {
.name = "ad7606-4",
.int_vref_mv = 2500,
- .channels = ad7606_4_channels,
- .num_channels = 4,
+ .channels = ad7606_channels,
+ .num_channels = 5,
},
};
@@ -578,8 +560,11 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq)
}
EXPORT_SYMBOL_GPL(ad7606_remove);
-void ad7606_suspend(struct iio_dev *indio_dev)
+#ifdef CONFIG_PM_SLEEP
+
+static int ad7606_suspend(struct device *dev)
{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7606_state *st = iio_priv(indio_dev);
if (gpio_is_valid(st->pdata->gpio_stby)) {
@@ -587,11 +572,13 @@ void ad7606_suspend(struct iio_dev *indio_dev)
gpio_set_value(st->pdata->gpio_range, 1);
gpio_set_value(st->pdata->gpio_stby, 0);
}
+
+ return 0;
}
-EXPORT_SYMBOL_GPL(ad7606_suspend);
-void ad7606_resume(struct iio_dev *indio_dev)
+static int ad7606_resume(struct device *dev)
{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7606_state *st = iio_priv(indio_dev);
if (gpio_is_valid(st->pdata->gpio_stby)) {
@@ -602,8 +589,14 @@ void ad7606_resume(struct iio_dev *indio_dev)
gpio_set_value(st->pdata->gpio_stby, 1);
ad7606_reset(st);
}
+
+ return 0;
}
-EXPORT_SYMBOL_GPL(ad7606_resume);
+
+SIMPLE_DEV_PM_OPS(ad7606_pm_ops, ad7606_suspend, ad7606_resume);
+EXPORT_SYMBOL_GPL(ad7606_pm_ops);
+
+#endif
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index adc370ee8..84d23930f 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -90,36 +90,6 @@ static int ad7606_par_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int ad7606_par_suspend(struct device *dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
- ad7606_suspend(indio_dev);
-
- return 0;
-}
-
-static int ad7606_par_resume(struct device *dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
- ad7606_resume(indio_dev);
-
- return 0;
-}
-
-static const struct dev_pm_ops ad7606_pm_ops = {
- .suspend = ad7606_par_suspend,
- .resume = ad7606_par_resume,
-};
-
-#define AD7606_PAR_PM_OPS (&ad7606_pm_ops)
-
-#else
-#define AD7606_PAR_PM_OPS NULL
-#endif /* CONFIG_PM */
-
static const struct platform_device_id ad7606_driver_ids[] = {
{
.name = "ad7606-8",
@@ -142,7 +112,7 @@ static struct platform_driver ad7606_driver = {
.id_table = ad7606_driver_ids,
.driver = {
.name = "ad7606",
- .pm = AD7606_PAR_PM_OPS,
+ .pm = AD7606_PM_OPS,
},
};
diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c
index cbb363172..d873a5164 100644
--- a/drivers/staging/iio/adc/ad7606_spi.c
+++ b/drivers/staging/iio/adc/ad7606_spi.c
@@ -62,36 +62,6 @@ static int ad7606_spi_remove(struct spi_device *spi)
return ad7606_remove(indio_dev, spi->irq);
}
-#ifdef CONFIG_PM
-static int ad7606_spi_suspend(struct device *dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
- ad7606_suspend(indio_dev);
-
- return 0;
-}
-
-static int ad7606_spi_resume(struct device *dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
- ad7606_resume(indio_dev);
-
- return 0;
-}
-
-static const struct dev_pm_ops ad7606_pm_ops = {
- .suspend = ad7606_spi_suspend,
- .resume = ad7606_spi_resume,
-};
-
-#define AD7606_SPI_PM_OPS (&ad7606_pm_ops)
-
-#else
-#define AD7606_SPI_PM_OPS NULL
-#endif
-
static const struct spi_device_id ad7606_id[] = {
{"ad7606-8", ID_AD7606_8},
{"ad7606-6", ID_AD7606_6},
@@ -103,7 +73,7 @@ MODULE_DEVICE_TABLE(spi, ad7606_id);
static struct spi_driver ad7606_driver = {
.driver = {
.name = "ad7606",
- .pm = AD7606_SPI_PM_OPS,
+ .pm = AD7606_PM_OPS,
},
.probe = ad7606_spi_probe,
.remove = ad7606_spi_remove,
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 22260512c..ac3735c7f 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -296,14 +296,14 @@ static inline ssize_t ad7816_set_oti(struct device *dev,
dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
return -EINVAL;
} else if (chip->channel_id == 0) {
- if (ret || value < AD7816_BOUND_VALUE_MIN ||
+ if (value < AD7816_BOUND_VALUE_MIN ||
value > AD7816_BOUND_VALUE_MAX)
return -EINVAL;
data = (u8)(value - AD7816_BOUND_VALUE_MIN +
AD7816_BOUND_VALUE_BASE);
} else {
- if (ret || value < AD7816_BOUND_VALUE_BASE || value > 255)
+ if (value < AD7816_BOUND_VALUE_BASE || value > 255)
return -EINVAL;
data = (u8)value;
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
deleted file mode 100644
index bb1f15224..000000000
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ /dev/null
@@ -1,1770 +0,0 @@
-/*
- * Freescale MXS LRADC driver
- *
- * Copyright (c) 2012 DENX Software Engineering, GmbH.
- * Marek Vasut <marex@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/bitops.h>
-#include <linux/clk.h>
-#include <linux/completion.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/stmp_device.h>
-#include <linux/sysfs.h>
-
-#include <linux/iio/buffer.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-#include <linux/iio/sysfs.h>
-
-#define DRIVER_NAME "mxs-lradc"
-
-#define LRADC_MAX_DELAY_CHANS 4
-#define LRADC_MAX_MAPPED_CHANS 8
-#define LRADC_MAX_TOTAL_CHANS 16
-
-#define LRADC_DELAY_TIMER_HZ 2000
-
-/*
- * Make this runtime configurable if necessary. Currently, if the buffered mode
- * is enabled, the LRADC takes LRADC_DELAY_TIMER_LOOP samples of data before
- * triggering IRQ. The sampling happens every (LRADC_DELAY_TIMER_PER / 2000)
- * seconds. The result is that the samples arrive every 500mS.
- */
-#define LRADC_DELAY_TIMER_PER 200
-#define LRADC_DELAY_TIMER_LOOP 5
-
-/*
- * Once the pen touches the touchscreen, the touchscreen switches from
- * IRQ-driven mode to polling mode to prevent interrupt storm. The polling
- * is realized by worker thread, which is called every 20 or so milliseconds.
- * This gives the touchscreen enough fluency and does not strain the system
- * too much.
- */
-#define LRADC_TS_SAMPLE_DELAY_MS 5
-
-/*
- * The LRADC reads the following amount of samples from each touchscreen
- * channel and the driver then computes average of these.
- */
-#define LRADC_TS_SAMPLE_AMOUNT 4
-
-enum mxs_lradc_id {
- IMX23_LRADC,
- IMX28_LRADC,
-};
-
-static const char * const mx23_lradc_irq_names[] = {
- "mxs-lradc-touchscreen",
- "mxs-lradc-channel0",
- "mxs-lradc-channel1",
- "mxs-lradc-channel2",
- "mxs-lradc-channel3",
- "mxs-lradc-channel4",
- "mxs-lradc-channel5",
- "mxs-lradc-channel6",
- "mxs-lradc-channel7",
-};
-
-static const char * const mx28_lradc_irq_names[] = {
- "mxs-lradc-touchscreen",
- "mxs-lradc-thresh0",
- "mxs-lradc-thresh1",
- "mxs-lradc-channel0",
- "mxs-lradc-channel1",
- "mxs-lradc-channel2",
- "mxs-lradc-channel3",
- "mxs-lradc-channel4",
- "mxs-lradc-channel5",
- "mxs-lradc-channel6",
- "mxs-lradc-channel7",
- "mxs-lradc-button0",
- "mxs-lradc-button1",
-};
-
-struct mxs_lradc_of_config {
- const int irq_count;
- const char * const *irq_name;
- const u32 *vref_mv;
-};
-
-#define VREF_MV_BASE 1850
-
-static const u32 mx23_vref_mv[LRADC_MAX_TOTAL_CHANS] = {
- VREF_MV_BASE, /* CH0 */
- VREF_MV_BASE, /* CH1 */
- VREF_MV_BASE, /* CH2 */
- VREF_MV_BASE, /* CH3 */
- VREF_MV_BASE, /* CH4 */
- VREF_MV_BASE, /* CH5 */
- VREF_MV_BASE * 2, /* CH6 VDDIO */
- VREF_MV_BASE * 4, /* CH7 VBATT */
- VREF_MV_BASE, /* CH8 Temp sense 0 */
- VREF_MV_BASE, /* CH9 Temp sense 1 */
- VREF_MV_BASE, /* CH10 */
- VREF_MV_BASE, /* CH11 */
- VREF_MV_BASE, /* CH12 USB_DP */
- VREF_MV_BASE, /* CH13 USB_DN */
- VREF_MV_BASE, /* CH14 VBG */
- VREF_MV_BASE * 4, /* CH15 VDD5V */
-};
-
-static const u32 mx28_vref_mv[LRADC_MAX_TOTAL_CHANS] = {
- VREF_MV_BASE, /* CH0 */
- VREF_MV_BASE, /* CH1 */
- VREF_MV_BASE, /* CH2 */
- VREF_MV_BASE, /* CH3 */
- VREF_MV_BASE, /* CH4 */
- VREF_MV_BASE, /* CH5 */
- VREF_MV_BASE, /* CH6 */
- VREF_MV_BASE * 4, /* CH7 VBATT */
- VREF_MV_BASE, /* CH8 Temp sense 0 */
- VREF_MV_BASE, /* CH9 Temp sense 1 */
- VREF_MV_BASE * 2, /* CH10 VDDIO */
- VREF_MV_BASE, /* CH11 VTH */
- VREF_MV_BASE * 2, /* CH12 VDDA */
- VREF_MV_BASE, /* CH13 VDDD */
- VREF_MV_BASE, /* CH14 VBG */
- VREF_MV_BASE * 4, /* CH15 VDD5V */
-};
-
-static const struct mxs_lradc_of_config mxs_lradc_of_config[] = {
- [IMX23_LRADC] = {
- .irq_count = ARRAY_SIZE(mx23_lradc_irq_names),
- .irq_name = mx23_lradc_irq_names,
- .vref_mv = mx23_vref_mv,
- },
- [IMX28_LRADC] = {
- .irq_count = ARRAY_SIZE(mx28_lradc_irq_names),
- .irq_name = mx28_lradc_irq_names,
- .vref_mv = mx28_vref_mv,
- },
-};
-
-enum mxs_lradc_ts {
- MXS_LRADC_TOUCHSCREEN_NONE = 0,
- MXS_LRADC_TOUCHSCREEN_4WIRE,
- MXS_LRADC_TOUCHSCREEN_5WIRE,
-};
-
-/*
- * Touchscreen handling
- */
-enum lradc_ts_plate {
- LRADC_TOUCH = 0,
- LRADC_SAMPLE_X,
- LRADC_SAMPLE_Y,
- LRADC_SAMPLE_PRESSURE,
- LRADC_SAMPLE_VALID,
-};
-
-enum mxs_lradc_divbytwo {
- MXS_LRADC_DIV_DISABLED = 0,
- MXS_LRADC_DIV_ENABLED,
-};
-
-struct mxs_lradc_scale {
- unsigned int integer;
- unsigned int nano;
-};
-
-struct mxs_lradc {
- struct device *dev;
- void __iomem *base;
- int irq[13];
-
- struct clk *clk;
-
- u32 *buffer;
- struct iio_trigger *trig;
-
- struct mutex lock;
-
- struct completion completion;
-
- const u32 *vref_mv;
- struct mxs_lradc_scale scale_avail[LRADC_MAX_TOTAL_CHANS][2];
- unsigned long is_divided;
-
- /*
- * When the touchscreen is enabled, we give it two private virtual
- * channels: #6 and #7. This means that only 6 virtual channels (instead
- * of 8) will be available for buffered capture.
- */
-#define TOUCHSCREEN_VCHANNEL1 7
-#define TOUCHSCREEN_VCHANNEL2 6
-#define BUFFER_VCHANS_LIMITED 0x3f
-#define BUFFER_VCHANS_ALL 0xff
- u8 buffer_vchans;
-
- /*
- * Furthermore, certain LRADC channels are shared between touchscreen
- * and/or touch-buttons and generic LRADC block. Therefore when using
- * either of these, these channels are not available for the regular
- * sampling. The shared channels are as follows:
- *
- * CH0 -- Touch button #0
- * CH1 -- Touch button #1
- * CH2 -- Touch screen XPUL
- * CH3 -- Touch screen YPLL
- * CH4 -- Touch screen XNUL
- * CH5 -- Touch screen YNLR
- * CH6 -- Touch screen WIPER (5-wire only)
- *
- * The bit fields below represents which parts of the LRADC block are
- * switched into special mode of operation. These channels can not
- * be sampled as regular LRADC channels. The driver will refuse any
- * attempt to sample these channels.
- */
-#define CHAN_MASK_TOUCHBUTTON (BIT(1) | BIT(0))
-#define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 2)
-#define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 2)
- enum mxs_lradc_ts use_touchscreen;
- bool use_touchbutton;
-
- struct input_dev *ts_input;
-
- enum mxs_lradc_id soc;
- enum lradc_ts_plate cur_plate; /* state machine */
- bool ts_valid;
- unsigned ts_x_pos;
- unsigned ts_y_pos;
- unsigned ts_pressure;
-
- /* handle touchscreen's physical behaviour */
- /* samples per coordinate */
- unsigned over_sample_cnt;
- /* time clocks between samples */
- unsigned over_sample_delay;
- /* time in clocks to wait after the plates where switched */
- unsigned settling_delay;
-};
-
-#define LRADC_CTRL0 0x00
-# define LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE BIT(23)
-# define LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE BIT(22)
-# define LRADC_CTRL0_MX28_YNNSW /* YM */ BIT(21)
-# define LRADC_CTRL0_MX28_YPNSW /* YP */ BIT(20)
-# define LRADC_CTRL0_MX28_YPPSW /* YP */ BIT(19)
-# define LRADC_CTRL0_MX28_XNNSW /* XM */ BIT(18)
-# define LRADC_CTRL0_MX28_XNPSW /* XM */ BIT(17)
-# define LRADC_CTRL0_MX28_XPPSW /* XP */ BIT(16)
-
-# define LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE BIT(20)
-# define LRADC_CTRL0_MX23_YM BIT(19)
-# define LRADC_CTRL0_MX23_XM BIT(18)
-# define LRADC_CTRL0_MX23_YP BIT(17)
-# define LRADC_CTRL0_MX23_XP BIT(16)
-
-# define LRADC_CTRL0_MX28_PLATE_MASK \
- (LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE | \
- LRADC_CTRL0_MX28_YNNSW | LRADC_CTRL0_MX28_YPNSW | \
- LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW | \
- LRADC_CTRL0_MX28_XNPSW | LRADC_CTRL0_MX28_XPPSW)
-
-# define LRADC_CTRL0_MX23_PLATE_MASK \
- (LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE | \
- LRADC_CTRL0_MX23_YM | LRADC_CTRL0_MX23_XM | \
- LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XP)
-
-#define LRADC_CTRL1 0x10
-#define LRADC_CTRL1_TOUCH_DETECT_IRQ_EN BIT(24)
-#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16))
-#define LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK (0x1fff << 16)
-#define LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK (0x01ff << 16)
-#define LRADC_CTRL1_LRADC_IRQ_EN_OFFSET 16
-#define LRADC_CTRL1_TOUCH_DETECT_IRQ BIT(8)
-#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
-#define LRADC_CTRL1_MX28_LRADC_IRQ_MASK 0x1fff
-#define LRADC_CTRL1_MX23_LRADC_IRQ_MASK 0x01ff
-#define LRADC_CTRL1_LRADC_IRQ_OFFSET 0
-
-#define LRADC_CTRL2 0x20
-#define LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET 24
-#define LRADC_CTRL2_TEMPSENSE_PWD BIT(15)
-
-#define LRADC_STATUS 0x40
-#define LRADC_STATUS_TOUCH_DETECT_RAW BIT(0)
-
-#define LRADC_CH(n) (0x50 + (0x10 * (n)))
-#define LRADC_CH_ACCUMULATE BIT(29)
-#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24)
-#define LRADC_CH_NUM_SAMPLES_OFFSET 24
-#define LRADC_CH_NUM_SAMPLES(x) \
- ((x) << LRADC_CH_NUM_SAMPLES_OFFSET)
-#define LRADC_CH_VALUE_MASK 0x3ffff
-#define LRADC_CH_VALUE_OFFSET 0
-
-#define LRADC_DELAY(n) (0xd0 + (0x10 * (n)))
-#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xffUL << 24)
-#define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24
-#define LRADC_DELAY_TRIGGER(x) \
- (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
- LRADC_DELAY_TRIGGER_LRADCS_MASK)
-#define LRADC_DELAY_KICK BIT(20)
-#define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16)
-#define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16
-#define LRADC_DELAY_TRIGGER_DELAYS(x) \
- (((x) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) & \
- LRADC_DELAY_TRIGGER_DELAYS_MASK)
-#define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11)
-#define LRADC_DELAY_LOOP_COUNT_OFFSET 11
-#define LRADC_DELAY_LOOP(x) \
- (((x) << LRADC_DELAY_LOOP_COUNT_OFFSET) & \
- LRADC_DELAY_LOOP_COUNT_MASK)
-#define LRADC_DELAY_DELAY_MASK 0x7ff
-#define LRADC_DELAY_DELAY_OFFSET 0
-#define LRADC_DELAY_DELAY(x) \
- (((x) << LRADC_DELAY_DELAY_OFFSET) & \
- LRADC_DELAY_DELAY_MASK)
-
-#define LRADC_CTRL4 0x140
-#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
-#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4)
-#define LRADC_CTRL4_LRADCSELECT(n, x) \
- (((x) << LRADC_CTRL4_LRADCSELECT_OFFSET(n)) & \
- LRADC_CTRL4_LRADCSELECT_MASK(n))
-
-#define LRADC_RESOLUTION 12
-#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1)
-
-static void mxs_lradc_reg_set(struct mxs_lradc *lradc, u32 val, u32 reg)
-{
- writel(val, lradc->base + reg + STMP_OFFSET_REG_SET);
-}
-
-static void mxs_lradc_reg_clear(struct mxs_lradc *lradc, u32 val, u32 reg)
-{
- writel(val, lradc->base + reg + STMP_OFFSET_REG_CLR);
-}
-
-static void mxs_lradc_reg_wrt(struct mxs_lradc *lradc, u32 val, u32 reg)
-{
- writel(val, lradc->base + reg);
-}
-
-static u32 mxs_lradc_plate_mask(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_PLATE_MASK;
- return LRADC_CTRL0_MX28_PLATE_MASK;
-}
-
-static u32 mxs_lradc_irq_en_mask(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK;
- return LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK;
-}
-
-static u32 mxs_lradc_irq_mask(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL1_MX23_LRADC_IRQ_MASK;
- return LRADC_CTRL1_MX28_LRADC_IRQ_MASK;
-}
-
-static u32 mxs_lradc_touch_detect_bit(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE;
- return LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE;
-}
-
-static u32 mxs_lradc_drive_x_plate(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM;
- return LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW;
-}
-
-static u32 mxs_lradc_drive_y_plate(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM;
- return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW;
-}
-
-static u32 mxs_lradc_drive_pressure(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM;
- return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW;
-}
-
-static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
-{
- return !!(readl(lradc->base + LRADC_STATUS) &
- LRADC_STATUS_TOUCH_DETECT_RAW);
-}
-
-static void mxs_lradc_map_channel(struct mxs_lradc *lradc, unsigned vch,
- unsigned ch)
-{
- mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(vch),
- LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, LRADC_CTRL4_LRADCSELECT(vch, ch), LRADC_CTRL4);
-}
-
-static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
-{
- /*
- * prepare for oversampling conversion
- *
- * from the datasheet:
- * "The ACCUMULATE bit in the appropriate channel register
- * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
- * otherwise, the IRQs will not fire."
- */
- mxs_lradc_reg_wrt(lradc, LRADC_CH_ACCUMULATE |
- LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1),
- LRADC_CH(ch));
-
- /* from the datasheet:
- * "Software must clear this register in preparation for a
- * multi-cycle accumulation.
- */
- mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
-
- /*
- * prepare the delay/loop unit according to the oversampling count
- *
- * from the datasheet:
- * "The DELAY fields in HW_LRADC_DELAY0, HW_LRADC_DELAY1,
- * HW_LRADC_DELAY2, and HW_LRADC_DELAY3 must be non-zero; otherwise,
- * the LRADC will not trigger the delay group."
- */
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
- LRADC_DELAY_TRIGGER_DELAYS(0) |
- LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
- LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
- LRADC_DELAY(3));
-
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch), LRADC_CTRL1);
-
- /*
- * after changing the touchscreen plates setting
- * the signals need some initial time to settle. Start the
- * SoC's delay unit and start the conversion later
- * and automatically.
- */
- mxs_lradc_reg_wrt(
- lradc,
- LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
- LRADC_DELAY_TRIGGER_DELAYS(BIT(3)) | /* trigger DELAY unit#3 */
- LRADC_DELAY_KICK |
- LRADC_DELAY_DELAY(lradc->settling_delay),
- LRADC_DELAY(2));
-}
-
-/*
- * Pressure detection is special:
- * We want to do both required measurements for the pressure detection in
- * one turn. Use the hardware features to chain both conversions and let the
- * hardware report one interrupt if both conversions are done
- */
-static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
- unsigned ch2)
-{
- u32 reg;
-
- /*
- * prepare for oversampling conversion
- *
- * from the datasheet:
- * "The ACCUMULATE bit in the appropriate channel register
- * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
- * otherwise, the IRQs will not fire."
- */
- reg = LRADC_CH_ACCUMULATE |
- LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1);
- mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch1));
- mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch2));
-
- /* from the datasheet:
- * "Software must clear this register in preparation for a
- * multi-cycle accumulation.
- */
- mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch1));
- mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch2));
-
- /* prepare the delay/loop unit according to the oversampling count */
- mxs_lradc_reg_wrt(
- lradc,
- LRADC_DELAY_TRIGGER(1 << ch1) |
- LRADC_DELAY_TRIGGER(1 << ch2) | /* start both channels */
- LRADC_DELAY_TRIGGER_DELAYS(0) |
- LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
- LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
- LRADC_DELAY(3));
-
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch2), LRADC_CTRL1);
-
- /*
- * after changing the touchscreen plates setting
- * the signals need some initial time to settle. Start the
- * SoC's delay unit and start the conversion later
- * and automatically.
- */
- mxs_lradc_reg_wrt(
- lradc,
- LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
- LRADC_DELAY_TRIGGER_DELAYS(BIT(3)) | /* trigger DELAY unit#3 */
- LRADC_DELAY_KICK |
- LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2));
-}
-
-static unsigned mxs_lradc_read_raw_channel(struct mxs_lradc *lradc,
- unsigned channel)
-{
- u32 reg;
- unsigned num_samples, val;
-
- reg = readl(lradc->base + LRADC_CH(channel));
- if (reg & LRADC_CH_ACCUMULATE)
- num_samples = lradc->over_sample_cnt;
- else
- num_samples = 1;
-
- val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
- return val / num_samples;
-}
-
-static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
- unsigned ch1, unsigned ch2)
-{
- u32 reg, mask;
- unsigned pressure, m1, m2;
-
- mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
- reg = readl(lradc->base + LRADC_CTRL1) & mask;
-
- while (reg != mask) {
- reg = readl(lradc->base + LRADC_CTRL1) & mask;
- dev_dbg(lradc->dev, "One channel is still busy: %X\n", reg);
- }
-
- m1 = mxs_lradc_read_raw_channel(lradc, ch1);
- m2 = mxs_lradc_read_raw_channel(lradc, ch2);
-
- if (m2 == 0) {
- dev_warn(lradc->dev, "Cannot calculate pressure\n");
- return 1 << (LRADC_RESOLUTION - 1);
- }
-
- /* simply scale the value from 0 ... max ADC resolution */
- pressure = m1;
- pressure *= (1 << LRADC_RESOLUTION);
- pressure /= m2;
-
- dev_dbg(lradc->dev, "Pressure = %u\n", pressure);
- return pressure;
-}
-
-#define TS_CH_XP 2
-#define TS_CH_YP 3
-#define TS_CH_XM 4
-#define TS_CH_YM 5
-
-/*
- * YP(open)--+-------------+
- * | |--+
- * | | |
- * YM(-)--+-------------+ |
- * +--------------+
- * | |
- * XP(weak+) XM(open)
- *
- * "weak+" means 200k Ohm VDDIO
- * (-) means GND
- */
-static void mxs_lradc_setup_touch_detection(struct mxs_lradc *lradc)
-{
- /*
- * In order to detect a touch event the 'touch detect enable' bit
- * enables:
- * - a weak pullup to the X+ connector
- * - a strong ground at the Y- connector
- */
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_touch_detect_bit(lradc),
- LRADC_CTRL0);
-}
-
-/*
- * YP(meas)--+-------------+
- * | |--+
- * | | |
- * YM(open)--+-------------+ |
- * +--------------+
- * | |
- * XP(+) XM(-)
- *
- * (+) means here 1.85 V
- * (-) means here GND
- */
-static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
-
- lradc->cur_plate = LRADC_SAMPLE_X;
- mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YP);
- mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1);
-}
-
-/*
- * YP(+)--+-------------+
- * | |--+
- * | | |
- * YM(-)--+-------------+ |
- * +--------------+
- * | |
- * XP(open) XM(meas)
- *
- * (+) means here 1.85 V
- * (-) means here GND
- */
-static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
-
- lradc->cur_plate = LRADC_SAMPLE_Y;
- mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_XM);
- mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1);
-}
-
-/*
- * YP(+)--+-------------+
- * | |--+
- * | | |
- * YM(meas)--+-------------+ |
- * +--------------+
- * | |
- * XP(meas) XM(-)
- *
- * (+) means here 1.85 V
- * (-) means here GND
- */
-static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
-
- lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
- mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YM);
- mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL2, TS_CH_XP);
- mxs_lradc_setup_ts_pressure(lradc, TOUCHSCREEN_VCHANNEL2,
- TOUCHSCREEN_VCHANNEL1);
-}
-
-static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
-{
- mxs_lradc_setup_touch_detection(lradc);
-
- lradc->cur_plate = LRADC_TOUCH;
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
- LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
-}
-
-static void mxs_lradc_start_touch_event(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc,
- LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
- LRADC_CTRL1);
- mxs_lradc_reg_set(lradc,
- LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1),
- LRADC_CTRL1);
- /*
- * start with the Y-pos, because it uses nearly the same plate
- * settings like the touch detection
- */
- mxs_lradc_prepare_y_pos(lradc);
-}
-
-static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
-{
- input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
- input_report_abs(lradc->ts_input, ABS_Y, lradc->ts_y_pos);
- input_report_abs(lradc->ts_input, ABS_PRESSURE, lradc->ts_pressure);
- input_report_key(lradc->ts_input, BTN_TOUCH, 1);
- input_sync(lradc->ts_input);
-}
-
-static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
-{
- mxs_lradc_setup_touch_detection(lradc);
- lradc->cur_plate = LRADC_SAMPLE_VALID;
- /*
- * start a dummy conversion to burn time to settle the signals
- * note: we are not interested in the conversion's value
- */
- mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(TOUCHSCREEN_VCHANNEL1));
- mxs_lradc_reg_clear(lradc,
- LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
- LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2),
- LRADC_CTRL1);
- mxs_lradc_reg_wrt(
- lradc,
- LRADC_DELAY_TRIGGER(1 << TOUCHSCREEN_VCHANNEL1) |
- LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
- LRADC_DELAY(2));
-}
-
-/*
- * in order to avoid false measurements, report only samples where
- * the surface is still touched after the position measurement
- */
-static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
-{
- /* if it is still touched, report the sample */
- if (valid && mxs_lradc_check_touch_event(lradc)) {
- lradc->ts_valid = true;
- mxs_lradc_report_ts_event(lradc);
- }
-
- /* if it is even still touched, continue with the next measurement */
- if (mxs_lradc_check_touch_event(lradc)) {
- mxs_lradc_prepare_y_pos(lradc);
- return;
- }
-
- if (lradc->ts_valid) {
- /* signal the release */
- lradc->ts_valid = false;
- input_report_key(lradc->ts_input, BTN_TOUCH, 0);
- input_sync(lradc->ts_input);
- }
-
- /* if it is released, wait for the next touch via IRQ */
- lradc->cur_plate = LRADC_TOUCH;
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
- mxs_lradc_reg_clear(lradc,
- LRADC_CTRL1_TOUCH_DETECT_IRQ |
- LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) |
- LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1),
- LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
-}
-
-/* touchscreen's state machine */
-static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
-{
- switch (lradc->cur_plate) {
- case LRADC_TOUCH:
- if (mxs_lradc_check_touch_event(lradc))
- mxs_lradc_start_touch_event(lradc);
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
- LRADC_CTRL1);
- return;
-
- case LRADC_SAMPLE_Y:
- lradc->ts_y_pos =
- mxs_lradc_read_raw_channel(lradc,
- TOUCHSCREEN_VCHANNEL1);
- mxs_lradc_prepare_x_pos(lradc);
- return;
-
- case LRADC_SAMPLE_X:
- lradc->ts_x_pos =
- mxs_lradc_read_raw_channel(lradc,
- TOUCHSCREEN_VCHANNEL1);
- mxs_lradc_prepare_pressure(lradc);
- return;
-
- case LRADC_SAMPLE_PRESSURE:
- lradc->ts_pressure =
- mxs_lradc_read_ts_pressure(lradc,
- TOUCHSCREEN_VCHANNEL2,
- TOUCHSCREEN_VCHANNEL1);
- mxs_lradc_complete_touch_event(lradc);
- return;
-
- case LRADC_SAMPLE_VALID:
- mxs_lradc_finish_touch_event(lradc, 1);
- break;
- }
-}
-
-/*
- * Raw I/O operations
- */
-static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val)
-{
- struct mxs_lradc *lradc = iio_priv(iio_dev);
- int ret;
-
- /*
- * See if there is no buffered operation in progress. If there is, simply
- * bail out. This can be improved to support both buffered and raw IO at
- * the same time, yet the code becomes horribly complicated. Therefore I
- * applied KISS principle here.
- */
- ret = mutex_trylock(&lradc->lock);
- if (!ret)
- return -EBUSY;
-
- reinit_completion(&lradc->completion);
-
- /*
- * No buffered operation in progress, map the channel and trigger it.
- * Virtual channel 0 is always used here as the others are always not
- * used if doing raw sampling.
- */
- if (lradc->soc == IMX28_LRADC)
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0),
- LRADC_CTRL1);
- mxs_lradc_reg_clear(lradc, 0x1, LRADC_CTRL0);
-
- /* Enable / disable the divider per requirement */
- if (test_bit(chan, &lradc->is_divided))
- mxs_lradc_reg_set(lradc,
- 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
- LRADC_CTRL2);
- else
- mxs_lradc_reg_clear(lradc,
- 1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
- LRADC_CTRL2);
-
- /* Clean the slot's previous content, then set new one. */
- mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0),
- LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, chan, LRADC_CTRL4);
-
- mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
-
- /* Enable the IRQ and start sampling the channel. */
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, BIT(0), LRADC_CTRL0);
-
- /* Wait for completion on the channel, 1 second max. */
- ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
- if (!ret)
- ret = -ETIMEDOUT;
- if (ret < 0)
- goto err;
-
- /* Read the data. */
- *val = readl(lradc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK;
- ret = IIO_VAL_INT;
-
-err:
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
-
- mutex_unlock(&lradc->lock);
-
- return ret;
-}
-
-static int mxs_lradc_read_temp(struct iio_dev *iio_dev, int *val)
-{
- int ret, min, max;
-
- ret = mxs_lradc_read_single(iio_dev, 8, &min);
- if (ret != IIO_VAL_INT)
- return ret;
-
- ret = mxs_lradc_read_single(iio_dev, 9, &max);
- if (ret != IIO_VAL_INT)
- return ret;
-
- *val = max - min;
-
- return IIO_VAL_INT;
-}
-
-static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
- const struct iio_chan_spec *chan,
- int *val, int *val2, long m)
-{
- struct mxs_lradc *lradc = iio_priv(iio_dev);
-
- switch (m) {
- case IIO_CHAN_INFO_RAW:
- if (chan->type == IIO_TEMP)
- return mxs_lradc_read_temp(iio_dev, val);
-
- return mxs_lradc_read_single(iio_dev, chan->channel, val);
-
- case IIO_CHAN_INFO_SCALE:
- if (chan->type == IIO_TEMP) {
- /* From the datasheet, we have to multiply by 1.012 and
- * divide by 4
- */
- *val = 0;
- *val2 = 253000;
- return IIO_VAL_INT_PLUS_MICRO;
- }
-
- *val = lradc->vref_mv[chan->channel];
- *val2 = chan->scan_type.realbits -
- test_bit(chan->channel, &lradc->is_divided);
- return IIO_VAL_FRACTIONAL_LOG2;
-
- case IIO_CHAN_INFO_OFFSET:
- if (chan->type == IIO_TEMP) {
- /* The calculated value from the ADC is in Kelvin, we
- * want Celsius for hwmon so the offset is -273.15
- * The offset is applied before scaling so it is
- * actually -213.15 * 4 / 1.012 = -1079.644268
- */
- *val = -1079;
- *val2 = 644268;
-
- return IIO_VAL_INT_PLUS_MICRO;
- }
-
- return -EINVAL;
-
- default:
- break;
- }
-
- return -EINVAL;
-}
-
-static int mxs_lradc_write_raw(struct iio_dev *iio_dev,
- const struct iio_chan_spec *chan,
- int val, int val2, long m)
-{
- struct mxs_lradc *lradc = iio_priv(iio_dev);
- struct mxs_lradc_scale *scale_avail =
- lradc->scale_avail[chan->channel];
- int ret;
-
- ret = mutex_trylock(&lradc->lock);
- if (!ret)
- return -EBUSY;
-
- switch (m) {
- case IIO_CHAN_INFO_SCALE:
- ret = -EINVAL;
- if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
- val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
- /* divider by two disabled */
- clear_bit(chan->channel, &lradc->is_divided);
- ret = 0;
- } else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer &&
- val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) {
- /* divider by two enabled */
- set_bit(chan->channel, &lradc->is_divided);
- ret = 0;
- }
-
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- mutex_unlock(&lradc->lock);
-
- return ret;
-}
-
-static int mxs_lradc_write_raw_get_fmt(struct iio_dev *iio_dev,
- const struct iio_chan_spec *chan,
- long m)
-{
- return IIO_VAL_INT_PLUS_NANO;
-}
-
-static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev,
- struct device_attribute *attr,
- char *buf,
- int ch)
-{
- struct iio_dev *iio = dev_to_iio_dev(dev);
- struct mxs_lradc *lradc = iio_priv(iio);
- int i, len = 0;
-
- for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++)
- len += sprintf(buf + len, "%u.%09u ",
- lradc->scale_avail[ch][i].integer,
- lradc->scale_avail[ch][i].nano);
-
- len += sprintf(buf + len, "\n");
-
- return len;
-}
-
-static ssize_t mxs_lradc_show_scale_available(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
-
- return mxs_lradc_show_scale_available_ch(dev, attr, buf,
- iio_attr->address);
-}
-
-#define SHOW_SCALE_AVAILABLE_ATTR(ch) \
-static IIO_DEVICE_ATTR(in_voltage##ch##_scale_available, S_IRUGO, \
- mxs_lradc_show_scale_available, NULL, ch)
-
-SHOW_SCALE_AVAILABLE_ATTR(0);
-SHOW_SCALE_AVAILABLE_ATTR(1);
-SHOW_SCALE_AVAILABLE_ATTR(2);
-SHOW_SCALE_AVAILABLE_ATTR(3);
-SHOW_SCALE_AVAILABLE_ATTR(4);
-SHOW_SCALE_AVAILABLE_ATTR(5);
-SHOW_SCALE_AVAILABLE_ATTR(6);
-SHOW_SCALE_AVAILABLE_ATTR(7);
-SHOW_SCALE_AVAILABLE_ATTR(10);
-SHOW_SCALE_AVAILABLE_ATTR(11);
-SHOW_SCALE_AVAILABLE_ATTR(12);
-SHOW_SCALE_AVAILABLE_ATTR(13);
-SHOW_SCALE_AVAILABLE_ATTR(14);
-SHOW_SCALE_AVAILABLE_ATTR(15);
-
-static struct attribute *mxs_lradc_attributes[] = {
- &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage2_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage3_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage4_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage13_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage14_scale_available.dev_attr.attr,
- &iio_dev_attr_in_voltage15_scale_available.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group mxs_lradc_attribute_group = {
- .attrs = mxs_lradc_attributes,
-};
-
-static const struct iio_info mxs_lradc_iio_info = {
- .driver_module = THIS_MODULE,
- .read_raw = mxs_lradc_read_raw,
- .write_raw = mxs_lradc_write_raw,
- .write_raw_get_fmt = mxs_lradc_write_raw_get_fmt,
- .attrs = &mxs_lradc_attribute_group,
-};
-
-static int mxs_lradc_ts_open(struct input_dev *dev)
-{
- struct mxs_lradc *lradc = input_get_drvdata(dev);
-
- /* Enable the touch-detect circuitry. */
- mxs_lradc_enable_touch_detection(lradc);
-
- return 0;
-}
-
-static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
-{
- /* stop all interrupts from firing */
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
- LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) |
- LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL2), LRADC_CTRL1);
-
- /* Power-down touchscreen touch-detect circuitry. */
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
-}
-
-static void mxs_lradc_ts_close(struct input_dev *dev)
-{
- struct mxs_lradc *lradc = input_get_drvdata(dev);
-
- mxs_lradc_disable_ts(lradc);
-}
-
-static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
-{
- struct input_dev *input;
- struct device *dev = lradc->dev;
- int ret;
-
- if (!lradc->use_touchscreen)
- return 0;
-
- input = input_allocate_device();
- if (!input)
- return -ENOMEM;
-
- input->name = DRIVER_NAME;
- input->id.bustype = BUS_HOST;
- input->dev.parent = dev;
- input->open = mxs_lradc_ts_open;
- input->close = mxs_lradc_ts_close;
-
- __set_bit(EV_ABS, input->evbit);
- __set_bit(EV_KEY, input->evbit);
- __set_bit(BTN_TOUCH, input->keybit);
- input_set_abs_params(input, ABS_X, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
- input_set_abs_params(input, ABS_Y, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
- input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_SINGLE_SAMPLE_MASK,
- 0, 0);
-
- lradc->ts_input = input;
- input_set_drvdata(input, lradc);
- ret = input_register_device(input);
- if (ret)
- input_free_device(lradc->ts_input);
-
- return ret;
-}
-
-static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
-{
- if (!lradc->use_touchscreen)
- return;
-
- mxs_lradc_disable_ts(lradc);
- input_unregister_device(lradc->ts_input);
-}
-
-/*
- * IRQ Handling
- */
-static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
-{
- struct iio_dev *iio = data;
- struct mxs_lradc *lradc = iio_priv(iio);
- unsigned long reg = readl(lradc->base + LRADC_CTRL1);
- u32 clr_irq = mxs_lradc_irq_mask(lradc);
- const u32 ts_irq_mask =
- LRADC_CTRL1_TOUCH_DETECT_IRQ |
- LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
- LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2);
-
- if (!(reg & mxs_lradc_irq_mask(lradc)))
- return IRQ_NONE;
-
- if (lradc->use_touchscreen && (reg & ts_irq_mask)) {
- mxs_lradc_handle_touch(lradc);
-
- /* Make sure we don't clear the next conversion's interrupt. */
- clr_irq &= ~(LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
- LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2));
- }
-
- if (iio_buffer_enabled(iio)) {
- if (reg & lradc->buffer_vchans)
- iio_trigger_poll(iio->trig);
- } else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) {
- complete(&lradc->completion);
- }
-
- mxs_lradc_reg_clear(lradc, reg & clr_irq, LRADC_CTRL1);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Trigger handling
- */
-static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *iio = pf->indio_dev;
- struct mxs_lradc *lradc = iio_priv(iio);
- const u32 chan_value = LRADC_CH_ACCUMULATE |
- ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
- unsigned int i, j = 0;
-
- for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
- lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
- mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(j));
- lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
- lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
- j++;
- }
-
- iio_push_to_buffers_with_timestamp(iio, lradc->buffer, pf->timestamp);
-
- iio_trigger_notify_done(iio->trig);
-
- return IRQ_HANDLED;
-}
-
-static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
-{
- struct iio_dev *iio = iio_trigger_get_drvdata(trig);
- struct mxs_lradc *lradc = iio_priv(iio);
- const u32 st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
-
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
-
- return 0;
-}
-
-static const struct iio_trigger_ops mxs_lradc_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &mxs_lradc_configure_trigger,
-};
-
-static int mxs_lradc_trigger_init(struct iio_dev *iio)
-{
- int ret;
- struct iio_trigger *trig;
- struct mxs_lradc *lradc = iio_priv(iio);
-
- trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id);
- if (!trig)
- return -ENOMEM;
-
- trig->dev.parent = lradc->dev;
- iio_trigger_set_drvdata(trig, iio);
- trig->ops = &mxs_lradc_trigger_ops;
-
- ret = iio_trigger_register(trig);
- if (ret) {
- iio_trigger_free(trig);
- return ret;
- }
-
- lradc->trig = trig;
-
- return 0;
-}
-
-static void mxs_lradc_trigger_remove(struct iio_dev *iio)
-{
- struct mxs_lradc *lradc = iio_priv(iio);
-
- iio_trigger_unregister(lradc->trig);
- iio_trigger_free(lradc->trig);
-}
-
-static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
-{
- struct mxs_lradc *lradc = iio_priv(iio);
- int ret = 0, chan, ofs = 0;
- unsigned long enable = 0;
- u32 ctrl4_set = 0;
- u32 ctrl4_clr = 0;
- u32 ctrl1_irq = 0;
- const u32 chan_value = LRADC_CH_ACCUMULATE |
- ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
- const int len = bitmap_weight(iio->active_scan_mask,
- LRADC_MAX_TOTAL_CHANS);
-
- if (!len)
- return -EINVAL;
-
- /*
- * Lock the driver so raw access can not be done during buffered
- * operation. This simplifies the code a lot.
- */
- ret = mutex_trylock(&lradc->lock);
- if (!ret)
- return -EBUSY;
-
- lradc->buffer = kmalloc_array(len, sizeof(*lradc->buffer), GFP_KERNEL);
- if (!lradc->buffer) {
- ret = -ENOMEM;
- goto err_mem;
- }
-
- if (lradc->soc == IMX28_LRADC)
- mxs_lradc_reg_clear(
- lradc,
- lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
- LRADC_CTRL1);
- mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0);
-
- for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
- ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
- ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
- ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
- mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
- bitmap_set(&enable, ofs, 1);
- ofs++;
- }
-
- mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
- LRADC_DELAY_KICK, LRADC_DELAY(0));
- mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
- LRADC_DELAY(0));
-
- return 0;
-
-err_mem:
- mutex_unlock(&lradc->lock);
- return ret;
-}
-
-static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
-{
- struct mxs_lradc *lradc = iio_priv(iio);
-
- mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
- LRADC_DELAY_KICK, LRADC_DELAY(0));
-
- mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0);
- if (lradc->soc == IMX28_LRADC)
- mxs_lradc_reg_clear(
- lradc,
- lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
- LRADC_CTRL1);
-
- kfree(lradc->buffer);
- mutex_unlock(&lradc->lock);
-
- return 0;
-}
-
-static bool mxs_lradc_validate_scan_mask(struct iio_dev *iio,
- const unsigned long *mask)
-{
- struct mxs_lradc *lradc = iio_priv(iio);
- const int map_chans = bitmap_weight(mask, LRADC_MAX_TOTAL_CHANS);
- int rsvd_chans = 0;
- unsigned long rsvd_mask = 0;
-
- if (lradc->use_touchbutton)
- rsvd_mask |= CHAN_MASK_TOUCHBUTTON;
- if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_4WIRE)
- rsvd_mask |= CHAN_MASK_TOUCHSCREEN_4WIRE;
- if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
- rsvd_mask |= CHAN_MASK_TOUCHSCREEN_5WIRE;
-
- if (lradc->use_touchbutton)
- rsvd_chans++;
- if (lradc->use_touchscreen)
- rsvd_chans += 2;
-
- /* Test for attempts to map channels with special mode of operation. */
- if (bitmap_intersects(mask, &rsvd_mask, LRADC_MAX_TOTAL_CHANS))
- return false;
-
- /* Test for attempts to map more channels then available slots. */
- if (map_chans + rsvd_chans > LRADC_MAX_MAPPED_CHANS)
- return false;
-
- return true;
-}
-
-static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
- .preenable = &mxs_lradc_buffer_preenable,
- .postenable = &iio_triggered_buffer_postenable,
- .predisable = &iio_triggered_buffer_predisable,
- .postdisable = &mxs_lradc_buffer_postdisable,
- .validate_scan_mask = &mxs_lradc_validate_scan_mask,
-};
-
-/*
- * Driver initialization
- */
-
-#define MXS_ADC_CHAN(idx, chan_type, name) { \
- .type = (chan_type), \
- .indexed = 1, \
- .scan_index = (idx), \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
- BIT(IIO_CHAN_INFO_SCALE), \
- .channel = (idx), \
- .address = (idx), \
- .scan_type = { \
- .sign = 'u', \
- .realbits = LRADC_RESOLUTION, \
- .storagebits = 32, \
- }, \
- .datasheet_name = (name), \
-}
-
-static const struct iio_chan_spec mx23_lradc_chan_spec[] = {
- MXS_ADC_CHAN(0, IIO_VOLTAGE, "LRADC0"),
- MXS_ADC_CHAN(1, IIO_VOLTAGE, "LRADC1"),
- MXS_ADC_CHAN(2, IIO_VOLTAGE, "LRADC2"),
- MXS_ADC_CHAN(3, IIO_VOLTAGE, "LRADC3"),
- MXS_ADC_CHAN(4, IIO_VOLTAGE, "LRADC4"),
- MXS_ADC_CHAN(5, IIO_VOLTAGE, "LRADC5"),
- MXS_ADC_CHAN(6, IIO_VOLTAGE, "VDDIO"),
- MXS_ADC_CHAN(7, IIO_VOLTAGE, "VBATT"),
- /* Combined Temperature sensors */
- {
- .type = IIO_TEMP,
- .indexed = 1,
- .scan_index = 8,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_OFFSET) |
- BIT(IIO_CHAN_INFO_SCALE),
- .channel = 8,
- .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
- .datasheet_name = "TEMP_DIE",
- },
- /* Hidden channel to keep indexes */
- {
- .type = IIO_TEMP,
- .indexed = 1,
- .scan_index = -1,
- .channel = 9,
- },
- MXS_ADC_CHAN(10, IIO_VOLTAGE, NULL),
- MXS_ADC_CHAN(11, IIO_VOLTAGE, NULL),
- MXS_ADC_CHAN(12, IIO_VOLTAGE, "USB_DP"),
- MXS_ADC_CHAN(13, IIO_VOLTAGE, "USB_DN"),
- MXS_ADC_CHAN(14, IIO_VOLTAGE, "VBG"),
- MXS_ADC_CHAN(15, IIO_VOLTAGE, "VDD5V"),
-};
-
-static const struct iio_chan_spec mx28_lradc_chan_spec[] = {
- MXS_ADC_CHAN(0, IIO_VOLTAGE, "LRADC0"),
- MXS_ADC_CHAN(1, IIO_VOLTAGE, "LRADC1"),
- MXS_ADC_CHAN(2, IIO_VOLTAGE, "LRADC2"),
- MXS_ADC_CHAN(3, IIO_VOLTAGE, "LRADC3"),
- MXS_ADC_CHAN(4, IIO_VOLTAGE, "LRADC4"),
- MXS_ADC_CHAN(5, IIO_VOLTAGE, "LRADC5"),
- MXS_ADC_CHAN(6, IIO_VOLTAGE, "LRADC6"),
- MXS_ADC_CHAN(7, IIO_VOLTAGE, "VBATT"),
- /* Combined Temperature sensors */
- {
- .type = IIO_TEMP,
- .indexed = 1,
- .scan_index = 8,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_OFFSET) |
- BIT(IIO_CHAN_INFO_SCALE),
- .channel = 8,
- .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
- .datasheet_name = "TEMP_DIE",
- },
- /* Hidden channel to keep indexes */
- {
- .type = IIO_TEMP,
- .indexed = 1,
- .scan_index = -1,
- .channel = 9,
- },
- MXS_ADC_CHAN(10, IIO_VOLTAGE, "VDDIO"),
- MXS_ADC_CHAN(11, IIO_VOLTAGE, "VTH"),
- MXS_ADC_CHAN(12, IIO_VOLTAGE, "VDDA"),
- MXS_ADC_CHAN(13, IIO_VOLTAGE, "VDDD"),
- MXS_ADC_CHAN(14, IIO_VOLTAGE, "VBG"),
- MXS_ADC_CHAN(15, IIO_VOLTAGE, "VDD5V"),
-};
-
-static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
-{
- /* The ADC always uses DELAY CHANNEL 0. */
- const u32 adc_cfg =
- (1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
- (LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);
-
- int ret = stmp_reset_block(lradc->base);
-
- if (ret)
- return ret;
-
- /* Configure DELAY CHANNEL 0 for generic ADC sampling. */
- mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
-
- /* Disable remaining DELAY CHANNELs */
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(1));
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
-
- /* Configure the touchscreen type */
- if (lradc->soc == IMX28_LRADC) {
- mxs_lradc_reg_clear(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
- LRADC_CTRL0);
-
- if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
- mxs_lradc_reg_set(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
- LRADC_CTRL0);
- }
-
- /* Start internal temperature sensing. */
- mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
-
- return 0;
-}
-
-static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
-{
- int i;
-
- mxs_lradc_reg_clear(lradc, mxs_lradc_irq_en_mask(lradc), LRADC_CTRL1);
-
- for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
-}
-
-static const struct of_device_id mxs_lradc_dt_ids[] = {
- { .compatible = "fsl,imx23-lradc", .data = (void *)IMX23_LRADC, },
- { .compatible = "fsl,imx28-lradc", .data = (void *)IMX28_LRADC, },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
-
-static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
- struct device_node *lradc_node)
-{
- int ret;
- u32 ts_wires = 0, adapt;
-
- ret = of_property_read_u32(lradc_node, "fsl,lradc-touchscreen-wires",
- &ts_wires);
- if (ret)
- return -ENODEV; /* touchscreen feature disabled */
-
- switch (ts_wires) {
- case 4:
- lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
- break;
- case 5:
- if (lradc->soc == IMX28_LRADC) {
- lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
- break;
- }
- /* fall through an error message for i.MX23 */
- default:
- dev_err(lradc->dev,
- "Unsupported number of touchscreen wires (%d)\n",
- ts_wires);
- return -EINVAL;
- }
-
- if (of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt)) {
- lradc->over_sample_cnt = 4;
- } else {
- if (adapt < 1 || adapt > 32) {
- dev_err(lradc->dev, "Invalid sample count (%u)\n",
- adapt);
- return -EINVAL;
- }
- lradc->over_sample_cnt = adapt;
- }
-
- if (of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt)) {
- lradc->over_sample_delay = 2;
- } else {
- if (adapt < 2 || adapt > LRADC_DELAY_DELAY_MASK + 1) {
- dev_err(lradc->dev, "Invalid sample delay (%u)\n",
- adapt);
- return -EINVAL;
- }
- lradc->over_sample_delay = adapt;
- }
-
- if (of_property_read_u32(lradc_node, "fsl,settling", &adapt)) {
- lradc->settling_delay = 10;
- } else {
- if (adapt < 1 || adapt > LRADC_DELAY_DELAY_MASK) {
- dev_err(lradc->dev, "Invalid settling delay (%u)\n",
- adapt);
- return -EINVAL;
- }
- lradc->settling_delay = adapt;
- }
-
- return 0;
-}
-
-static int mxs_lradc_probe(struct platform_device *pdev)
-{
- const struct of_device_id *of_id =
- of_match_device(mxs_lradc_dt_ids, &pdev->dev);
- const struct mxs_lradc_of_config *of_cfg =
- &mxs_lradc_of_config[(enum mxs_lradc_id)of_id->data];
- struct device *dev = &pdev->dev;
- struct device_node *node = dev->of_node;
- struct mxs_lradc *lradc;
- struct iio_dev *iio;
- struct resource *iores;
- int ret = 0, touch_ret;
- int i, s;
- u64 scale_uv;
-
- /* Allocate the IIO device. */
- iio = devm_iio_device_alloc(dev, sizeof(*lradc));
- if (!iio) {
- dev_err(dev, "Failed to allocate IIO device\n");
- return -ENOMEM;
- }
-
- lradc = iio_priv(iio);
- lradc->soc = (enum mxs_lradc_id)of_id->data;
-
- /* Grab the memory area */
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- lradc->dev = &pdev->dev;
- lradc->base = devm_ioremap_resource(dev, iores);
- if (IS_ERR(lradc->base))
- return PTR_ERR(lradc->base);
-
- lradc->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(lradc->clk)) {
- dev_err(dev, "Failed to get the delay unit clock\n");
- return PTR_ERR(lradc->clk);
- }
- ret = clk_prepare_enable(lradc->clk);
- if (ret != 0) {
- dev_err(dev, "Failed to enable the delay unit clock\n");
- return ret;
- }
-
- touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
-
- if (touch_ret == 0)
- lradc->buffer_vchans = BUFFER_VCHANS_LIMITED;
- else
- lradc->buffer_vchans = BUFFER_VCHANS_ALL;
-
- /* Grab all IRQ sources */
- for (i = 0; i < of_cfg->irq_count; i++) {
- lradc->irq[i] = platform_get_irq(pdev, i);
- if (lradc->irq[i] < 0) {
- ret = lradc->irq[i];
- goto err_clk;
- }
-
- ret = devm_request_irq(dev, lradc->irq[i],
- mxs_lradc_handle_irq, 0,
- of_cfg->irq_name[i], iio);
- if (ret)
- goto err_clk;
- }
-
- lradc->vref_mv = of_cfg->vref_mv;
-
- platform_set_drvdata(pdev, iio);
-
- init_completion(&lradc->completion);
- mutex_init(&lradc->lock);
-
- iio->name = pdev->name;
- iio->dev.parent = &pdev->dev;
- iio->info = &mxs_lradc_iio_info;
- iio->modes = INDIO_DIRECT_MODE;
- iio->masklength = LRADC_MAX_TOTAL_CHANS;
-
- if (lradc->soc == IMX23_LRADC) {
- iio->channels = mx23_lradc_chan_spec;
- iio->num_channels = ARRAY_SIZE(mx23_lradc_chan_spec);
- } else {
- iio->channels = mx28_lradc_chan_spec;
- iio->num_channels = ARRAY_SIZE(mx28_lradc_chan_spec);
- }
-
- ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time,
- &mxs_lradc_trigger_handler,
- &mxs_lradc_buffer_ops);
- if (ret)
- goto err_clk;
-
- ret = mxs_lradc_trigger_init(iio);
- if (ret)
- goto err_trig;
-
- /* Populate available ADC input ranges */
- for (i = 0; i < LRADC_MAX_TOTAL_CHANS; i++) {
- for (s = 0; s < ARRAY_SIZE(lradc->scale_avail[i]); s++) {
- /*
- * [s=0] = optional divider by two disabled (default)
- * [s=1] = optional divider by two enabled
- *
- * The scale is calculated by doing:
- * Vref >> (realbits - s)
- * which multiplies by two on the second component
- * of the array.
- */
- scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >>
- (LRADC_RESOLUTION - s);
- lradc->scale_avail[i][s].nano =
- do_div(scale_uv, 100000000) * 10;
- lradc->scale_avail[i][s].integer = scale_uv;
- }
- }
-
- /* Configure the hardware. */
- ret = mxs_lradc_hw_init(lradc);
- if (ret)
- goto err_dev;
-
- /* Register the touchscreen input device. */
- if (touch_ret == 0) {
- ret = mxs_lradc_ts_register(lradc);
- if (ret)
- goto err_ts_register;
- }
-
- /* Register IIO device. */
- ret = iio_device_register(iio);
- if (ret) {
- dev_err(dev, "Failed to register IIO device\n");
- goto err_ts;
- }
-
- return 0;
-
-err_ts:
- mxs_lradc_ts_unregister(lradc);
-err_ts_register:
- mxs_lradc_hw_stop(lradc);
-err_dev:
- mxs_lradc_trigger_remove(iio);
-err_trig:
- iio_triggered_buffer_cleanup(iio);
-err_clk:
- clk_disable_unprepare(lradc->clk);
- return ret;
-}
-
-static int mxs_lradc_remove(struct platform_device *pdev)
-{
- struct iio_dev *iio = platform_get_drvdata(pdev);
- struct mxs_lradc *lradc = iio_priv(iio);
-
- iio_device_unregister(iio);
- mxs_lradc_ts_unregister(lradc);
- mxs_lradc_hw_stop(lradc);
- mxs_lradc_trigger_remove(iio);
- iio_triggered_buffer_cleanup(iio);
-
- clk_disable_unprepare(lradc->clk);
- return 0;
-}
-
-static struct platform_driver mxs_lradc_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .of_match_table = mxs_lradc_dt_ids,
- },
- .probe = mxs_lradc_probe,
- .remove = mxs_lradc_remove,
-};
-
-module_platform_driver(mxs_lradc_driver);
-
-MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
-MODULE_DESCRIPTION("Freescale MXS LRADC driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 712cae0e8..5dd61f6a5 100644
--- a/drivers/staging/iio/adc/spear_adc.c
+++ b/drivers/staging/iio/adc/spear_adc.c
@@ -262,6 +262,7 @@ static int spear_adc_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct spear_adc_state *st;
+ struct resource *res;
struct iio_dev *indio_dev = NULL;
int ret = -ENODEV;
int irq;
@@ -280,45 +281,45 @@ static int spear_adc_probe(struct platform_device *pdev)
* (e.g. SPEAr3xx). Let's provide two register base addresses
* to support multi-arch kernels.
*/
- st->adc_base_spear6xx = of_iomap(np, 0);
- if (!st->adc_base_spear6xx) {
- dev_err(dev, "failed mapping memory\n");
- return -ENOMEM;
- }
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ st->adc_base_spear6xx = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(st->adc_base_spear6xx))
+ return PTR_ERR(st->adc_base_spear6xx);
+
st->adc_base_spear3xx =
(struct adc_regs_spear3xx __iomem *)st->adc_base_spear6xx;
- st->clk = clk_get(dev, NULL);
+ st->clk = devm_clk_get(dev, NULL);
if (IS_ERR(st->clk)) {
dev_err(dev, "failed getting clock\n");
- goto errout1;
+ return PTR_ERR(st->clk);
}
ret = clk_prepare_enable(st->clk);
if (ret) {
dev_err(dev, "failed enabling clock\n");
- goto errout2;
+ return ret;
}
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(dev, "failed getting interrupt resource\n");
ret = -EINVAL;
- goto errout3;
+ goto errout2;
}
ret = devm_request_irq(dev, irq, spear_adc_isr, 0, SPEAR_ADC_MOD_NAME,
st);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
- goto errout3;
+ goto errout2;
}
if (of_property_read_u32(np, "sampling-frequency",
&st->sampling_freq)) {
dev_err(dev, "sampling-frequency missing in DT\n");
ret = -EINVAL;
- goto errout3;
+ goto errout2;
}
/*
@@ -348,18 +349,14 @@ static int spear_adc_probe(struct platform_device *pdev)
ret = iio_device_register(indio_dev);
if (ret)
- goto errout3;
+ goto errout2;
dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
return 0;
-errout3:
- clk_disable_unprepare(st->clk);
errout2:
- clk_put(st->clk);
-errout1:
- iounmap(st->adc_base_spear6xx);
+ clk_disable_unprepare(st->clk);
return ret;
}
@@ -370,8 +367,6 @@ static int spear_adc_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
clk_disable_unprepare(st->clk);
- clk_put(st->clk);
- iounmap(st->adc_base_spear6xx);
return 0;
}
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c
index 78fe0b557..0ccf192b9 100644
--- a/drivers/staging/iio/addac/adt7316-i2c.c
+++ b/drivers/staging/iio/addac/adt7316-i2c.c
@@ -21,7 +21,7 @@
static int adt7316_i2c_read(void *client, u8 reg, u8 *data)
{
struct i2c_client *cl = client;
- int ret = 0;
+ int ret;
ret = i2c_smbus_write_byte(cl, reg);
if (ret < 0) {
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 3adc45169..a10e7d8e6 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -465,9 +465,8 @@ static ssize_t adt7316_show_all_ad_channels(struct device *dev,
return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
"2 - External Temperature or AIN1\n"
"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
- else
- return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
- "2 - External Temperature\n");
+ return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+ "2 - External Temperature\n");
}
static IIO_DEVICE_ATTR(all_ad_channels, S_IRUGO,
@@ -637,7 +636,7 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev,
if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) {
if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
return sprintf(buf, "1 (12 bits)\n");
- else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
+ if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
return sprintf(buf, "1 (10 bits)\n");
}
@@ -919,8 +918,7 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev,
"1 - auto at MSB DAC AB and CD writing\n"
"2 - auto at MSB DAC ABCD writing\n"
"3 - manual\n");
- else
- return sprintf(buf, "manual\n");
+ return sprintf(buf, "manual\n");
}
static IIO_DEVICE_ATTR(all_DAC_update_modes, S_IRUGO,
@@ -1068,9 +1066,8 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev,
return sprintf(buf, "0x%x\n",
(chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >>
ADT7516_DAC_IN_VREF_OFFSET);
- else
- return sprintf(buf, "%d\n",
- !!(chip->dac_config & ADT7316_DAC_IN_VREF));
+ return sprintf(buf, "%d\n",
+ !!(chip->dac_config & ADT7316_DAC_IN_VREF));
}
static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index e8d0ff2d5..f6b9a1032 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -21,8 +21,8 @@
*/
#define AD7150_STATUS 0
-#define AD7150_STATUS_OUT1 (1 << 3)
-#define AD7150_STATUS_OUT2 (1 << 5)
+#define AD7150_STATUS_OUT1 BIT(3)
+#define AD7150_STATUS_OUT2 BIT(5)
#define AD7150_CH1_DATA_HIGH 1
#define AD7150_CH2_DATA_HIGH 3
#define AD7150_CH1_AVG_HIGH 5
@@ -36,7 +36,7 @@
#define AD7150_CH2_TIMEOUT 13
#define AD7150_CH2_SETUP 14
#define AD7150_CFG 15
-#define AD7150_CFG_FIX (1 << 7)
+#define AD7150_CFG_FIX BIT(7)
#define AD7150_PD_TIMER 16
#define AD7150_CH1_CAPDAC 17
#define AD7150_CH2_CAPDAC 18
@@ -160,8 +160,9 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev,
/* lock should be held */
static int ad7150_write_event_params(struct iio_dev *indio_dev,
- unsigned int chan, enum iio_event_type type,
- enum iio_event_direction dir)
+ unsigned int chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir)
{
int ret;
u16 value;
@@ -209,8 +210,9 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev,
}
static int ad7150_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan, enum iio_event_type type,
- enum iio_event_direction dir, int state)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir, int state)
{
u8 thresh_type, cfg, adaptive;
int ret;
@@ -302,11 +304,11 @@ static int ad7150_read_event_value(struct iio_dev *indio_dev,
}
static int ad7150_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ const struct iio_chan_spec *chan,
+ enum iio_event_type type,
+ enum iio_event_direction dir,
+ enum iio_event_info info,
+ int val, int val2)
{
int ret;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
@@ -365,9 +367,9 @@ static ssize_t ad7150_show_timeout(struct device *dev,
}
static ssize_t ad7150_store_timeout(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7150_chip_info *chip = iio_priv(indio_dev);
@@ -580,7 +582,7 @@ static const struct iio_info ad7150_info = {
*/
static int ad7150_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
int ret;
struct ad7150_chip_info *chip;
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index 2c5d27784..5771d4ee8 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -529,8 +529,8 @@ static int ad7746_write_raw(struct iio_dev *indio_dev,
val /= 338646;
- chip->capdac[chan->channel][chan->differential] = (val > 0 ?
- AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0);
+ chip->capdac[chan->channel][chan->differential] = val > 0 ?
+ AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0;
ret = i2c_smbus_write_byte_data(chip->client,
AD7746_REG_CAPDACA,
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 10c43dda0..d1218d896 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -558,7 +558,7 @@ out:
}
static const struct iio_info ad5933_info = {
- .read_raw = &ad5933_read_raw,
+ .read_raw = ad5933_read_raw,
.attrs = &ad5933_attribute_group,
.driver_module = THIS_MODULE,
};
@@ -616,9 +616,9 @@ static int ad5933_ring_postdisable(struct iio_dev *indio_dev)
}
static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
- .preenable = &ad5933_ring_preenable,
- .postenable = &ad5933_ring_postenable,
- .postdisable = &ad5933_ring_postdisable,
+ .preenable = ad5933_ring_preenable,
+ .postenable = ad5933_ring_postenable,
+ .postdisable = ad5933_ring_postdisable,
};
static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index bbf7e35cb..76d9f74e7 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -100,7 +100,6 @@ static const struct isl29018_scale {
};
struct isl29018_chip {
- struct device *dev;
struct regmap *regmap;
struct mutex lock;
int type;
@@ -180,30 +179,31 @@ static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
int status;
unsigned int lsb;
unsigned int msb;
+ struct device *dev = regmap_get_device(chip->regmap);
/* Set mode */
status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1,
- mode << COMMMAND1_OPMODE_SHIFT);
+ mode << COMMMAND1_OPMODE_SHIFT);
if (status) {
- dev_err(chip->dev,
+ dev_err(dev,
"Error in setting operating mode err %d\n", status);
return status;
}
msleep(CONVERSION_TIME_MS);
status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_LSB, &lsb);
if (status < 0) {
- dev_err(chip->dev,
+ dev_err(dev,
"Error in reading LSB DATA with err %d\n", status);
return status;
}
status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_MSB, &msb);
if (status < 0) {
- dev_err(chip->dev,
+ dev_err(dev,
"Error in reading MSB DATA with error %d\n", status);
return status;
}
- dev_vdbg(chip->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb);
+ dev_vdbg(dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb);
return (msb << 8) | lsb;
}
@@ -241,23 +241,24 @@ static int isl29018_read_ir(struct isl29018_chip *chip, int *ir)
}
static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
- int *near_ir)
+ int *near_ir)
{
int status;
int prox_data = -1;
int ir_data = -1;
+ struct device *dev = regmap_get_device(chip->regmap);
/* Do proximity sensing with required scheme */
status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII,
- COMMANDII_SCHEME_MASK,
- scheme << COMMANDII_SCHEME_SHIFT);
+ COMMANDII_SCHEME_MASK,
+ scheme << COMMANDII_SCHEME_SHIFT);
if (status) {
- dev_err(chip->dev, "Error in setting operating mode\n");
+ dev_err(dev, "Error in setting operating mode\n");
return status;
}
prox_data = isl29018_read_sensor_input(chip,
- COMMMAND1_OPMODE_PROX_ONCE);
+ COMMMAND1_OPMODE_PROX_ONCE);
if (prox_data < 0)
return prox_data;
@@ -280,7 +281,7 @@ static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
}
static ssize_t show_scale_available(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
@@ -297,7 +298,7 @@ static ssize_t show_scale_available(struct device *dev,
}
static ssize_t show_int_time_available(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
@@ -314,18 +315,22 @@ static ssize_t show_int_time_available(struct device *dev,
/* proximity scheme */
static ssize_t show_prox_infrared_suppression(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
- /* return the "proximity scheme" i.e. if the chip does on chip
- infrared suppression (1 means perform on chip suppression) */
+ /*
+ * return the "proximity scheme" i.e. if the chip does on chip
+ * infrared suppression (1 means perform on chip suppression)
+ */
return sprintf(buf, "%d\n", chip->prox_scheme);
}
static ssize_t store_prox_infrared_suppression(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
@@ -338,8 +343,10 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
return -EINVAL;
}
- /* get the "proximity scheme" i.e. if the chip does on chip
- infrared suppression (1 means perform on chip suppression) */
+ /*
+ * get the "proximity scheme" i.e. if the chip does on chip
+ * infrared suppression (1 means perform on chip suppression)
+ */
mutex_lock(&chip->lock);
chip->prox_scheme = val;
mutex_unlock(&chip->lock);
@@ -413,7 +420,8 @@ static int isl29018_read_raw(struct iio_dev *indio_dev,
break;
case IIO_PROXIMITY:
ret = isl29018_read_proximity_ir(chip,
- chip->prox_scheme, val);
+ chip->prox_scheme,
+ val);
break;
default:
break;
@@ -518,10 +526,11 @@ static int isl29035_detect(struct isl29018_chip *chip)
{
int status;
unsigned int id;
+ struct device *dev = regmap_get_device(chip->regmap);
status = regmap_read(chip->regmap, ISL29035_REG_DEVICE_ID, &id);
if (status < 0) {
- dev_err(chip->dev,
+ dev_err(dev,
"Error reading ID register with error %d\n",
status);
return status;
@@ -546,6 +555,7 @@ enum {
static int isl29018_chip_init(struct isl29018_chip *chip)
{
int status;
+ struct device *dev = regmap_get_device(chip->regmap);
if (chip->type == isl29035) {
status = isl29035_detect(chip);
@@ -575,7 +585,7 @@ static int isl29018_chip_init(struct isl29018_chip *chip)
*/
status = regmap_write(chip->regmap, ISL29018_REG_TEST, 0x0);
if (status < 0) {
- dev_err(chip->dev, "Failed to clear isl29018 TEST reg.(%d)\n",
+ dev_err(dev, "Failed to clear isl29018 TEST reg.(%d)\n",
status);
return status;
}
@@ -586,7 +596,7 @@ static int isl29018_chip_init(struct isl29018_chip *chip)
*/
status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, 0);
if (status < 0) {
- dev_err(chip->dev, "Failed to clear isl29018 CMD1 reg.(%d)\n",
+ dev_err(dev, "Failed to clear isl29018 CMD1 reg.(%d)\n",
status);
return status;
}
@@ -597,14 +607,14 @@ static int isl29018_chip_init(struct isl29018_chip *chip)
status = isl29018_set_scale(chip, chip->scale.scale,
chip->scale.uscale);
if (status < 0) {
- dev_err(chip->dev, "Init of isl29018 fails\n");
+ dev_err(dev, "Init of isl29018 fails\n");
return status;
}
status = isl29018_set_integration_time(chip,
isl29018_int_utimes[chip->type][chip->int_time]);
if (status < 0) {
- dev_err(chip->dev, "Init of isl29018 fails\n");
+ dev_err(dev, "Init of isl29018 fails\n");
return status;
}
@@ -614,15 +624,15 @@ static int isl29018_chip_init(struct isl29018_chip *chip)
static const struct iio_info isl29018_info = {
.attrs = &isl29018_group,
.driver_module = THIS_MODULE,
- .read_raw = &isl29018_read_raw,
- .write_raw = &isl29018_write_raw,
+ .read_raw = isl29018_read_raw,
+ .write_raw = isl29018_write_raw,
};
static const struct iio_info isl29023_info = {
.attrs = &isl29023_group,
.driver_module = THIS_MODULE,
- .read_raw = &isl29018_read_raw,
- .write_raw = &isl29018_write_raw,
+ .read_raw = isl29018_read_raw,
+ .write_raw = isl29018_write_raw,
};
static bool is_volatile_reg(struct device *dev, unsigned int reg)
@@ -699,13 +709,13 @@ static const char *isl29018_match_acpi_device(struct device *dev, int *data)
if (!id)
return NULL;
- *data = (int) id->driver_data;
+ *data = (int)id->driver_data;
return dev_name(dev);
}
static int isl29018_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct isl29018_chip *chip;
struct iio_dev *indio_dev;
@@ -721,7 +731,6 @@ static int isl29018_probe(struct i2c_client *client,
chip = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
- chip->dev = &client->dev;
if (id) {
name = id->name;
@@ -744,7 +753,7 @@ static int isl29018_probe(struct i2c_client *client,
chip_info_tbl[dev_id].regmap_cfg);
if (IS_ERR(chip->regmap)) {
err = PTR_ERR(chip->regmap);
- dev_err(chip->dev, "regmap initialization failed: %d\n", err);
+ dev_err(&client->dev, "regmap initialization fails: %d\n", err);
return err;
}
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index 32ae1127d..6e2ba458c 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -81,7 +81,7 @@ struct isl29028_chip {
};
static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
- unsigned int sampling)
+ unsigned int sampling)
{
static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0};
int sel;
@@ -103,7 +103,7 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable)
if (enable)
val = CONFIGURE_PROX_EN;
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_PROX_EN_MASK, val);
+ CONFIGURE_PROX_EN_MASK, val);
if (ret < 0)
return ret;
@@ -122,24 +122,27 @@ static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
}
static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
- enum als_ir_mode mode)
+ enum als_ir_mode mode)
{
int ret = 0;
switch (mode) {
case MODE_ALS:
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_ALS);
+ CONFIGURE_ALS_IR_MODE_MASK,
+ CONFIGURE_ALS_IR_MODE_ALS);
if (ret < 0)
return ret;
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_RANGE_MASK, CONFIGURE_ALS_RANGE_HIGH_LUX);
+ CONFIGURE_ALS_RANGE_MASK,
+ CONFIGURE_ALS_RANGE_HIGH_LUX);
break;
case MODE_IR:
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_IR);
+ CONFIGURE_ALS_IR_MODE_MASK,
+ CONFIGURE_ALS_IR_MODE_IR);
break;
case MODE_NONE:
@@ -152,7 +155,7 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
/* Enable the ALS/IR */
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_EN);
+ CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_EN);
if (ret < 0)
return ret;
@@ -193,7 +196,7 @@ static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox)
ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data);
if (ret < 0) {
dev_err(chip->dev, "Error in reading register %d, error %d\n",
- ISL29028_REG_PROX_DATA, ret);
+ ISL29028_REG_PROX_DATA, ret);
return ret;
}
*prox = data;
@@ -264,7 +267,8 @@ static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
/* Channel IO */
static int isl29028_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan, int val, int val2, long mask)
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
{
struct isl29028_chip *chip = iio_priv(indio_dev);
int ret = -EINVAL;
@@ -323,7 +327,8 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
}
static int isl29028_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan, int *val, int *val2, long mask)
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
{
struct isl29028_chip *chip = iio_priv(indio_dev);
int ret = -EINVAL;
@@ -406,8 +411,8 @@ static const struct iio_chan_spec isl29028_channels[] = {
static const struct iio_info isl29028_info = {
.attrs = &isl29108_group,
.driver_module = THIS_MODULE,
- .read_raw = &isl29028_read_raw,
- .write_raw = &isl29028_write_raw,
+ .read_raw = isl29028_read_raw,
+ .write_raw = isl29028_write_raw,
};
static int isl29028_chip_init(struct isl29028_chip *chip)
@@ -476,7 +481,7 @@ static const struct regmap_config isl29028_regmap_config = {
};
static int isl29028_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct isl29028_chip *chip;
struct iio_dev *indio_dev;
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index 3100d960f..05b4ad4e9 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -240,8 +240,10 @@ static int taos_get_lux(struct iio_dev *indio_dev)
}
}
- /* clear status, really interrupt status (interrupts are off), but
- * we use the bit anyway - don't forget 0x80 - this is a command*/
+ /*
+ * clear status, really interrupt status (interrupts are off), but
+ * we use the bit anyway - don't forget 0x80 - this is a command
+ */
ret = i2c_smbus_write_byte(chip->client,
(TSL258X_CMD_REG | TSL258X_CMD_SPL_FN |
TSL258X_CMD_ALS_INT_CLR));
@@ -265,13 +267,14 @@ static int taos_get_lux(struct iio_dev *indio_dev)
if (!ch0) {
/* have no data, so return LAST VALUE */
- ret = chip->als_cur_info.lux = 0;
+ ret = 0;
+ chip->als_cur_info.lux = 0;
goto out_unlock;
}
/* calculate ratio */
ratio = (ch1 << 15) / ch0;
/* convert to unscaled lux using the pointer to the table */
- for (p = (struct taos_lux *) taos_device_lux;
+ for (p = (struct taos_lux *)taos_device_lux;
p->ratio != 0 && p->ratio < ratio; p++)
;
@@ -290,7 +293,8 @@ static int taos_get_lux(struct iio_dev *indio_dev)
/* note: lux is 31 bit max at this point */
if (ch1lux > ch0lux) {
dev_dbg(&chip->client->dev, "No Data - Return last value\n");
- ret = chip->als_cur_info.lux = 0;
+ ret = 0;
+ chip->als_cur_info.lux = 0;
goto out_unlock;
}
@@ -378,7 +382,7 @@ static int taos_als_calibrate(struct iio_dev *indio_dev)
dev_err(&chip->client->dev, "taos_als_calibrate failed to get lux\n");
return lux_val;
}
- gain_trim_val = (unsigned int) (((chip->taos_settings.als_cal_target)
+ gain_trim_val = (unsigned int)(((chip->taos_settings.als_cal_target)
* chip->taos_settings.als_gain_trim) / lux_val);
if ((gain_trim_val < 250) || (gain_trim_val > 4000)) {
@@ -387,9 +391,9 @@ static int taos_als_calibrate(struct iio_dev *indio_dev)
gain_trim_val);
return -ENODATA;
}
- chip->taos_settings.als_gain_trim = (int) gain_trim_val;
+ chip->taos_settings.als_gain_trim = (int)gain_trim_val;
- return (int) gain_trim_val;
+ return (int)gain_trim_val;
}
/*
@@ -429,8 +433,10 @@ static int taos_chip_on(struct iio_dev *indio_dev)
chip->als_saturation = als_count * 922; /* 90% of full scale */
chip->als_time_scale = (als_time + 25) / 50;
- /* TSL258x Specific power-on / adc enable sequence
- * Power on the device 1st. */
+ /*
+ * TSL258x Specific power-on / adc enable sequence
+ * Power on the device 1st.
+ */
utmp = TSL258X_CNTL_PWR_ON;
ret = i2c_smbus_write_byte_data(chip->client,
TSL258X_CMD_REG | TSL258X_CNTRL, utmp);
@@ -439,8 +445,10 @@ static int taos_chip_on(struct iio_dev *indio_dev)
return ret;
}
- /* Use the following shadow copy for our delay before enabling ADC.
- * Write all the registers. */
+ /*
+ * Use the following shadow copy for our delay before enabling ADC.
+ * Write all the registers.
+ */
for (i = 0, uP = chip->taos_config; i < TSL258X_REG_MAX; i++) {
ret = i2c_smbus_write_byte_data(chip->client,
TSL258X_CMD_REG + i,
@@ -453,8 +461,10 @@ static int taos_chip_on(struct iio_dev *indio_dev)
}
usleep_range(3000, 3500);
- /* NOW enable the ADC
- * initialize the desired mode of operation */
+ /*
+ * NOW enable the ADC
+ * initialize the desired mode of operation
+ */
utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL;
ret = i2c_smbus_write_byte_data(chip->client,
TSL258X_CMD_REG | TSL258X_CNTRL,
@@ -482,7 +492,7 @@ static int taos_chip_off(struct iio_dev *indio_dev)
/* Sysfs Interface Functions */
static ssize_t taos_power_state_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -491,7 +501,8 @@ static ssize_t taos_power_state_show(struct device *dev,
}
static ssize_t taos_power_state_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
int value;
@@ -508,7 +519,7 @@ static ssize_t taos_power_state_store(struct device *dev,
}
static ssize_t taos_gain_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -533,7 +544,8 @@ static ssize_t taos_gain_show(struct device *dev,
}
static ssize_t taos_gain_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -564,13 +576,14 @@ static ssize_t taos_gain_store(struct device *dev,
}
static ssize_t taos_gain_available_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%s\n", "1 8 16 111");
}
static ssize_t taos_als_time_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -579,7 +592,8 @@ static ssize_t taos_als_time_show(struct device *dev,
}
static ssize_t taos_als_time_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -600,14 +614,15 @@ static ssize_t taos_als_time_store(struct device *dev,
}
static ssize_t taos_als_time_available_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%s\n",
"50 100 150 200 250 300 350 400 450 500 550 600 650");
}
static ssize_t taos_als_trim_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -616,7 +631,8 @@ static ssize_t taos_als_trim_show(struct device *dev,
}
static ssize_t taos_als_trim_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -632,7 +648,8 @@ static ssize_t taos_als_trim_store(struct device *dev,
}
static ssize_t taos_als_cal_target_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -641,7 +658,8 @@ static ssize_t taos_als_cal_target_show(struct device *dev,
}
static ssize_t taos_als_cal_target_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
@@ -657,7 +675,7 @@ static ssize_t taos_als_cal_target_store(struct device *dev,
}
static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+ char *buf)
{
int ret;
@@ -669,7 +687,8 @@ static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr,
}
static ssize_t taos_do_calibrate(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
int value;
@@ -684,7 +703,7 @@ static ssize_t taos_do_calibrate(struct device *dev,
}
static ssize_t taos_luxtable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
int i;
int offset = 0;
@@ -695,8 +714,10 @@ static ssize_t taos_luxtable_show(struct device *dev,
taos_device_lux[i].ch0,
taos_device_lux[i].ch1);
if (taos_device_lux[i].ratio == 0) {
- /* We just printed the first "0" entry.
- * Now get rid of the extra "," and break. */
+ /*
+ * We just printed the first "0" entry.
+ * Now get rid of the extra "," and break.
+ */
offset--;
break;
}
@@ -707,11 +728,12 @@ static ssize_t taos_luxtable_show(struct device *dev,
}
static ssize_t taos_luxtable_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value[ARRAY_SIZE(taos_device_lux)*3 + 1];
+ int value[ARRAY_SIZE(taos_device_lux) * 3 + 1];
int n;
get_options(buf, ARRAY_SIZE(value), value);
@@ -809,7 +831,7 @@ static int taos_probe(struct i2c_client *clientp,
struct iio_dev *indio_dev;
if (!i2c_check_functionality(clientp->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA)) {
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&clientp->dev, "taos_probe() - i2c smbus byte data func unsupported\n");
return -EOPNOTSUPP;
}
@@ -846,7 +868,7 @@ static int taos_probe(struct i2c_client *clientp,
if (!taos_tsl258x_device(buf)) {
dev_info(&clientp->dev,
- "i2c device found but does not match expected id in taos_probe()\n");
+ "i2c device found but does not match expected id in taos_probe()\n");
return -EINVAL;
}
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 5b1c1650a..5f308bae4 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -296,7 +296,7 @@ static const u8 device_channel_config[] = {
static int
tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
{
- int ret = 0;
+ int ret;
/* select register to write */
ret = i2c_smbus_write_byte(client, (TSL2X7X_CMD_REG | reg));
@@ -687,9 +687,9 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
/* Set the gain based on tsl2x7x_settings struct */
chip->tsl2x7x_config[TSL2X7X_GAIN] =
- (chip->tsl2x7x_settings.als_gain |
+ chip->tsl2x7x_settings.als_gain |
(TSL2X7X_mA100 | TSL2X7X_DIODE1)
- | ((chip->tsl2x7x_settings.prox_gain) << 2));
+ | ((chip->tsl2x7x_settings.prox_gain) << 2);
/* set chip struct re scaling and saturation */
chip->als_saturation = als_count * 922; /* 90% of full scale */
@@ -983,7 +983,7 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev,
result.fract /= 3;
chip->tsl2x7x_settings.als_time =
- (TSL2X7X_MAX_TIMER_CNT - (u8)result.fract);
+ TSL2X7X_MAX_TIMER_CNT - (u8)result.fract;
dev_info(&chip->client->dev, "%s: als time = %d",
__func__, chip->tsl2x7x_settings.als_time);
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
deleted file mode 100644
index dec814a7a..000000000
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Magnetometer sensors
-#
-menu "Magnetometer sensors"
-
-config SENSORS_HMC5843
- tristate
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
-
-config SENSORS_HMC5843_I2C
- tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer (I2C)"
- depends on I2C
- select SENSORS_HMC5843
- select REGMAP_I2C
- help
- Say Y here to add support for the Honeywell HMC5843, HMC5883 and
- HMC5883L 3-Axis Magnetometer (digital compass).
-
- This driver can also be compiled as a set of modules.
- If so, these modules will be created:
- - hmc5843_core (core functions)
- - hmc5843_i2c (support for HMC5843, HMC5883, HMC5883L and HMC5983)
-
-config SENSORS_HMC5843_SPI
- tristate "Honeywell HMC5983 3-Axis Magnetometer (SPI)"
- depends on SPI_MASTER
- select SENSORS_HMC5843
- select REGMAP_SPI
- help
- Say Y here to add support for the Honeywell HMC5983 3-Axis Magnetometer
- (digital compass).
-
- This driver can also be compiled as a set of modules.
- If so, these modules will be created:
- - hmc5843_core (core functions)
- - hmc5843_spi (support for HMC5983)
-
-
-endmenu
diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile
deleted file mode 100644
index 33761a19a..000000000
--- a/drivers/staging/iio/magnetometer/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for industrial I/O Magnetometer sensors
-#
-
-obj-$(CONFIG_SENSORS_HMC5843) += hmc5843_core.o
-obj-$(CONFIG_SENSORS_HMC5843_I2C) += hmc5843_i2c.o
-obj-$(CONFIG_SENSORS_HMC5843_SPI) += hmc5843_spi.o
diff --git a/drivers/staging/iio/magnetometer/hmc5843.h b/drivers/staging/iio/magnetometer/hmc5843.h
deleted file mode 100644
index 06f35d382..000000000
--- a/drivers/staging/iio/magnetometer/hmc5843.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Header file for hmc5843 driver
- *
- * Split from hmc5843.c
- * Copyright (C) Josef Gajdusek <atx@atx.name>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * */
-
-#ifndef HMC5843_CORE_H
-#define HMC5843_CORE_H
-
-#include <linux/regmap.h>
-#include <linux/iio/iio.h>
-
-#define HMC5843_CONFIG_REG_A 0x00
-#define HMC5843_CONFIG_REG_B 0x01
-#define HMC5843_MODE_REG 0x02
-#define HMC5843_DATA_OUT_MSB_REGS 0x03
-#define HMC5843_STATUS_REG 0x09
-#define HMC5843_ID_REG 0x0a
-#define HMC5843_ID_END 0x0c
-
-enum hmc5843_ids {
- HMC5843_ID,
- HMC5883_ID,
- HMC5883L_ID,
- HMC5983_ID,
-};
-
-/**
- * struct hcm5843_data - device specific data
- * @dev: actual device
- * @lock: update and read regmap data
- * @regmap: hardware access register maps
- * @variant: describe chip variants
- * @buffer: 3x 16-bit channels + padding + 64-bit timestamp
- **/
-struct hmc5843_data {
- struct device *dev;
- struct mutex lock;
- struct regmap *regmap;
- const struct hmc5843_chip_info *variant;
- __be16 buffer[8];
-};
-
-int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
- enum hmc5843_ids id, const char *name);
-int hmc5843_common_remove(struct device *dev);
-
-int hmc5843_common_suspend(struct device *dev);
-int hmc5843_common_resume(struct device *dev);
-
-#ifdef CONFIG_PM_SLEEP
-static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops,
- hmc5843_common_suspend,
- hmc5843_common_resume);
-#define HMC5843_PM_OPS (&hmc5843_pm_ops)
-#else
-#define HMC5843_PM_OPS NULL
-#endif
-
-#endif /* HMC5843_CORE_H */
diff --git a/drivers/staging/iio/magnetometer/hmc5843_core.c b/drivers/staging/iio/magnetometer/hmc5843_core.c
deleted file mode 100644
index 394bc141a..000000000
--- a/drivers/staging/iio/magnetometer/hmc5843_core.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Device driver for the the HMC5843 multi-chip module designed
- * for low field magnetic sensing.
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
- * Acknowledgment: Jonathan Cameron <jic23@kernel.org> for valuable inputs.
- * Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
- * Split to multiple files by Josef Gajdusek <atx@atx.name> - 2014
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/regmap.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/triggered_buffer.h>
-#include <linux/delay.h>
-
-#include "hmc5843.h"
-
-/*
- * Range gain settings in (+-)Ga
- * Beware: HMC5843 and HMC5883 have different recommended sensor field
- * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
- */
-#define HMC5843_RANGE_GAIN_OFFSET 0x05
-#define HMC5843_RANGE_GAIN_DEFAULT 0x01
-#define HMC5843_RANGE_GAIN_MASK 0xe0
-
-/* Device status */
-#define HMC5843_DATA_READY 0x01
-#define HMC5843_DATA_OUTPUT_LOCK 0x02
-
-/* Mode register configuration */
-#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00
-#define HMC5843_MODE_CONVERSION_SINGLE 0x01
-#define HMC5843_MODE_IDLE 0x02
-#define HMC5843_MODE_SLEEP 0x03
-#define HMC5843_MODE_MASK 0x03
-
-/*
- * HMC5843: Minimum data output rate
- * HMC5883: Typical data output rate
- */
-#define HMC5843_RATE_OFFSET 0x02
-#define HMC5843_RATE_DEFAULT 0x04
-#define HMC5843_RATE_MASK 0x1c
-
-/* Device measurement configuration */
-#define HMC5843_MEAS_CONF_NORMAL 0x00
-#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01
-#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02
-#define HMC5843_MEAS_CONF_MASK 0x03
-
-/* Scaling factors: 10000000/Gain */
-static const int hmc5843_regval_to_nanoscale[] = {
- 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
-};
-
-static const int hmc5883_regval_to_nanoscale[] = {
- 7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
-};
-
-static const int hmc5883l_regval_to_nanoscale[] = {
- 7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
-};
-
-/*
- * From the datasheet:
- * Value | HMC5843 | HMC5883/HMC5883L
- * | Data output rate (Hz) | Data output rate (Hz)
- * 0 | 0.5 | 0.75
- * 1 | 1 | 1.5
- * 2 | 2 | 3
- * 3 | 5 | 7.5
- * 4 | 10 (default) | 15
- * 5 | 20 | 30
- * 6 | 50 | 75
- * 7 | Not used | Not used
- */
-static const int hmc5843_regval_to_samp_freq[][2] = {
- {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
-};
-
-static const int hmc5883_regval_to_samp_freq[][2] = {
- {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
- {75, 0}
-};
-
-static const int hmc5983_regval_to_samp_freq[][2] = {
- {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
- {75, 0}, {220, 0}
-};
-
-/* Describe chip variants */
-struct hmc5843_chip_info {
- const struct iio_chan_spec *channels;
- const int (*regval_to_samp_freq)[2];
- const int n_regval_to_samp_freq;
- const int *regval_to_nanoscale;
- const int n_regval_to_nanoscale;
-};
-
-/* The lower two bits contain the current conversion mode */
-static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
-{
- int ret;
-
- mutex_lock(&data->lock);
- ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
- HMC5843_MODE_MASK, operating_mode);
- mutex_unlock(&data->lock);
-
- return ret;
-}
-
-static int hmc5843_wait_measurement(struct hmc5843_data *data)
-{
- int tries = 150;
- unsigned int val;
- int ret;
-
- while (tries-- > 0) {
- ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);
- if (ret < 0)
- return ret;
- if (val & HMC5843_DATA_READY)
- break;
- msleep(20);
- }
-
- if (tries < 0) {
- dev_err(data->dev, "data not ready\n");
- return -EIO;
- }
-
- return 0;
-}
-
-/* Return the measurement value from the specified channel */
-static int hmc5843_read_measurement(struct hmc5843_data *data,
- int idx, int *val)
-{
- __be16 values[3];
- int ret;
-
- mutex_lock(&data->lock);
- ret = hmc5843_wait_measurement(data);
- if (ret < 0) {
- mutex_unlock(&data->lock);
- return ret;
- }
- ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
- values, sizeof(values));
- mutex_unlock(&data->lock);
- if (ret < 0)
- return ret;
-
- *val = sign_extend32(be16_to_cpu(values[idx]), 15);
- return IIO_VAL_INT;
-}
-
-/*
- * API for setting the measurement configuration to
- * Normal, Positive bias and Negative bias
- *
- * From the datasheet:
- * 0 - Normal measurement configuration (default): In normal measurement
- * configuration the device follows normal measurement flow. Pins BP
- * and BN are left floating and high impedance.
- *
- * 1 - Positive bias configuration: In positive bias configuration, a
- * positive current is forced across the resistive load on pins BP
- * and BN.
- *
- * 2 - Negative bias configuration. In negative bias configuration, a
- * negative current is forced across the resistive load on pins BP
- * and BN.
- *
- */
-static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
-{
- int ret;
-
- mutex_lock(&data->lock);
- ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
- HMC5843_MEAS_CONF_MASK, meas_conf);
- mutex_unlock(&data->lock);
-
- return ret;
-}
-
-static
-ssize_t hmc5843_show_measurement_configuration(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- unsigned int val;
- int ret;
-
- ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);
- if (ret)
- return ret;
- val &= HMC5843_MEAS_CONF_MASK;
-
- return sprintf(buf, "%d\n", val);
-}
-
-static
-ssize_t hmc5843_set_measurement_configuration(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- unsigned long meas_conf = 0;
- int ret;
-
- ret = kstrtoul(buf, 10, &meas_conf);
- if (ret)
- return ret;
- if (meas_conf >= HMC5843_MEAS_CONF_MASK)
- return -EINVAL;
-
- ret = hmc5843_set_meas_conf(data, meas_conf);
-
- return (ret < 0) ? ret : count;
-}
-
-static IIO_DEVICE_ATTR(meas_conf,
- S_IWUSR | S_IRUGO,
- hmc5843_show_measurement_configuration,
- hmc5843_set_measurement_configuration,
- 0);
-
-static
-ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- size_t len = 0;
- int i;
-
- for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
- len += scnprintf(buf + len, PAGE_SIZE - len,
- "%d.%d ", data->variant->regval_to_samp_freq[i][0],
- data->variant->regval_to_samp_freq[i][1]);
-
- /* replace trailing space by newline */
- buf[len - 1] = '\n';
-
- return len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
-
-static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
-{
- int ret;
-
- mutex_lock(&data->lock);
- ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
- HMC5843_RATE_MASK,
- rate << HMC5843_RATE_OFFSET);
- mutex_unlock(&data->lock);
-
- return ret;
-}
-
-static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
- int val, int val2)
-{
- int i;
-
- for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
- if (val == data->variant->regval_to_samp_freq[i][0] &&
- val2 == data->variant->regval_to_samp_freq[i][1])
- return i;
-
- return -EINVAL;
-}
-
-static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
-{
- int ret;
-
- mutex_lock(&data->lock);
- ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
- HMC5843_RANGE_GAIN_MASK,
- range << HMC5843_RANGE_GAIN_OFFSET);
- mutex_unlock(&data->lock);
-
- return ret;
-}
-
-static ssize_t hmc5843_show_scale_avail(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
-
- size_t len = 0;
- int i;
-
- for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
- len += scnprintf(buf + len, PAGE_SIZE - len,
- "0.%09d ", data->variant->regval_to_nanoscale[i]);
-
- /* replace trailing space by newline */
- buf[len - 1] = '\n';
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
- hmc5843_show_scale_avail, NULL, 0);
-
-static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
-{
- int i;
-
- if (val)
- return -EINVAL;
-
- for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
- if (val2 == data->variant->regval_to_nanoscale[i])
- return i;
-
- return -EINVAL;
-}
-
-static int hmc5843_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
-{
- struct hmc5843_data *data = iio_priv(indio_dev);
- unsigned int rval;
- int ret;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- return hmc5843_read_measurement(data, chan->scan_index, val);
- case IIO_CHAN_INFO_SCALE:
- ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);
- if (ret < 0)
- return ret;
- rval >>= HMC5843_RANGE_GAIN_OFFSET;
- *val = 0;
- *val2 = data->variant->regval_to_nanoscale[rval];
- return IIO_VAL_INT_PLUS_NANO;
- case IIO_CHAN_INFO_SAMP_FREQ:
- ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);
- if (ret < 0)
- return ret;
- rval >>= HMC5843_RATE_OFFSET;
- *val = data->variant->regval_to_samp_freq[rval][0];
- *val2 = data->variant->regval_to_samp_freq[rval][1];
- return IIO_VAL_INT_PLUS_MICRO;
- }
- return -EINVAL;
-}
-
-static int hmc5843_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val, int val2, long mask)
-{
- struct hmc5843_data *data = iio_priv(indio_dev);
- int rate, range;
-
- switch (mask) {
- case IIO_CHAN_INFO_SAMP_FREQ:
- rate = hmc5843_get_samp_freq_index(data, val, val2);
- if (rate < 0)
- return -EINVAL;
-
- return hmc5843_set_samp_freq(data, rate);
- case IIO_CHAN_INFO_SCALE:
- range = hmc5843_get_scale_index(data, val, val2);
- if (range < 0)
- return -EINVAL;
-
- return hmc5843_set_range_gain(data, range);
- default:
- return -EINVAL;
- }
-}
-
-static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- long mask)
-{
- switch (mask) {
- case IIO_CHAN_INFO_SAMP_FREQ:
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_CHAN_INFO_SCALE:
- return IIO_VAL_INT_PLUS_NANO;
- default:
- return -EINVAL;
- }
-}
-
-static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct hmc5843_data *data = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&data->lock);
- ret = hmc5843_wait_measurement(data);
- if (ret < 0) {
- mutex_unlock(&data->lock);
- goto done;
- }
-
- ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
- data->buffer, 3 * sizeof(__be16));
-
- mutex_unlock(&data->lock);
- if (ret < 0)
- goto done;
-
- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
- iio_get_time_ns());
-
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-#define HMC5843_CHANNEL(axis, idx) \
- { \
- .type = IIO_MAGN, \
- .modified = 1, \
- .channel2 = IIO_MOD_##axis, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_SAMP_FREQ), \
- .scan_index = idx, \
- .scan_type = { \
- .sign = 's', \
- .realbits = 16, \
- .storagebits = 16, \
- .endianness = IIO_BE, \
- }, \
- }
-
-static const struct iio_chan_spec hmc5843_channels[] = {
- HMC5843_CHANNEL(X, 0),
- HMC5843_CHANNEL(Y, 1),
- HMC5843_CHANNEL(Z, 2),
- IIO_CHAN_SOFT_TIMESTAMP(3),
-};
-
-/* Beware: Y and Z are exchanged on HMC5883 and 5983 */
-static const struct iio_chan_spec hmc5883_channels[] = {
- HMC5843_CHANNEL(X, 0),
- HMC5843_CHANNEL(Z, 1),
- HMC5843_CHANNEL(Y, 2),
- IIO_CHAN_SOFT_TIMESTAMP(3),
-};
-
-static struct attribute *hmc5843_attributes[] = {
- &iio_dev_attr_meas_conf.dev_attr.attr,
- &iio_dev_attr_scale_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group hmc5843_group = {
- .attrs = hmc5843_attributes,
-};
-
-static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
- [HMC5843_ID] = {
- .channels = hmc5843_channels,
- .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
- .n_regval_to_samp_freq =
- ARRAY_SIZE(hmc5843_regval_to_samp_freq),
- .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
- .n_regval_to_nanoscale =
- ARRAY_SIZE(hmc5843_regval_to_nanoscale),
- },
- [HMC5883_ID] = {
- .channels = hmc5883_channels,
- .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
- .n_regval_to_samp_freq =
- ARRAY_SIZE(hmc5883_regval_to_samp_freq),
- .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
- .n_regval_to_nanoscale =
- ARRAY_SIZE(hmc5883_regval_to_nanoscale),
- },
- [HMC5883L_ID] = {
- .channels = hmc5883_channels,
- .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
- .n_regval_to_samp_freq =
- ARRAY_SIZE(hmc5883_regval_to_samp_freq),
- .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
- .n_regval_to_nanoscale =
- ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
- },
- [HMC5983_ID] = {
- .channels = hmc5883_channels,
- .regval_to_samp_freq = hmc5983_regval_to_samp_freq,
- .n_regval_to_samp_freq =
- ARRAY_SIZE(hmc5983_regval_to_samp_freq),
- .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
- .n_regval_to_nanoscale =
- ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
- }
-};
-
-static int hmc5843_init(struct hmc5843_data *data)
-{
- int ret;
- u8 id[3];
-
- ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,
- id, ARRAY_SIZE(id));
- if (ret < 0)
- return ret;
- if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
- dev_err(data->dev, "no HMC5843/5883/5883L/5983 sensor\n");
- return -ENODEV;
- }
-
- ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
- if (ret < 0)
- return ret;
- ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
- if (ret < 0)
- return ret;
- ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
- if (ret < 0)
- return ret;
- return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
-}
-
-static const struct iio_info hmc5843_info = {
- .attrs = &hmc5843_group,
- .read_raw = &hmc5843_read_raw,
- .write_raw = &hmc5843_write_raw,
- .write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
- .driver_module = THIS_MODULE,
-};
-
-static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
-
-int hmc5843_common_suspend(struct device *dev)
-{
- return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
- HMC5843_MODE_CONVERSION_CONTINUOUS);
-}
-EXPORT_SYMBOL(hmc5843_common_suspend);
-
-int hmc5843_common_resume(struct device *dev)
-{
- return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
- HMC5843_MODE_SLEEP);
-}
-EXPORT_SYMBOL(hmc5843_common_resume);
-
-int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
- enum hmc5843_ids id, const char *name)
-{
- struct hmc5843_data *data;
- struct iio_dev *indio_dev;
- int ret;
-
- indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
- if (!indio_dev)
- return -ENOMEM;
-
- dev_set_drvdata(dev, indio_dev);
-
- /* default settings at probe */
- data = iio_priv(indio_dev);
- data->dev = dev;
- data->regmap = regmap;
- data->variant = &hmc5843_chip_info_tbl[id];
- mutex_init(&data->lock);
-
- indio_dev->dev.parent = dev;
- indio_dev->name = name;
- indio_dev->info = &hmc5843_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = data->variant->channels;
- indio_dev->num_channels = 4;
- indio_dev->available_scan_masks = hmc5843_scan_masks;
-
- ret = hmc5843_init(data);
- if (ret < 0)
- return ret;
-
- ret = iio_triggered_buffer_setup(indio_dev, NULL,
- hmc5843_trigger_handler, NULL);
- if (ret < 0)
- goto buffer_setup_err;
-
- ret = iio_device_register(indio_dev);
- if (ret < 0)
- goto buffer_cleanup;
-
- return 0;
-
-buffer_cleanup:
- iio_triggered_buffer_cleanup(indio_dev);
-buffer_setup_err:
- hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
- return ret;
-}
-EXPORT_SYMBOL(hmc5843_common_probe);
-
-int hmc5843_common_remove(struct device *dev)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
- iio_device_unregister(indio_dev);
- iio_triggered_buffer_cleanup(indio_dev);
-
- /* sleep mode to save power */
- hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
-
- return 0;
-}
-EXPORT_SYMBOL(hmc5843_common_remove);
-
-MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
-MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843_i2c.c b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
deleted file mode 100644
index 3e06ceb32..000000000
--- a/drivers/staging/iio/magnetometer/hmc5843_i2c.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * i2c driver for hmc5843/5843/5883/5883l/5983
- *
- * Split from hmc5843.c
- * Copyright (C) Josef Gajdusek <atx@atx.name>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "hmc5843.h"
-
-static const struct regmap_range hmc5843_readable_ranges[] = {
- regmap_reg_range(0, HMC5843_ID_END),
-};
-
-static const struct regmap_access_table hmc5843_readable_table = {
- .yes_ranges = hmc5843_readable_ranges,
- .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
-};
-
-static const struct regmap_range hmc5843_writable_ranges[] = {
- regmap_reg_range(0, HMC5843_MODE_REG),
-};
-
-static const struct regmap_access_table hmc5843_writable_table = {
- .yes_ranges = hmc5843_writable_ranges,
- .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
-};
-
-static const struct regmap_range hmc5843_volatile_ranges[] = {
- regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
-};
-
-static const struct regmap_access_table hmc5843_volatile_table = {
- .yes_ranges = hmc5843_volatile_ranges,
- .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
-};
-
-static const struct regmap_config hmc5843_i2c_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .rd_table = &hmc5843_readable_table,
- .wr_table = &hmc5843_writable_table,
- .volatile_table = &hmc5843_volatile_table,
-
- .cache_type = REGCACHE_RBTREE,
-};
-
-static int hmc5843_i2c_probe(struct i2c_client *cli,
- const struct i2c_device_id *id)
-{
- return hmc5843_common_probe(&cli->dev,
- devm_regmap_init_i2c(cli, &hmc5843_i2c_regmap_config),
- id->driver_data, id->name);
-}
-
-static int hmc5843_i2c_remove(struct i2c_client *client)
-{
- return hmc5843_common_remove(&client->dev);
-}
-
-static const struct i2c_device_id hmc5843_id[] = {
- { "hmc5843", HMC5843_ID },
- { "hmc5883", HMC5883_ID },
- { "hmc5883l", HMC5883L_ID },
- { "hmc5983", HMC5983_ID },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, hmc5843_id);
-
-static const struct of_device_id hmc5843_of_match[] = {
- { .compatible = "honeywell,hmc5843", .data = (void *)HMC5843_ID },
- { .compatible = "honeywell,hmc5883", .data = (void *)HMC5883_ID },
- { .compatible = "honeywell,hmc5883l", .data = (void *)HMC5883L_ID },
- { .compatible = "honeywell,hmc5983", .data = (void *)HMC5983_ID },
- {}
-};
-MODULE_DEVICE_TABLE(of, hmc5843_of_match);
-
-static struct i2c_driver hmc5843_driver = {
- .driver = {
- .name = "hmc5843",
- .pm = HMC5843_PM_OPS,
- .of_match_table = hmc5843_of_match,
- },
- .id_table = hmc5843_id,
- .probe = hmc5843_i2c_probe,
- .remove = hmc5843_i2c_remove,
-};
-module_i2c_driver(hmc5843_driver);
-
-MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
-MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 i2c driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843_spi.c b/drivers/staging/iio/magnetometer/hmc5843_spi.c
deleted file mode 100644
index 8be198058..000000000
--- a/drivers/staging/iio/magnetometer/hmc5843_spi.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SPI driver for hmc5983
- *
- * Copyright (C) Josef Gajdusek <atx@atx.name>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * */
-
-#include <linux/module.h>
-#include <linux/spi/spi.h>
-#include <linux/iio/iio.h>
-
-#include "hmc5843.h"
-
-static const struct regmap_range hmc5843_readable_ranges[] = {
- regmap_reg_range(0, HMC5843_ID_END),
-};
-
-static const struct regmap_access_table hmc5843_readable_table = {
- .yes_ranges = hmc5843_readable_ranges,
- .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
-};
-
-static const struct regmap_range hmc5843_writable_ranges[] = {
- regmap_reg_range(0, HMC5843_MODE_REG),
-};
-
-static const struct regmap_access_table hmc5843_writable_table = {
- .yes_ranges = hmc5843_writable_ranges,
- .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
-};
-
-static const struct regmap_range hmc5843_volatile_ranges[] = {
- regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
-};
-
-static const struct regmap_access_table hmc5843_volatile_table = {
- .yes_ranges = hmc5843_volatile_ranges,
- .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
-};
-
-static const struct regmap_config hmc5843_spi_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-
- .rd_table = &hmc5843_readable_table,
- .wr_table = &hmc5843_writable_table,
- .volatile_table = &hmc5843_volatile_table,
-
- /* Autoincrement address pointer */
- .read_flag_mask = 0xc0,
-
- .cache_type = REGCACHE_RBTREE,
-};
-
-static int hmc5843_spi_probe(struct spi_device *spi)
-{
- int ret;
- const struct spi_device_id *id = spi_get_device_id(spi);
-
- spi->mode = SPI_MODE_3;
- spi->max_speed_hz = 8000000;
- spi->bits_per_word = 8;
- ret = spi_setup(spi);
- if (ret)
- return ret;
-
- return hmc5843_common_probe(&spi->dev,
- devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config),
- id->driver_data, id->name);
-}
-
-static int hmc5843_spi_remove(struct spi_device *spi)
-{
- return hmc5843_common_remove(&spi->dev);
-}
-
-static const struct spi_device_id hmc5843_id[] = {
- { "hmc5983", HMC5983_ID },
- { }
-};
-MODULE_DEVICE_TABLE(spi, hmc5843_id);
-
-static struct spi_driver hmc5843_driver = {
- .driver = {
- .name = "hmc5843",
- .pm = HMC5843_PM_OPS,
- },
- .id_table = hmc5843_id,
- .probe = hmc5843_spi_probe,
- .remove = hmc5843_spi_remove,
-};
-
-module_spi_driver(hmc5843_driver);
-
-MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
-MODULE_DESCRIPTION("HMC5983 SPI driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 1e950685e..f4188e17d 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -347,7 +347,7 @@ static int ade7754_set_irq(struct device *dev, bool enable)
ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen);
if (ret)
- goto error_ret;
+ return ret;
if (enable)
irqen |= BIT(14); /* Enables an interrupt when a data is
@@ -356,10 +356,7 @@ static int ade7754_set_irq(struct device *dev, bool enable)
irqen &= ~BIT(14);
ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
- if (ret)
- goto error_ret;
-error_ret:
return ret;
}
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 0db23e4d1..40f5afaa9 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -423,7 +423,7 @@ int ade7758_set_irq(struct device *dev, bool enable)
ret = ade7758_spi_read_reg_24(dev, ADE7758_MASK, &irqen);
if (ret)
- goto error_ret;
+ return ret;
if (enable)
irqen |= BIT(16); /* Enables an interrupt when a data is
@@ -432,10 +432,7 @@ int ade7758_set_irq(struct device *dev, bool enable)
irqen &= ~BIT(16);
ret = ade7758_spi_write_reg_24(dev, ADE7758_MASK, irqen);
- if (ret)
- goto error_ret;
-error_ret:
return ret;
}
diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c
index 07cfe28b2..8106f8cce 100644
--- a/drivers/staging/iio/meter/ade7854-i2c.c
+++ b/drivers/staging/iio/meter/ade7854-i2c.c
@@ -227,11 +227,6 @@ static int ade7854_i2c_probe(struct i2c_client *client,
return ade7854_probe(indio_dev, &client->dev);
}
-static int ade7854_i2c_remove(struct i2c_client *client)
-{
- return ade7854_remove(i2c_get_clientdata(client));
-}
-
static const struct i2c_device_id ade7854_id[] = {
{ "ade7854", 0 },
{ "ade7858", 0 },
@@ -246,7 +241,6 @@ static struct i2c_driver ade7854_i2c_driver = {
.name = "ade7854",
},
.probe = ade7854_i2c_probe,
- .remove = ade7854_i2c_remove,
.id_table = ade7854_id,
};
module_i2c_driver(ade7854_i2c_driver);
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index 2413052c5..63e200ffd 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -296,12 +296,6 @@ static int ade7854_spi_probe(struct spi_device *spi)
return ade7854_probe(indio_dev, &spi->dev);
}
-static int ade7854_spi_remove(struct spi_device *spi)
-{
- ade7854_remove(spi_get_drvdata(spi));
-
- return 0;
-}
static const struct spi_device_id ade7854_id[] = {
{ "ade7854", 0 },
{ "ade7858", 0 },
@@ -316,7 +310,6 @@ static struct spi_driver ade7854_driver = {
.name = "ade7854",
},
.probe = ade7854_spi_probe,
- .remove = ade7854_spi_remove,
.id_table = ade7854_id,
};
module_spi_driver(ade7854_driver);
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index a83883596..9e439af71 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -417,7 +417,7 @@ static int ade7854_set_irq(struct device *dev, bool enable)
ret = st->read_reg_32(dev, ADE7854_MASK0, &irqen);
if (ret)
- goto error_ret;
+ return ret;
if (enable)
irqen |= BIT(17); /* 1: interrupt enabled when all periodical
@@ -426,10 +426,7 @@ static int ade7854_set_irq(struct device *dev, bool enable)
irqen &= ~BIT(17);
ret = st->write_reg_32(dev, ADE7854_MASK0, irqen);
- if (ret)
- goto error_ret;
-error_ret:
return ret;
}
@@ -548,31 +545,15 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
indio_dev->info = &ade7854_info;
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(dev, indio_dev);
if (ret)
return ret;
/* Get the device into a sane initial state */
- ret = ade7854_initial_setup(indio_dev);
- if (ret)
- goto error_unreg_dev;
-
- return 0;
-
-error_unreg_dev:
- iio_device_unregister(indio_dev);
- return ret;
+ return ade7854_initial_setup(indio_dev);
}
EXPORT_SYMBOL(ade7854_probe);
-int ade7854_remove(struct iio_dev *indio_dev)
-{
- iio_device_unregister(indio_dev);
-
- return 0;
-}
-EXPORT_SYMBOL(ade7854_remove);
-
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Energy Meter");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c
index 595e711d3..82b2d88ca 100644
--- a/drivers/staging/iio/resolver/ad2s1200.c
+++ b/drivers/staging/iio/resolver/ad2s1200.c
@@ -31,7 +31,7 @@
/* input clock on serial interface */
#define AD2S1200_HZ 8192000
/* clock period in nano second */
-#define AD2S1200_TSCLK (1000000000/AD2S1200_HZ)
+#define AD2S1200_TSCLK (1000000000 / AD2S1200_HZ)
struct ad2s1200_state {
struct mutex lock;
@@ -42,10 +42,10 @@ struct ad2s1200_state {
};
static int ad2s1200_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long m)
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
{
int ret = 0;
s16 vel;
@@ -113,7 +113,7 @@ static int ad2s1200_probe(struct spi_device *spi)
DRV_NAME);
if (ret) {
dev_err(&spi->dev, "request gpio pin %d failed\n",
- pins[pn]);
+ pins[pn]);
return ret;
}
}
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index d97aa2827..6b992634f 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -67,7 +67,7 @@
/* default input clock on serial interface */
#define AD2S1210_DEF_CLKIN 8192000
/* clock period in nano second */
-#define AD2S1210_DEF_TCK (1000000000/AD2S1210_DEF_CLKIN)
+#define AD2S1210_DEF_TCK (1000000000 / AD2S1210_DEF_CLKIN)
#define AD2S1210_DEF_EXCIT 10000
enum ad2s1210_mode {
@@ -98,6 +98,7 @@ static const int ad2s1210_mode_vals[4][2] = {
[MOD_VEL] = { 0, 1 },
[MOD_CONFIG] = { 1, 0 },
};
+
static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
struct ad2s1210_state *st)
{
@@ -123,7 +124,7 @@ static int ad2s1210_config_write(struct ad2s1210_state *st, u8 data)
/* read value from one of the registers */
static int ad2s1210_config_read(struct ad2s1210_state *st,
- unsigned char address)
+ unsigned char address)
{
struct spi_transfer xfer = {
.len = 2,
@@ -176,9 +177,9 @@ static const int ad2s1210_res_pins[4][2] = {
static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st)
{
gpio_set_value(st->pdata->res[0],
- ad2s1210_res_pins[(st->resolution - 10)/2][0]);
+ ad2s1210_res_pins[(st->resolution - 10) / 2][0]);
gpio_set_value(st->pdata->res[1],
- ad2s1210_res_pins[(st->resolution - 10)/2][1]);
+ ad2s1210_res_pins[(st->resolution - 10) / 2][1]);
}
static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
@@ -282,8 +283,8 @@ static ssize_t ad2s1210_show_control(struct device *dev,
}
static ssize_t ad2s1210_store_control(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
unsigned char udata;
@@ -318,9 +319,9 @@ static ssize_t ad2s1210_store_control(struct device *dev,
data = ad2s1210_read_resolution_pin(st);
if (data != st->resolution)
dev_warn(dev, "ad2s1210: resolution settings not match\n");
- } else
+ } else {
ad2s1210_set_resolution_pin(st);
-
+ }
ret = len;
st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS);
@@ -330,7 +331,8 @@ error_ret:
}
static ssize_t ad2s1210_show_resolution(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
@@ -338,8 +340,8 @@ static ssize_t ad2s1210_show_resolution(struct device *dev,
}
static ssize_t ad2s1210_store_resolution(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
unsigned char data;
@@ -379,8 +381,9 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
data = ad2s1210_read_resolution_pin(st);
if (data != st->resolution)
dev_warn(dev, "ad2s1210: resolution settings not match\n");
- } else
+ } else {
ad2s1210_set_resolution_pin(st);
+ }
ret = len;
error_ret:
mutex_unlock(&st->lock);
@@ -389,7 +392,7 @@ error_ret:
/* read the fault register since last sample */
static ssize_t ad2s1210_show_fault(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
int ret;
@@ -441,7 +444,8 @@ static ssize_t ad2s1210_show_reg(struct device *dev,
}
static ssize_t ad2s1210_store_reg(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
+ struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
unsigned char data;
@@ -497,7 +501,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
switch (chan->type) {
case IIO_ANGL:
- pos = be16_to_cpup((__be16 *) st->rx);
+ pos = be16_to_cpup((__be16 *)st->rx);
if (st->hysteresis)
pos >>= 16 - st->resolution;
*val = pos;
@@ -505,7 +509,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
break;
case IIO_ANGL_VEL:
negative = st->rx[0] & 0x80;
- vel = be16_to_cpup((__be16 *) st->rx);
+ vel = be16_to_cpup((__be16 *)st->rx);
vel >>= 16 - st->resolution;
if (vel & 0x8000) {
negative = (0xffff >> st->resolution) << st->resolution;
@@ -560,7 +564,6 @@ static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR,
ad2s1210_show_reg, ad2s1210_store_reg,
AD2S1210_REG_LOT_LOW_THRD);
-
static const struct iio_chan_spec ad2s1210_channels[] = {
{
.type = IIO_ANGL,
@@ -672,7 +675,7 @@ static int ad2s1210_probe(struct spi_device *spi)
struct ad2s1210_state *st;
int ret;
- if (spi->dev.platform_data == NULL)
+ if (!spi->dev.platform_data)
return -EINVAL;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig
index 710a2f3e7..0b01d24ce 100644
--- a/drivers/staging/iio/trigger/Kconfig
+++ b/drivers/staging/iio/trigger/Kconfig
@@ -5,16 +5,6 @@ comment "Triggers - standalone"
if IIO_TRIGGER
-config IIO_PERIODIC_RTC_TRIGGER
- tristate "Periodic RTC triggers"
- depends on RTC_CLASS
- help
- Provides support for using periodic capable real time
- clocks as IIO triggers.
-
- To compile this driver as a module, choose M here: the
- module will be called iio-trig-periodic-rtc.
-
config IIO_BFIN_TMR_TRIGGER
tristate "Blackfin TIMER trigger"
depends on BLACKFIN
diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile
index 238481b78..1300a2136 100644
--- a/drivers/staging/iio/trigger/Makefile
+++ b/drivers/staging/iio/trigger/Makefile
@@ -2,5 +2,4 @@
# Makefile for triggers not associated with iio-devices
#
-obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o
obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
deleted file mode 100644
index 00d139331..000000000
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/* The industrial I/O periodic RTC trigger driver
- *
- * Copyright (c) 2008 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This is a heavily rewritten version of the periodic timer system in
- * earlier version of industrialio. It supplies the same functionality
- * but via a trigger rather than a specific periodic timer system.
- */
-
-#include <linux/platform_device.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/rtc.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-
-static LIST_HEAD(iio_prtc_trigger_list);
-static DEFINE_MUTEX(iio_prtc_trigger_list_lock);
-
-struct iio_prtc_trigger_info {
- struct rtc_device *rtc;
- unsigned int frequency;
- struct rtc_task task;
- bool state;
-};
-
-static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state)
-{
- struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
- int ret;
-
- if (trig_info->frequency == 0 && state)
- return -EINVAL;
- dev_dbg(&trig_info->rtc->dev, "trigger frequency is %u\n",
- trig_info->frequency);
- ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
- if (!ret)
- trig_info->state = state;
-
- return ret;
-}
-
-static ssize_t iio_trig_periodic_read_freq(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_trigger *trig = to_iio_trigger(dev);
- struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
-
- return sprintf(buf, "%u\n", trig_info->frequency);
-}
-
-static ssize_t iio_trig_periodic_write_freq(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_trigger *trig = to_iio_trigger(dev);
- struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
- unsigned int val;
- int ret;
-
- ret = kstrtouint(buf, 10, &val);
- if (ret)
- goto error_ret;
-
- if (val > 0) {
- ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
- if (ret == 0 && trig_info->state && trig_info->frequency == 0)
- ret = rtc_irq_set_state(trig_info->rtc,
- &trig_info->task, 1);
- } else {
- ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0);
- }
- if (ret)
- goto error_ret;
-
- trig_info->frequency = val;
-
- return len;
-
-error_ret:
- return ret;
-}
-
-static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR,
- iio_trig_periodic_read_freq,
- iio_trig_periodic_write_freq);
-
-static struct attribute *iio_trig_prtc_attrs[] = {
- &dev_attr_frequency.attr,
- NULL,
-};
-
-static const struct attribute_group iio_trig_prtc_attr_group = {
- .attrs = iio_trig_prtc_attrs,
-};
-
-static const struct attribute_group *iio_trig_prtc_attr_groups[] = {
- &iio_trig_prtc_attr_group,
- NULL
-};
-
-static void iio_prtc_trigger_poll(void *private_data)
-{
- iio_trigger_poll(private_data);
-}
-
-static const struct iio_trigger_ops iio_prtc_trigger_ops = {
- .owner = THIS_MODULE,
- .set_trigger_state = &iio_trig_periodic_rtc_set_state,
-};
-
-static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
-{
- char **pdata = dev->dev.platform_data;
- struct iio_prtc_trigger_info *trig_info;
- struct iio_trigger *trig, *trig2;
-
- int i, ret;
-
- for (i = 0;; i++) {
- if (!pdata[i])
- break;
- trig = iio_trigger_alloc("periodic%s", pdata[i]);
- if (!trig) {
- ret = -ENOMEM;
- goto error_free_completed_registrations;
- }
- list_add(&trig->alloc_list, &iio_prtc_trigger_list);
-
- trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
- if (!trig_info) {
- ret = -ENOMEM;
- goto error_put_trigger_and_remove_from_list;
- }
- iio_trigger_set_drvdata(trig, trig_info);
- trig->ops = &iio_prtc_trigger_ops;
- /* RTC access */
- trig_info->rtc = rtc_class_open(pdata[i]);
- if (!trig_info->rtc) {
- ret = -EINVAL;
- goto error_free_trig_info;
- }
- trig_info->task.func = iio_prtc_trigger_poll;
- trig_info->task.private_data = trig;
- ret = rtc_irq_register(trig_info->rtc, &trig_info->task);
- if (ret)
- goto error_close_rtc;
- trig->dev.groups = iio_trig_prtc_attr_groups;
- ret = iio_trigger_register(trig);
- if (ret)
- goto error_unregister_rtc_irq;
- }
- return 0;
-error_unregister_rtc_irq:
- rtc_irq_unregister(trig_info->rtc, &trig_info->task);
-error_close_rtc:
- rtc_class_close(trig_info->rtc);
-error_free_trig_info:
- kfree(trig_info);
-error_put_trigger_and_remove_from_list:
- list_del(&trig->alloc_list);
- iio_trigger_put(trig);
-error_free_completed_registrations:
- list_for_each_entry_safe(trig,
- trig2,
- &iio_prtc_trigger_list,
- alloc_list) {
- trig_info = iio_trigger_get_drvdata(trig);
- rtc_irq_unregister(trig_info->rtc, &trig_info->task);
- rtc_class_close(trig_info->rtc);
- kfree(trig_info);
- iio_trigger_unregister(trig);
- }
- return ret;
-}
-
-static int iio_trig_periodic_rtc_remove(struct platform_device *dev)
-{
- struct iio_trigger *trig, *trig2;
- struct iio_prtc_trigger_info *trig_info;
-
- mutex_lock(&iio_prtc_trigger_list_lock);
- list_for_each_entry_safe(trig,
- trig2,
- &iio_prtc_trigger_list,
- alloc_list) {
- trig_info = iio_trigger_get_drvdata(trig);
- rtc_irq_unregister(trig_info->rtc, &trig_info->task);
- rtc_class_close(trig_info->rtc);
- kfree(trig_info);
- iio_trigger_unregister(trig);
- }
- mutex_unlock(&iio_prtc_trigger_list_lock);
- return 0;
-}
-
-static struct platform_driver iio_trig_periodic_rtc_driver = {
- .probe = iio_trig_periodic_rtc_probe,
- .remove = iio_trig_periodic_rtc_remove,
- .driver = {
- .name = "iio_prtc_trigger",
- },
-};
-
-module_platform_driver(iio_trig_periodic_rtc_driver);
-
-MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
-MODULE_LICENSE("GPL v2");