First round of new IIO drivers, features and cleanups for the 3.12 cycle.

There has been a lot of good work going into IIO recently, some of which
 missed this pull request purely because I haven't caught up with all my
 emails.
 
 Core changes
 
 1) Introduction of devm_iio_device_alloc/free and conversions of lots of
    drivers (37 + patches so far mostly from Sachin)
 2) A Kconfig option to enabled some debug logging subsystem wide.
 
 New drivers
 
 1) Nuvoton NAU7802 adc driver
 2) Avago APDS9300 ambient light sensor driver.
 
 Staging graduations
 1) ADIS16260 gyroscope (after a lot fo cleaning up from Lars-Peter)
 
 New driver features
 
 1) ST-sensors gain control of which pin is used for dataready.
 2) mcp4725 gains eeprom saving (a later fix deals with a wrong return type
    bug in that patch)
 3) A number of drivers have gained module alias' to aid autoloading.
 
 Cleanups and minor bug fixes.
 
 1) A number of typos in Kconfig comments
 2) Drop remaining mentions of ring buffers (now just buffers)
 3) Overrestrictive i2c function checking in the invensense mpu6050 driver
 4) Some help text clarifications.
 5) store_eeprom is now used in several drivers so move to generic abi docs.
 6) Update dac power down options.
 7) Add some error handlign to mxs-lradc on stmp_reset_block call.
 8) Lars fixed the alphabetical order in various files and added comments
    to try and prevent them getting messed up again.
 9) Dropped some remaining 'reset' attributes for drivers.  We have never
    seen a reason why these should be available.  Finally the macro
    used to define many of these has gone.
 10) lps331ap gets an easier to check temperature scale implementation.
 11) Various cleanups for the hmc5843 from Peter with a view to getting
     it ready for a staging graduation.
 
 Quite a few other little typo fixes etc.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.20 (GNU/Linux)
 
 iQIcBAABAgAGBQJR/ofcAAoJEFSFNJnE9BaIN00QALxIW/4uP3/Ebv7jDJtOA1Ow
 zzmsEfvDelAlqV+LZM97l7vHPRDrZY7PgDmOtDQZPsRdawnXH1rUopj0oxVWLiYv
 NGDagCi2D5kPbR67/79n0ArNBvTo15EluxrcxDvMDTLX2QRUCrV0a67TFemT/Ooy
 rvYEwLau/nUrxdwwGayxx81Pxy2Xke6wwvCfa/+pZqZv8q8GkKGDbhXfZdsW968t
 0zgOSh+MyxfvEfeRam+kwZ806AAbz34c0b9aVSGCzTS8ZQ8kuxMBFhNgICVWEzoK
 zS/sx0jbIsoTPUF+lwoluSYx15fih1t5sktYD4rAOo2HBVyYNM9GgOjbazU/Mskb
 2mNkAkWboxvfccuBaIB4wRSTa/e33d/qTczs62e7MEcUCWnHmfzsdUJOiZwJJLSk
 WhxoVaom16ze+EEPqQ8rWRRqI4nn4bP0bBSuZ+uptHA45VUokyHj8eIVkuZa34Lm
 HQPiiF647kFsBnWOEZVxGsku0BSVjZWBpOyr95OOOtJcNMvxpBfDF21mtWpZtC4u
 UCMnDBsHmyK/z8VXTtUXQ1PePrc8YKZajMJypcUEq9dcd5ymlvUf2gVsnoGLn4Zb
 vhpov//UR+OVRoZOOfbWhnRhUS3zx7+b9+qNhN/9UYN5lxx8zy9YyRJEWOcBbaQu
 k+KzLiEZrtAVeZ7+WT05
 =gGdq
 -----END PGP SIGNATURE-----

Merge tag 'iio-for-3.12a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

First round of new IIO drivers, features and cleanups for the 3.12 cycle.

There has been a lot of good work going into IIO recently, some of which
missed this pull request purely because I haven't caught up with all my
emails.

Core changes

1) Introduction of devm_iio_device_alloc/free and conversions of lots of
   drivers (37 + patches so far mostly from Sachin)
2) A Kconfig option to enabled some debug logging subsystem wide.

New drivers

1) Nuvoton NAU7802 adc driver
2) Avago APDS9300 ambient light sensor driver.

Staging graduations
1) ADIS16260 gyroscope (after a lot fo cleaning up from Lars-Peter)

New driver features

1) ST-sensors gain control of which pin is used for dataready.
2) mcp4725 gains eeprom saving (a later fix deals with a wrong return type
   bug in that patch)
3) A number of drivers have gained module alias' to aid autoloading.

Cleanups and minor bug fixes.

1) A number of typos in Kconfig comments
2) Drop remaining mentions of ring buffers (now just buffers)
3) Overrestrictive i2c function checking in the invensense mpu6050 driver
4) Some help text clarifications.
5) store_eeprom is now used in several drivers so move to generic abi docs.
6) Update dac power down options.
7) Add some error handlign to mxs-lradc on stmp_reset_block call.
8) Lars fixed the alphabetical order in various files and added comments
   to try and prevent them getting messed up again.
9) Dropped some remaining 'reset' attributes for drivers.  We have never
   seen a reason why these should be available.  Finally the macro
   used to define many of these has gone.
10) lps331ap gets an easier to check temperature scale implementation.
11) Various cleanups for the hmc5843 from Peter with a view to getting
    it ready for a staging graduation.

Quite a few other little typo fixes etc.
This commit is contained in:
Greg Kroah-Hartman 2013-08-05 14:14:26 +08:00
commit a083c4f215
107 changed files with 2128 additions and 1146 deletions

View File

@ -351,6 +351,7 @@ Description:
6kohm_to_gnd: connected to ground via a 6kOhm resistor,
20kohm_to_gnd: connected to ground via a 20kOhm resistor,
100kohm_to_gnd: connected to ground via an 100kOhm resistor,
500kohm_to_gnd: connected to ground via a 500kOhm resistor,
three_state: left floating.
For a list of available output power down options read
outX_powerdown_mode_available. If Y is not present the
@ -792,3 +793,11 @@ Contact: linux-iio@vger.kernel.org
Description:
This attribute is used to read the amount of quadrature error
present in the device at a given time.
What: /sys/bus/iio/devices/iio:deviceX/store_eeprom
KernelVersion: 3.4.0
Contact: linux-iio@vger.kernel.org
Description:
Writing '1' stores the current device configuration into
on-chip EEPROM. After power-up or chip reset the device will
automatically load the saved configuration.

View File

@ -18,14 +18,6 @@ Description:
Reading returns either '1' or '0'. '1' means that the
pllY is locked.
What: /sys/bus/iio/devices/iio:deviceX/store_eeprom
KernelVersion: 3.4.0
Contact: linux-iio@vger.kernel.org
Description:
Writing '1' stores the current device configuration into
on-chip EEPROM. After power-up or chip reset the device will
automatically load the saved configuration.
What: /sys/bus/iio/devices/iio:deviceX/sync_dividers
KernelVersion: 3.4.0
Contact: linux-iio@vger.kernel.org

View File

@ -18,4 +18,4 @@ Description:
adjust the reference frequency accordingly.
The value written has no effect until out_altvoltageY_frequency
is updated. Consider to use out_altvoltageY_powerdown to power
down the PLL and it's RFOut buffers during REFin changes.
down the PLL and its RFOut buffers during REFin changes.

View File

@ -0,0 +1,18 @@
* Nuvoton NAU7802 Analog to Digital Converter (ADC)
Required properties:
- compatible: Should be "nuvoton,nau7802"
- reg: Should contain the ADC I2C address
Optional properties:
- nuvoton,vldo: Internal reference voltage in millivolts to be
configured valid values are between 2400 mV and 4500 mV.
- interrupts: IRQ line for the ADC. If not used the driver will use
polling.
Example:
adc2: nau7802@2a {
compatible = "nuvoton,nau7802";
reg = <0x2a>;
nuvoton,vldo = <3000>;
};

View File

@ -0,0 +1,22 @@
* Avago APDS9300 ambient light sensor
http://www.avagotech.com/docs/AV02-1077EN
Required properties:
- compatible : should be "avago,apds9300"
- reg : the I2C address of the sensor
Optional properties:
- interrupt-parent : should be the phandle for the interrupt controller
- interrupts : interrupt mapping for GPIO IRQ
Example:
apds9300@39 {
compatible = "avago,apds9300";
reg = <0x39>;
interrupt-parent = <&gpio2>;
interrupts = <29 8>;
};

View File

@ -11,6 +11,7 @@ amcc Applied Micro Circuits Corporation (APM, formally AMCC)
apm Applied Micro Circuits Corporation (APM)
arm ARM Ltd.
atmel Atmel Corporation
avago Avago Technologies
bosch Bosch Sensortec GmbH
brcm Broadcom Corporation
cavium Cavium, Inc.

View File

@ -237,6 +237,10 @@ MEM
devm_kzalloc()
devm_kfree()
IIO
devm_iio_device_alloc()
devm_iio_device_free()
IO region
devm_request_region()
devm_request_mem_region()

View File

@ -12,6 +12,13 @@ menuconfig IIO
if IIO
config IIO_DEBUG
boolean "Debug support for Industrial I/O"
depends on DEBUG_KERNEL
help
Say "yes" to enable debug messaging (like dev_dbg and pr_debug)
support in Industrial I/O subsystem and drivers.
config IIO_BUFFER
bool "Enable buffer support within IIO"
help
@ -23,15 +30,14 @@ if IIO_BUFFER
config IIO_BUFFER_CB
boolean "IIO callback buffer used for push in-kernel interfaces"
help
Should be selected by any drivers that do-inkernel push
Should be selected by any drivers that do in-kernel push
usage. That is, those where the data is pushed to the consumer.
config IIO_KFIFO_BUF
select IIO_TRIGGER
tristate "Industrial I/O buffering based on kfifo"
help
A simple fifo based on kfifo. Use this if you want a fifo
rather than a ring buffer. Note that this currently provides
A simple fifo based on kfifo. Note that this currently provides
no buffer events so it is up to userspace to work out how
often to read from the buffer.
@ -49,7 +55,7 @@ config IIO_TRIGGER
help
Provides IIO core support for triggers. Currently these
are used to initialize capture of samples to push into
ring buffers. The triggers are effectively a 'capture
buffers. The triggers are effectively a 'capture
data now' interrupt.
config IIO_CONSUMERS_PER_TRIGGER

View File

@ -2,6 +2,8 @@
# Makefile for the industrial I/O core.
#
ccflags-$(CONFIG_IIO_DEBUG) := -DDEBUG
obj-$(CONFIG_IIO) += industrialio.o
industrialio-y := industrialio-core.o industrialio-event.o inkern.o
industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o

View File

@ -1,6 +1,8 @@
#
# Accelerometer drivers
#
# When adding new entries keep the list in alphabetical order
menu "Accelerometers"
config HID_SENSOR_ACCEL_3D
@ -14,13 +16,6 @@ config HID_SENSOR_ACCEL_3D
Say yes here to build support for the HID SENSOR
accelerometers 3D.
config KXSD9
tristate "Kionix KXSD9 Accelerometer Driver"
depends on SPI
help
Say yes here to build support for the Kionix KXSD9 accelerometer.
Currently this only supports the device via an SPI interface.
config IIO_ST_ACCEL_3AXIS
tristate "STMicroelectronics accelerometers 3-Axis Driver"
depends on (I2C || SPI_MASTER) && SYSFS
@ -33,8 +28,8 @@ config IIO_ST_ACCEL_3AXIS
LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
LIS331DLH, LSM303DL, LSM303DLM, LSM330.
This driver can also be built as a module. If so, will be created
these modules:
This driver can also be built as a module. If so, these modules
will be created:
- st_accel (core functions for the driver [it is mandatory]);
- st_accel_i2c (necessary for the I2C devices [optional*]);
- st_accel_spi (necessary for the SPI devices [optional*]);
@ -51,4 +46,11 @@ config IIO_ST_ACCEL_SPI_3AXIS
depends on IIO_ST_ACCEL_3AXIS
depends on IIO_ST_SENSORS_SPI
config KXSD9
tristate "Kionix KXSD9 Accelerometer Driver"
depends on SPI
help
Say yes here to build support for the Kionix KXSD9 accelerometer.
Currently this only supports the device via an SPI interface.
endmenu

View File

@ -2,7 +2,9 @@
# Makefile for industrial I/O accelerometer drivers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXSD9) += kxsd9.o
obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
st_accel-y := st_accel_core.o
@ -10,5 +12,3 @@ st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
obj-$(CONFIG_KXSD9) += kxsd9.o

View File

@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
/*Format: HID-SENSOR-usage_id_in_hex*/
/*Usage ID from spec for Accelerometer-3D: 0x200073*/
#define DRIVER_NAME "HID-SENSOR-200073"
enum accel_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
@ -286,11 +282,11 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
indio_dev = iio_device_alloc(sizeof(struct accel_3d_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&pdev->dev,
sizeof(struct accel_3d_state));
if (indio_dev == NULL)
return -ENOMEM;
platform_set_drvdata(pdev, indio_dev);
accel_state = iio_priv(indio_dev);
@ -302,15 +298,14 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
&accel_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
goto error_free_dev;
return ret;
}
channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
return -ENOMEM;
}
ret = accel_3d_parse_report(pdev, hsdev, channels,
@ -367,9 +362,6 @@ error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
@ -384,14 +376,23 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
iio_device_free(indio_dev);
return 0;
}
static struct platform_device_id hid_accel_3d_ids[] = {
{
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-200073",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids);
static struct platform_driver hid_accel_3d_platform_driver = {
.id_table = hid_accel_3d_ids,
.driver = {
.name = DRIVER_NAME,
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_accel_3d_probe,

View File

@ -224,11 +224,10 @@ static int kxsd9_probe(struct spi_device *spi)
struct kxsd9_state *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
@ -247,20 +246,14 @@ static int kxsd9_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
return ret;
return 0;
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
static int kxsd9_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
return 0;
}

View File

@ -25,7 +25,16 @@
#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel"
#define LSM330_ACCEL_DEV_NAME "lsm330_accel"
int st_accel_common_probe(struct iio_dev *indio_dev);
/**
* struct st_sensors_platform_data - default accel platform data
* @drdy_int_pin: default accel DRDY is available on INT1 pin.
*/
static const struct st_sensors_platform_data default_accel_pdata = {
.drdy_int_pin = 1,
};
int st_accel_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata);
void st_accel_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER

View File

@ -65,7 +65,8 @@
#define ST_ACCEL_1_BDU_ADDR 0x23
#define ST_ACCEL_1_BDU_MASK 0x80
#define ST_ACCEL_1_DRDY_IRQ_ADDR 0x22
#define ST_ACCEL_1_DRDY_IRQ_MASK 0x10
#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK 0x10
#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK 0x08
#define ST_ACCEL_1_MULTIREAD_BIT true
/* CUSTOM VALUES FOR SENSOR 2 */
@ -89,7 +90,8 @@
#define ST_ACCEL_2_BDU_ADDR 0x23
#define ST_ACCEL_2_BDU_MASK 0x80
#define ST_ACCEL_2_DRDY_IRQ_ADDR 0x22
#define ST_ACCEL_2_DRDY_IRQ_MASK 0x02
#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK 0x02
#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK 0x10
#define ST_ACCEL_2_MULTIREAD_BIT true
/* CUSTOM VALUES FOR SENSOR 3 */
@ -121,7 +123,8 @@
#define ST_ACCEL_3_BDU_ADDR 0x20
#define ST_ACCEL_3_BDU_MASK 0x08
#define ST_ACCEL_3_DRDY_IRQ_ADDR 0x23
#define ST_ACCEL_3_DRDY_IRQ_MASK 0x80
#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK 0x80
#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK 0x00
#define ST_ACCEL_3_IG1_EN_ADDR 0x23
#define ST_ACCEL_3_IG1_EN_MASK 0x08
#define ST_ACCEL_3_MULTIREAD_BIT false
@ -224,7 +227,8 @@ static const struct st_sensors st_accel_sensors[] = {
},
.drdy_irq = {
.addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
.mask = ST_ACCEL_1_DRDY_IRQ_MASK,
.mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK,
.mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
.bootime = 2,
@ -285,7 +289,8 @@ static const struct st_sensors st_accel_sensors[] = {
},
.drdy_irq = {
.addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
.mask = ST_ACCEL_2_DRDY_IRQ_MASK,
.mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK,
.mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
.bootime = 2,
@ -358,7 +363,8 @@ static const struct st_sensors st_accel_sensors[] = {
},
.drdy_irq = {
.addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
.mask = ST_ACCEL_3_DRDY_IRQ_MASK,
.mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK,
.mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
.ig1 = {
.en_addr = ST_ACCEL_3_IG1_EN_ADDR,
.en_mask = ST_ACCEL_3_IG1_EN_MASK,
@ -443,7 +449,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
#define ST_ACCEL_TRIGGER_OPS NULL
#endif
int st_accel_common_probe(struct iio_dev *indio_dev)
int st_accel_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *plat_data)
{
int err;
struct st_sensor_data *adata = iio_priv(indio_dev);
@ -465,7 +472,11 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
&adata->sensor->fs.fs_avl[0];
adata->odr = adata->sensor->odr.odr_avl[0].hz;
err = st_sensors_init_sensor(indio_dev);
if (!plat_data)
plat_data =
(struct st_sensors_platform_data *)&default_accel_pdata;
err = st_sensors_init_sensor(indio_dev, plat_data);
if (err < 0)
goto st_accel_common_probe_error;
@ -506,7 +517,6 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_accel_deallocate_ring(indio_dev);
}
iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_accel_common_remove);

View File

@ -25,27 +25,20 @@ static int st_accel_i2c_probe(struct i2c_client *client,
struct st_sensor_data *adata;
int err;
indio_dev = iio_device_alloc(sizeof(*adata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));
if (!indio_dev)
return -ENOMEM;
adata = iio_priv(indio_dev);
adata->dev = &client->dev;
st_sensors_i2c_configure(indio_dev, client, adata);
err = st_accel_common_probe(indio_dev);
err = st_accel_common_probe(indio_dev, client->dev.platform_data);
if (err < 0)
goto st_accel_common_probe_error;
return err;
return 0;
st_accel_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_accel_i2c_remove(struct i2c_client *client)

View File

@ -24,27 +24,20 @@ static int st_accel_spi_probe(struct spi_device *spi)
struct st_sensor_data *adata;
int err;
indio_dev = iio_device_alloc(sizeof(*adata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adata));
if (!indio_dev)
return -ENOMEM;
adata = iio_priv(indio_dev);
adata->dev = &spi->dev;
st_sensors_spi_configure(indio_dev, spi, adata);
err = st_accel_common_probe(indio_dev);
err = st_accel_common_probe(indio_dev, spi->dev.platform_data);
if (err < 0)
goto st_accel_common_probe_error;
return err;
return 0;
st_accel_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_accel_spi_remove(struct spi_device *spi)

View File

@ -1,6 +1,8 @@
#
# ADC drivers
#
# When adding new entries keep the list in alphabetical order
menu "Analog to digital converters"
config AD_SIGMA_DELTA
@ -30,17 +32,20 @@ config AD7298
To compile this driver as a module, choose M here: the
module will be called ad7298.
config AD7923
tristate "Analog Devices AD7923 and similar ADCs driver"
config AD7476
tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices
AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
AD7495, AD7910, AD7920, AD7920 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
module will be called ad7923.
module will be called ad7476.
config AD7791
tristate "Analog Devices AD7791 ADC driver"
@ -66,21 +71,6 @@ config AD7793
To compile this driver as a module, choose M here: the
module will be called AD7793.
config AD7476
tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
AD7495, AD7910, AD7920, AD7920 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
module will be called ad7476.
config AD7887
tristate "Analog Devices AD7887 ADC driver"
depends on SPI
@ -94,6 +84,18 @@ config AD7887
To compile this driver as a module, choose M here: the
module will be called ad7887.
config AD7923
tristate "Analog Devices AD7923 and similar ADCs driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices
AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
To compile this driver as a module, choose M here: the
module will be called ad7923.
config AT91_ADC
tristate "Atmel AT91 ADC"
depends on ARCH_AT91
@ -143,6 +145,15 @@ config MCP320X
This driver can also be built as a module. If so, the module will be
called mcp320x.
config NAU7802
tristate "Nuvoton NAU7802 ADC driver"
depends on I2C
help
Say yes here to build support for Nuvoton NAU7802 ADC.
To compile this driver as a module, choose M here: the
module will be called nau7802.
config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
@ -154,7 +165,7 @@ config TI_ADC081C
called ti-adc081c.
config TI_AM335X_ADC
tristate "TI's ADC driver"
tristate "TI's AM335X ADC driver"
depends on MFD_TI_AM335X_TSCADC
help
Say yes here to build support for Texas Instruments ADC

View File

@ -2,6 +2,7 @@
# Makefile for IIO ADC drivers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7298) += ad7298.o
@ -15,6 +16,7 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o

View File

@ -399,17 +399,17 @@ static int ad7266_probe(struct spi_device *spi)
unsigned int i;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vref");
st->reg = devm_regulator_get(&spi->dev, "vref");
if (!IS_ERR_OR_NULL(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
ret = regulator_get_voltage(st->reg);
if (ret < 0)
@ -489,11 +489,6 @@ error_free_gpios:
error_disable_reg:
if (!IS_ERR_OR_NULL(st->reg))
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR_OR_NULL(st->reg))
regulator_put(st->reg);
iio_device_free(indio_dev);
return ret;
}
@ -507,11 +502,8 @@ static int ad7266_remove(struct spi_device *spi)
iio_triggered_buffer_cleanup(indio_dev);
if (!st->fixed_addr)
gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
if (!IS_ERR_OR_NULL(st->reg)) {
if (!IS_ERR_OR_NULL(st->reg))
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}

View File

@ -296,9 +296,10 @@ static int ad7298_probe(struct spi_device *spi)
{
struct ad7298_platform_data *pdata = spi->dev.platform_data;
struct ad7298_state *st;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -308,14 +309,13 @@ static int ad7298_probe(struct spi_device *spi)
st->ext_ref = AD7298_EXTREF;
if (st->ext_ref) {
st->reg = regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free;
}
st->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
}
spi_set_drvdata(spi, indio_dev);
@ -361,11 +361,6 @@ error_cleanup_ring:
error_disable_reg:
if (st->ext_ref)
regulator_disable(st->reg);
error_put_reg:
if (st->ext_ref)
regulator_put(st->reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
@ -377,11 +372,8 @@ static int ad7298_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (st->ext_ref) {
if (st->ext_ref)
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}

View File

@ -213,24 +213,21 @@ static int ad7476_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->chip_info =
&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
st->reg = regulator_get(&spi->dev, "vcc");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free_dev;
}
st->reg = devm_regulator_get(&spi->dev, "vcc");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
spi_set_drvdata(spi, indio_dev);
@ -268,12 +265,7 @@ error_ring_unregister:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
error_put_reg:
regulator_put(st->reg);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
@ -285,8 +277,6 @@ static int ad7476_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(st->reg);
regulator_put(st->reg);
iio_device_free(indio_dev);
return 0;
}

View File

@ -361,21 +361,19 @@ static int ad7791_probe(struct spi_device *spi)
return -ENXIO;
}
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto err_iio_free;
}
st->reg = devm_regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data];
ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info);
@ -410,10 +408,6 @@ error_remove_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
error_put_reg:
regulator_put(st->reg);
err_iio_free:
iio_device_free(indio_dev);
return ret;
}
@ -427,9 +421,6 @@ static int ad7791_remove(struct spi_device *spi)
ad_sd_cleanup_buffer_and_trigger(indio_dev);
regulator_disable(st->reg);
regulator_put(st->reg);
iio_device_free(indio_dev);
return 0;
}

View File

@ -757,7 +757,7 @@ static int ad7793_probe(struct spi_device *spi)
return -ENODEV;
}
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -766,15 +766,13 @@ static int ad7793_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
st->reg = regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_device_free;
}
st->reg = devm_regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
vref_mv = regulator_get_voltage(st->reg);
if (vref_mv < 0) {
@ -818,11 +816,6 @@ error_remove_trigger:
error_disable_reg:
if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_disable(st->reg);
error_put_reg:
if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_put(st->reg);
error_device_free:
iio_device_free(indio_dev);
return ret;
}
@ -836,12 +829,8 @@ static int ad7793_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
if (pdata->refsel != AD7793_REFSEL_INTERNAL)
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}

View File

@ -237,25 +237,24 @@ static int ad7887_probe(struct spi_device *spi)
{
struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
struct iio_dev *indio_dev;
uint8_t mode;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
if (!pdata || !pdata->use_onchip_ref) {
st->reg = regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free;
}
st->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
}
st->chip_info =
@ -331,11 +330,6 @@ error_unregister_ring:
error_disable_reg:
if (st->reg)
regulator_disable(st->reg);
error_put_reg:
if (st->reg)
regulator_put(st->reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
@ -347,11 +341,8 @@ static int ad7887_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (st->reg) {
if (st->reg)
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}

View File

@ -275,10 +275,11 @@ static const struct iio_info ad7923_info = {
static int ad7923_probe(struct spi_device *spi)
{
struct ad7923_state *st;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
struct iio_dev *indio_dev;
const struct ad7923_chip_info *info;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -311,14 +312,13 @@ static int ad7923_probe(struct spi_device *spi)
spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
st->reg = regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free;
}
st->reg = devm_regulator_get(&spi->dev, "refin");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&ad7923_trigger_handler, NULL);
@ -335,10 +335,6 @@ error_cleanup_ring:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
error_put_reg:
regulator_put(st->reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
@ -351,8 +347,6 @@ static int ad7923_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(st->reg);
regulator_put(st->reg);
iio_device_free(indio_dev);
return 0;
}

View File

@ -589,11 +589,9 @@ static int at91_adc_probe(struct platform_device *pdev)
struct resource *res;
u32 reg;
idev = iio_device_alloc(sizeof(struct at91_adc_state));
if (idev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state));
if (!idev)
return -ENOMEM;
st = iio_priv(idev);
@ -604,8 +602,7 @@ static int at91_adc_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "No platform data available.\n");
ret = -EINVAL;
goto error_free_device;
return -EINVAL;
}
platform_set_drvdata(pdev, idev);
@ -618,16 +615,14 @@ static int at91_adc_probe(struct platform_device *pdev)
st->irq = platform_get_irq(pdev, 0);
if (st->irq < 0) {
dev_err(&pdev->dev, "No IRQ ID is designated\n");
ret = -ENODEV;
goto error_free_device;
return -ENODEV;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
st->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(st->reg_base)) {
ret = PTR_ERR(st->reg_base);
goto error_free_device;
return PTR_ERR(st->reg_base);
}
/*
@ -642,7 +637,7 @@ static int at91_adc_probe(struct platform_device *pdev)
idev);
if (ret) {
dev_err(&pdev->dev, "Failed to allocate IRQ.\n");
goto error_free_device;
return ret;
}
st->clk = devm_clk_get(&pdev->dev, "adc_clk");
@ -752,9 +747,6 @@ error_disable_clk:
clk_disable_unprepare(st->clk);
error_free_irq:
free_irq(st->irq, idev);
error_free_device:
iio_device_free(idev);
error_ret:
return ret;
}
@ -769,7 +761,6 @@ static int at91_adc_remove(struct platform_device *pdev)
clk_disable_unprepare(st->adc_clk);
clk_disable_unprepare(st->clk);
free_irq(st->irq, idev);
iio_device_free(idev);
return 0;
}

View File

@ -33,6 +33,7 @@
#include <linux/of_irq.h>
#include <linux/regulator/consumer.h>
#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
@ -261,7 +262,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (!np)
return ret;
indio_dev = iio_device_alloc(sizeof(struct exynos_adc));
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc));
if (!indio_dev) {
dev_err(&pdev->dev, "failed allocating iio device\n");
return -ENOMEM;
@ -271,23 +272,18 @@ static int exynos_adc_probe(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(info->regs)) {
ret = PTR_ERR(info->regs);
goto err_iio;
}
if (IS_ERR(info->regs))
return PTR_ERR(info->regs);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
info->enable_reg = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(info->enable_reg)) {
ret = PTR_ERR(info->enable_reg);
goto err_iio;
}
if (IS_ERR(info->enable_reg))
return PTR_ERR(info->enable_reg);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
ret = irq;
goto err_iio;
return irq;
}
info->irq = irq;
@ -299,7 +295,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
info->irq);
goto err_iio;
return ret;
}
writel(1, info->enable_reg);
@ -365,8 +361,6 @@ err_iio_dev:
iio_device_unregister(indio_dev);
err_irq:
free_irq(info->irq, info);
err_iio:
iio_device_free(indio_dev);
return ret;
}
@ -382,7 +376,6 @@ static int exynos_adc_remove(struct platform_device *pdev)
writel(0, info->enable_reg);
iio_device_unregister(indio_dev);
free_irq(info->irq, info);
iio_device_free(indio_dev);
return 0;
}

View File

@ -194,7 +194,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
struct lp8788_adc *adc;
int ret;
indio_dev = iio_device_alloc(sizeof(*adc));
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
@ -205,7 +205,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
indio_dev->dev.of_node = pdev->dev.of_node;
ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
if (ret)
goto err_iio_map;
return ret;
mutex_init(&adc->lock);
@ -226,8 +226,6 @@ static int lp8788_adc_probe(struct platform_device *pdev)
err_iio_device:
iio_map_array_unregister(indio_dev);
err_iio_map:
iio_device_free(indio_dev);
return ret;
}
@ -237,7 +235,6 @@ static int lp8788_adc_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
iio_map_array_unregister(indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -1498,16 +1498,15 @@ static int max1363_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
struct regulator *vref;
indio_dev = iio_device_alloc(sizeof(struct max1363_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_out;
}
indio_dev = devm_iio_device_alloc(&client->dev,
sizeof(struct max1363_state));
if (!indio_dev)
return -ENOMEM;
indio_dev->dev.of_node = client->dev.of_node;
ret = iio_map_array_register(indio_dev, client->dev.platform_data);
if (ret < 0)
goto error_free_device;
return ret;
st = iio_priv(indio_dev);
@ -1590,9 +1589,6 @@ error_disable_reg:
regulator_disable(st->reg);
error_unregister_map:
iio_map_array_unregister(indio_dev);
error_free_device:
iio_device_free(indio_dev);
error_out:
return ret;
}
@ -1607,7 +1603,6 @@ static int max1363_remove(struct i2c_client *client)
regulator_disable(st->vref);
regulator_disable(st->reg);
iio_map_array_unregister(indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -169,7 +169,7 @@ static int mcp320x_probe(struct spi_device *spi)
const struct mcp3208_chip_info *chip_info;
int ret;
indio_dev = iio_device_alloc(sizeof(*adc));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
@ -193,15 +193,13 @@ static int mcp320x_probe(struct spi_device *spi)
spi_message_init_with_transfers(&adc->msg, adc->transfer,
ARRAY_SIZE(adc->transfer));
adc->reg = regulator_get(&spi->dev, "vref");
if (IS_ERR(adc->reg)) {
ret = PTR_ERR(adc->reg);
goto iio_free;
}
adc->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(adc->reg))
return PTR_ERR(adc->reg);
ret = regulator_enable(adc->reg);
if (ret < 0)
goto reg_free;
return ret;
mutex_init(&adc->lock);
@ -213,10 +211,6 @@ static int mcp320x_probe(struct spi_device *spi)
reg_disable:
regulator_disable(adc->reg);
reg_free:
regulator_put(adc->reg);
iio_free:
iio_device_free(indio_dev);
return ret;
}
@ -228,8 +222,6 @@ static int mcp320x_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
regulator_disable(adc->reg);
regulator_put(adc->reg);
iio_device_free(indio_dev);
return 0;
}

581
drivers/iio/adc/nau7802.c Normal file
View File

@ -0,0 +1,581 @@
/*
* Driver for the Nuvoton NAU7802 ADC
*
* Copyright 2013 Free Electrons
*
* Licensed under the GPLv2 or later.
*/
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/log2.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define NAU7802_REG_PUCTRL 0x00
#define NAU7802_PUCTRL_RR(x) (x << 0)
#define NAU7802_PUCTRL_RR_BIT NAU7802_PUCTRL_RR(1)
#define NAU7802_PUCTRL_PUD(x) (x << 1)
#define NAU7802_PUCTRL_PUD_BIT NAU7802_PUCTRL_PUD(1)
#define NAU7802_PUCTRL_PUA(x) (x << 2)
#define NAU7802_PUCTRL_PUA_BIT NAU7802_PUCTRL_PUA(1)
#define NAU7802_PUCTRL_PUR(x) (x << 3)
#define NAU7802_PUCTRL_PUR_BIT NAU7802_PUCTRL_PUR(1)
#define NAU7802_PUCTRL_CS(x) (x << 4)
#define NAU7802_PUCTRL_CS_BIT NAU7802_PUCTRL_CS(1)
#define NAU7802_PUCTRL_CR(x) (x << 5)
#define NAU7802_PUCTRL_CR_BIT NAU7802_PUCTRL_CR(1)
#define NAU7802_PUCTRL_AVDDS(x) (x << 7)
#define NAU7802_PUCTRL_AVDDS_BIT NAU7802_PUCTRL_AVDDS(1)
#define NAU7802_REG_CTRL1 0x01
#define NAU7802_CTRL1_VLDO(x) (x << 3)
#define NAU7802_CTRL1_GAINS(x) (x)
#define NAU7802_CTRL1_GAINS_BITS 0x07
#define NAU7802_REG_CTRL2 0x02
#define NAU7802_CTRL2_CHS(x) (x << 7)
#define NAU7802_CTRL2_CRS(x) (x << 4)
#define NAU7802_SAMP_FREQ_320 0x07
#define NAU7802_CTRL2_CHS_BIT NAU7802_CTRL2_CHS(1)
#define NAU7802_REG_ADC_B2 0x12
#define NAU7802_REG_ADC_B1 0x13
#define NAU7802_REG_ADC_B0 0x14
#define NAU7802_REG_ADC_CTRL 0x15
#define NAU7802_MIN_CONVERSIONS 6
struct nau7802_state {
struct i2c_client *client;
s32 last_value;
struct mutex lock;
struct mutex data_lock;
u32 vref_mv;
u32 conversion_count;
u32 min_conversions;
u8 sample_rate;
u32 scale_avail[8];
struct completion value_ok;
};
#define NAU7802_CHANNEL(chan) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (chan), \
.scan_index = (chan), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ) \
}
static const struct iio_chan_spec nau7802_chan_array[] = {
NAU7802_CHANNEL(0),
NAU7802_CHANNEL(1),
};
static const u16 nau7802_sample_freq_avail[] = {10, 20, 40, 80,
10, 10, 10, 320};
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 40 80 320");
static struct attribute *nau7802_attributes[] = {
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
static const struct attribute_group nau7802_attribute_group = {
.attrs = nau7802_attributes,
};
static int nau7802_set_gain(struct nau7802_state *st, int gain)
{
int ret;
mutex_lock(&st->lock);
st->conversion_count = 0;
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
if (ret < 0)
goto nau7802_sysfs_set_gain_out;
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
(ret & (~NAU7802_CTRL1_GAINS_BITS)) |
gain);
nau7802_sysfs_set_gain_out:
mutex_unlock(&st->lock);
return ret;
}
static int nau7802_read_conversion(struct nau7802_state *st)
{
int data;
mutex_lock(&st->data_lock);
data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B2);
if (data < 0)
goto nau7802_read_conversion_out;
st->last_value = data << 16;
data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B1);
if (data < 0)
goto nau7802_read_conversion_out;
st->last_value |= data << 8;
data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B0);
if (data < 0)
goto nau7802_read_conversion_out;
st->last_value |= data;
st->last_value = sign_extend32(st->last_value, 23);
nau7802_read_conversion_out:
mutex_unlock(&st->data_lock);
return data;
}
/*
* Conversions are synchronised on the rising edge of NAU7802_PUCTRL_CS_BIT
*/
static int nau7802_sync(struct nau7802_state *st)
{
int ret;
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
ret | NAU7802_PUCTRL_CS_BIT);
return ret;
}
static irqreturn_t nau7802_eoc_trigger(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct nau7802_state *st = iio_priv(indio_dev);
int status;
status = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
if (status < 0)
return IRQ_HANDLED;
if (!(status & NAU7802_PUCTRL_CR_BIT))
return IRQ_NONE;
if (nau7802_read_conversion(st) < 0)
return IRQ_HANDLED;
/*
* Because there is actually only one ADC for both channels, we have to
* wait for enough conversions to happen before getting a significant
* value when changing channels and the values are far apart.
*/
if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
st->conversion_count++;
if (st->conversion_count >= NAU7802_MIN_CONVERSIONS)
complete_all(&st->value_ok);
return IRQ_HANDLED;
}
static int nau7802_read_irq(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val)
{
struct nau7802_state *st = iio_priv(indio_dev);
int ret;
INIT_COMPLETION(st->value_ok);
enable_irq(st->client->irq);
nau7802_sync(st);
/* read registers to ensure we flush everything */
ret = nau7802_read_conversion(st);
if (ret < 0)
goto read_chan_info_failure;
/* Wait for a conversion to finish */
ret = wait_for_completion_interruptible_timeout(&st->value_ok,
msecs_to_jiffies(1000));
if (ret == 0)
ret = -ETIMEDOUT;
if (ret < 0)
goto read_chan_info_failure;
disable_irq(st->client->irq);
*val = st->last_value;
return IIO_VAL_INT;
read_chan_info_failure:
disable_irq(st->client->irq);
return ret;
}
static int nau7802_read_poll(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val)
{
struct nau7802_state *st = iio_priv(indio_dev);
int ret;
nau7802_sync(st);
/* read registers to ensure we flush everything */
ret = nau7802_read_conversion(st);
if (ret < 0)
return ret;
/*
* Because there is actually only one ADC for both channels, we have to
* wait for enough conversions to happen before getting a significant
* value when changing channels and the values are far appart.
*/
do {
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
if (ret < 0)
return ret;
while (!(ret & NAU7802_PUCTRL_CR_BIT)) {
if (st->sample_rate != NAU7802_SAMP_FREQ_320)
msleep(20);
else
mdelay(4);
ret = i2c_smbus_read_byte_data(st->client,
NAU7802_REG_PUCTRL);
if (ret < 0)
return ret;
}
ret = nau7802_read_conversion(st);
if (ret < 0)
return ret;
if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
st->conversion_count++;
} while (st->conversion_count < NAU7802_MIN_CONVERSIONS);
*val = st->last_value;
return IIO_VAL_INT;
}
static int nau7802_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct nau7802_state *st = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
/*
* Select the channel to use
* - Channel 1 is value 0 in the CHS register
* - Channel 2 is value 1 in the CHS register
*/
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL2);
if (ret < 0) {
mutex_unlock(&st->lock);
return ret;
}
if (((ret & NAU7802_CTRL2_CHS_BIT) && !chan->channel) ||
(!(ret & NAU7802_CTRL2_CHS_BIT) &&
chan->channel)) {
st->conversion_count = 0;
ret = i2c_smbus_write_byte_data(st->client,
NAU7802_REG_CTRL2,
NAU7802_CTRL2_CHS(chan->channel) |
NAU7802_CTRL2_CRS(st->sample_rate));
if (ret < 0) {
mutex_unlock(&st->lock);
return ret;
}
}
if (st->client->irq)
ret = nau7802_read_irq(indio_dev, chan, val);
else
ret = nau7802_read_poll(indio_dev, chan, val);
mutex_unlock(&st->lock);
return ret;
case IIO_CHAN_INFO_SCALE:
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
if (ret < 0)
return ret;
/*
* We have 24 bits of signed data, that means 23 bits of data
* plus the sign bit
*/
*val = st->vref_mv;
*val2 = 23 + (ret & NAU7802_CTRL1_GAINS_BITS);
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = nau7802_sample_freq_avail[st->sample_rate];
*val2 = 0;
return IIO_VAL_INT;
default:
break;
}
return -EINVAL;
}
static int nau7802_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct nau7802_state *st = iio_priv(indio_dev);
int i, ret;
switch (mask) {
case IIO_CHAN_INFO_SCALE:
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
if (val2 == st->scale_avail[i])
return nau7802_set_gain(st, i);
break;
case IIO_CHAN_INFO_SAMP_FREQ:
for (i = 0; i < ARRAY_SIZE(nau7802_sample_freq_avail); i++)
if (val == nau7802_sample_freq_avail[i]) {
mutex_lock(&st->lock);
st->sample_rate = i;
st->conversion_count = 0;
ret = i2c_smbus_write_byte_data(st->client,
NAU7802_REG_CTRL2,
NAU7802_CTRL2_CRS(st->sample_rate));
mutex_unlock(&st->lock);
return ret;
}
break;
default:
break;
}
return -EINVAL;
}
static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
return IIO_VAL_INT_PLUS_NANO;
}
static const struct iio_info nau7802_info = {
.driver_module = THIS_MODULE,
.read_raw = &nau7802_read_raw,
.write_raw = &nau7802_write_raw,
.write_raw_get_fmt = nau7802_write_raw_get_fmt,
.attrs = &nau7802_attribute_group,
};
static int nau7802_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct nau7802_state *st;
struct device_node *np = client->dev.of_node;
int i, ret;
u8 data;
u32 tmp = 0;
if (!client->dev.of_node) {
dev_err(&client->dev, "No device tree node available.\n");
return -EINVAL;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
indio_dev->dev.parent = &client->dev;
indio_dev->name = dev_name(&client->dev);
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &nau7802_info;
st->client = client;
/* Reset the device */
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
NAU7802_PUCTRL_RR_BIT);
if (ret < 0)
return ret;
/* Enter normal operation mode */
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
NAU7802_PUCTRL_PUD_BIT);
if (ret < 0)
return ret;
/*
* After about 200 usecs, the device should be ready and then
* the Power Up bit will be set to 1. If not, wait for it.
*/
udelay(210);
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
if (ret < 0)
return ret;
if (!(ret & NAU7802_PUCTRL_PUR_BIT))
return ret;
of_property_read_u32(np, "nuvoton,vldo", &tmp);
st->vref_mv = tmp;
data = NAU7802_PUCTRL_PUD_BIT | NAU7802_PUCTRL_PUA_BIT |
NAU7802_PUCTRL_CS_BIT;
if (tmp >= 2400)
data |= NAU7802_PUCTRL_AVDDS_BIT;
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL, data);
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_ADC_CTRL, 0x30);
if (ret < 0)
return ret;
if (tmp >= 2400) {
data = NAU7802_CTRL1_VLDO((4500 - tmp) / 300);
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
data);
if (ret < 0)
return ret;
}
/* Populate available ADC input ranges */
for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
st->scale_avail[i] = (((u64)st->vref_mv) * 1000000000ULL)
>> (23 + i);
init_completion(&st->value_ok);
/*
* The ADC fires continuously and we can't do anything about
* it. So we need to have the IRQ disabled by default, and we
* will enable them back when we will need them..
*/
if (client->irq) {
ret = request_threaded_irq(client->irq,
NULL,
nau7802_eoc_trigger,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
client->dev.driver->name,
indio_dev);
if (ret) {
/*
* What may happen here is that our IRQ controller is
* not able to get level interrupt but this is required
* by this ADC as when going over 40 sample per second,
* the interrupt line may stay high between conversions.
* So, we continue no matter what but we switch to
* polling mode.
*/
dev_info(&client->dev,
"Failed to allocate IRQ, using polling mode\n");
client->irq = 0;
} else
disable_irq(client->irq);
}
if (!client->irq) {
/*
* We are polling, use the fastest sample rate by
* default
*/
st->sample_rate = NAU7802_SAMP_FREQ_320;
ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL2,
NAU7802_CTRL2_CRS(st->sample_rate));
if (ret)
goto error_free_irq;
}
/* Setup the ADC channels available on the board */
indio_dev->num_channels = ARRAY_SIZE(nau7802_chan_array);
indio_dev->channels = nau7802_chan_array;
mutex_init(&st->lock);
mutex_init(&st->data_lock);
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "Couldn't register the device.\n");
goto error_device_register;
}
return 0;
error_device_register:
mutex_destroy(&st->lock);
mutex_destroy(&st->data_lock);
error_free_irq:
if (client->irq)
free_irq(client->irq, indio_dev);
return ret;
}
static int nau7802_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct nau7802_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
mutex_destroy(&st->lock);
mutex_destroy(&st->data_lock);
if (client->irq)
free_irq(client->irq, indio_dev);
return 0;
}
static const struct i2c_device_id nau7802_i2c_id[] = {
{ "nau7802", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);
static const struct of_device_id nau7802_dt_ids[] = {
{ .compatible = "nuvoton,nau7802" },
{},
};
MODULE_DEVICE_TABLE(of, nau7802_dt_ids);
static struct i2c_driver nau7802_driver = {
.probe = nau7802_probe,
.remove = nau7802_remove,
.id_table = nau7802_i2c_id,
.driver = {
.name = "nau7802",
.of_match_table = of_match_ptr(nau7802_dt_ids),
},
};
module_i2c_driver(nau7802_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Nuvoton NAU7802 ADC Driver");
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");

View File

@ -74,22 +74,20 @@ static int adc081c_probe(struct i2c_client *client,
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
iio = iio_device_alloc(sizeof(*adc));
iio = devm_iio_device_alloc(&client->dev, sizeof(*adc));
if (!iio)
return -ENOMEM;
adc = iio_priv(iio);
adc->i2c = client;
adc->ref = regulator_get(&client->dev, "vref");
if (IS_ERR(adc->ref)) {
err = PTR_ERR(adc->ref);
goto iio_free;
}
adc->ref = devm_regulator_get(&client->dev, "vref");
if (IS_ERR(adc->ref))
return PTR_ERR(adc->ref);
err = regulator_enable(adc->ref);
if (err < 0)
goto regulator_put;
return err;
iio->dev.parent = &client->dev;
iio->name = dev_name(&client->dev);
@ -109,10 +107,6 @@ static int adc081c_probe(struct i2c_client *client,
regulator_disable:
regulator_disable(adc->ref);
regulator_put:
regulator_put(adc->ref);
iio_free:
iio_device_free(iio);
return err;
}
@ -124,8 +118,6 @@ static int adc081c_remove(struct i2c_client *client)
iio_device_unregister(iio);
regulator_disable(adc->ref);
regulator_put(adc->ref);
iio_device_free(iio);
return 0;
}

View File

@ -202,11 +202,11 @@ static int tiadc_probe(struct platform_device *pdev)
return -EINVAL;
}
indio_dev = iio_device_alloc(sizeof(struct tiadc_device));
indio_dev = devm_iio_device_alloc(&pdev->dev,
sizeof(struct tiadc_device));
if (indio_dev == NULL) {
dev_err(&pdev->dev, "failed to allocate iio device\n");
err = -ENOMEM;
goto err_ret;
return -ENOMEM;
}
adc_dev = iio_priv(indio_dev);
@ -227,7 +227,7 @@ static int tiadc_probe(struct platform_device *pdev)
err = tiadc_channel_init(indio_dev, adc_dev->channels);
if (err < 0)
goto err_free_device;
return err;
err = iio_device_register(indio_dev);
if (err)
@ -239,9 +239,6 @@ static int tiadc_probe(struct platform_device *pdev)
err_free_channels:
tiadc_channels_remove(indio_dev);
err_free_device:
iio_device_free(indio_dev);
err_ret:
return err;
}
@ -257,8 +254,6 @@ static int tiadc_remove(struct platform_device *pdev)
step_en = get_adc_step_mask(adc_dev);
am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
iio_device_free(indio_dev);
return 0;
}

View File

@ -124,7 +124,7 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
int ret;
/* registering iio */
indio_dev = iio_device_alloc(sizeof(*adc));
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
if (!indio_dev) {
dev_err(&pdev->dev, "failed allocating iio device\n");
return -ENOMEM;
@ -142,16 +142,12 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&pdev->dev, "could not register iio (adc)");
goto error;
return ret;
}
platform_set_drvdata(pdev, indio_dev);
return 0;
error:
iio_device_free(indio_dev);
return ret;
}
static int vprbrd_adc_remove(struct platform_device *pdev)
@ -159,7 +155,6 @@ static int vprbrd_adc_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
iio_device_unregister(indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -1,6 +1,8 @@
#
# Gain Amplifiers, etc.
#
# When adding new entries keep the list in alphabetical order
menu "Amplifiers"
config AD8366

View File

@ -2,4 +2,5 @@
# Makefile iio/amplifiers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD8366) += ad8366.o

View File

@ -139,17 +139,17 @@ static int ad8366_probe(struct spi_device *spi)
struct ad8366_state *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
}
spi_set_drvdata(spi, indio_dev);
@ -173,11 +173,6 @@ static int ad8366_probe(struct spi_device *spi)
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
regulator_put(st->reg);
iio_device_free(indio_dev);
return ret;
}
@ -195,8 +190,6 @@ static int ad8366_remove(struct spi_device *spi)
regulator_put(reg);
}
iio_device_free(indio_dev);
return 0;
}

View File

@ -6,5 +6,6 @@
# instead of duplicating in each module.
#
# When adding new entries keep the list in alphabetical order
obj-y += hid-sensors/
obj-y += st_sensors/

View File

@ -22,7 +22,7 @@
static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
{
return ((s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8);
return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8;
}
static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
@ -118,7 +118,7 @@ st_sensors_match_odr_error:
}
static int st_sensors_set_fullscale(struct iio_dev *indio_dev,
unsigned int fs)
unsigned int fs)
{
int err, i = 0;
struct st_sensor_data *sdata = iio_priv(indio_dev);
@ -198,13 +198,39 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
}
EXPORT_SYMBOL(st_sensors_set_axis_enable);
int st_sensors_init_sensor(struct iio_dev *indio_dev)
int st_sensors_init_sensor(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *sdata = iio_priv(indio_dev);
mutex_init(&sdata->tb.buf_lock);
switch (pdata->drdy_int_pin) {
case 1:
if (sdata->sensor->drdy_irq.mask_int1 == 0) {
dev_err(&indio_dev->dev,
"DRDY on INT1 not available.\n");
err = -EINVAL;
goto init_error;
}
sdata->drdy_int_pin = 1;
break;
case 2:
if (sdata->sensor->drdy_irq.mask_int2 == 0) {
dev_err(&indio_dev->dev,
"DRDY on INT2 not available.\n");
err = -EINVAL;
goto init_error;
}
sdata->drdy_int_pin = 2;
break;
default:
dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
err = -EINVAL;
goto init_error;
}
err = st_sensors_set_enable(indio_dev, false);
if (err < 0)
goto init_error;
@ -234,6 +260,7 @@ EXPORT_SYMBOL(st_sensors_init_sensor);
int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
{
int err;
u8 drdy_mask;
struct st_sensor_data *sdata = iio_priv(indio_dev);
/* Enable/Disable the interrupt generator 1. */
@ -245,10 +272,14 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
goto st_accel_set_dataready_irq_error;
}
if (sdata->drdy_int_pin == 1)
drdy_mask = sdata->sensor->drdy_irq.mask_int1;
else
drdy_mask = sdata->sensor->drdy_irq.mask_int2;
/* Enable/Disable the interrupt generator for data ready. */
err = st_sensors_write_data_with_mask(indio_dev,
sdata->sensor->drdy_irq.addr,
sdata->sensor->drdy_irq.mask, (int)enable);
sdata->sensor->drdy_irq.addr, drdy_mask, (int)enable);
st_accel_set_dataready_irq_error:
return err;

View File

@ -1,6 +1,8 @@
#
# DAC drivers
#
# When adding new entries keep the list in alphabetical order
menu "Digital to analog converters"
config AD5064
@ -15,7 +17,7 @@ config AD5064
module will be called ad5064.
config AD5360
tristate "Analog Devices Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
tristate "Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD5360, AD5361,
@ -48,13 +50,6 @@ config AD5421
To compile this driver as module choose M here: the module will be called
ad5421.
config AD5624R_SPI
tristate "Analog Devices AD5624/44/64R DAC spi driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD5624R, AD5644R and
AD5664R converters (DAC). This driver uses the common SPI interface.
config AD5446
tristate "Analog Devices AD5446 and similar single channel DACs driver"
depends on (SPI_MASTER && I2C!=m) || I2C
@ -68,7 +63,7 @@ config AD5446
module will be called ad5446.
config AD5449
tristate "Analog Device AD5449 and similar DACs driver"
tristate "Analog Devices AD5449 and similar DACs driver"
depends on SPI_MASTER
help
Say yes here to build support for Analog Devices AD5415, AD5426, AD5429,
@ -87,6 +82,24 @@ config AD5504
To compile this driver as a module, choose M here: the
module will be called ad5504.
config AD5624R_SPI
tristate "Analog Devices AD5624/44/64R DAC spi driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD5624R, AD5644R and
AD5664R converters (DAC). This driver uses the common SPI interface.
config AD5686
tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD5686R, AD5685R,
AD5684R, AD5791 Voltage Output Digital to
Analog Converter.
To compile this driver as a module, choose M here: the
module will be called ad5686.
config AD5755
tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver"
depends on SPI_MASTER
@ -119,19 +132,8 @@ config AD5791
To compile this driver as a module, choose M here: the
module will be called ad5791.
config AD5686
tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD5686R, AD5685R,
AD5684R, AD5791 Voltage Output Digital to
Analog Converter.
To compile this driver as a module, choose M here: the
module will be called ad5686.
config AD7303
tristate "Analog Devices Analog Devices AD7303 DAC driver"
tristate "Analog Devices AD7303 DAC driver"
depends on SPI
help
Say yes here to build support for Analog Devices AD7303 Digital to Analog

View File

@ -2,6 +2,7 @@
# Makefile for industrial I/O DAC drivers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD5360) += ad5360.o
obj-$(CONFIG_AD5380) += ad5380.o
obj-$(CONFIG_AD5421) += ad5421.o

View File

@ -12,14 +12,13 @@
* driver for the Microchip I2C 12-bit digital-to-analog converter (DAC)
* (7-bit I2C slave address 0x60, the three LSBs can be configured in
* hardware)
*
* writing the DAC value to EEPROM is not supported
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -32,15 +31,19 @@ struct mcp4725_data {
struct i2c_client *client;
u16 vref_mv;
u16 dac_value;
bool powerdown;
unsigned powerdown_mode;
};
#ifdef CONFIG_PM_SLEEP
static int mcp4725_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct mcp4725_data *data = iio_priv(indio_dev);
u8 outbuf[2];
outbuf[0] = 0x3 << 4; /* power-down bits, 500 kOhm resistor */
outbuf[0] = (data->powerdown_mode + 1) << 4;
outbuf[1] = 0;
data->powerdown = true;
return i2c_master_send(to_i2c_client(dev), outbuf, 2);
}
@ -54,16 +57,150 @@ static int mcp4725_resume(struct device *dev)
/* restore previous DAC value */
outbuf[0] = (data->dac_value >> 8) & 0xf;
outbuf[1] = data->dac_value & 0xff;
data->powerdown = false;
return i2c_master_send(to_i2c_client(dev), outbuf, 2);
}
#ifdef CONFIG_PM_SLEEP
static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
#define MCP4725_PM_OPS (&mcp4725_pm_ops)
#else
#define MCP4725_PM_OPS NULL
#endif
static ssize_t mcp4725_store_eeprom(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct mcp4725_data *data = iio_priv(indio_dev);
int tries = 20;
u8 inoutbuf[3];
bool state;
int ret;
ret = strtobool(buf, &state);
if (ret < 0)
return ret;
if (!state)
return 0;
inoutbuf[0] = 0x60; /* write EEPROM */
inoutbuf[1] = data->dac_value >> 4;
inoutbuf[2] = (data->dac_value & 0xf) << 4;
ret = i2c_master_send(data->client, inoutbuf, 3);
if (ret < 0)
return ret;
else if (ret != 3)
return -EIO;
/* wait for write complete, takes up to 50ms */
while (tries--) {
msleep(20);
ret = i2c_master_recv(data->client, inoutbuf, 3);
if (ret < 0)
return ret;
else if (ret != 3)
return -EIO;
if (inoutbuf[0] & 0x80)
break;
}
if (tries < 0) {
dev_err(&data->client->dev,
"mcp4725_store_eeprom() failed, incomplete\n");
return -EIO;
}
return len;
}
static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0);
static struct attribute *mcp4725_attributes[] = {
&iio_dev_attr_store_eeprom.dev_attr.attr,
NULL,
};
static const struct attribute_group mcp4725_attribute_group = {
.attrs = mcp4725_attributes,
};
static const char * const mcp4725_powerdown_modes[] = {
"1kohm_to_gnd",
"100kohm_to_gnd",
"500kohm_to_gnd"
};
static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
struct mcp4725_data *data = iio_priv(indio_dev);
return data->powerdown_mode;
}
static int mcp4725_set_powerdown_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, unsigned mode)
{
struct mcp4725_data *data = iio_priv(indio_dev);
data->powerdown_mode = mode;
return 0;
}
static ssize_t mcp4725_read_powerdown(struct iio_dev *indio_dev,
uintptr_t private, const struct iio_chan_spec *chan, char *buf)
{
struct mcp4725_data *data = iio_priv(indio_dev);
return sprintf(buf, "%d\n", data->powerdown);
}
static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
uintptr_t private, const struct iio_chan_spec *chan,
const char *buf, size_t len)
{
struct mcp4725_data *data = iio_priv(indio_dev);
bool state;
int ret;
ret = strtobool(buf, &state);
if (ret)
return ret;
if (state)
ret = mcp4725_suspend(&data->client->dev);
else
ret = mcp4725_resume(&data->client->dev);
if (ret < 0)
return ret;
return len;
}
static const struct iio_enum mcp4725_powerdown_mode_enum = {
.items = mcp4725_powerdown_modes,
.num_items = ARRAY_SIZE(mcp4725_powerdown_modes),
.get = mcp4725_get_powerdown_mode,
.set = mcp4725_set_powerdown_mode,
};
static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
{
.name = "powerdown",
.read = mcp4725_read_powerdown,
.write = mcp4725_write_powerdown,
},
IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
{ },
};
static const struct iio_chan_spec mcp4725_channel = {
.type = IIO_VOLTAGE,
.indexed = 1,
@ -72,6 +209,7 @@ static const struct iio_chan_spec mcp4725_channel = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
.scan_type = IIO_ST('u', 12, 16, 0),
.ext_info = mcp4725_ext_info,
};
static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
@ -138,6 +276,7 @@ static int mcp4725_write_raw(struct iio_dev *indio_dev,
static const struct iio_info mcp4725_info = {
.read_raw = mcp4725_read_raw,
.write_raw = mcp4725_write_raw,
.attrs = &mcp4725_attribute_group,
.driver_module = THIS_MODULE,
};
@ -148,19 +287,17 @@ static int mcp4725_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
struct mcp4725_platform_data *platform_data = client->dev.platform_data;
u8 inbuf[3];
u8 pd;
int err;
if (!platform_data || !platform_data->vref_mv) {
dev_err(&client->dev, "invalid platform data");
err = -EINVAL;
goto exit;
return -EINVAL;
}
indio_dev = iio_device_alloc(sizeof(*data));
if (indio_dev == NULL) {
err = -ENOMEM;
goto exit;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (indio_dev == NULL)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
@ -177,31 +314,25 @@ static int mcp4725_probe(struct i2c_client *client,
err = i2c_master_recv(client, inbuf, 3);
if (err < 0) {
dev_err(&client->dev, "failed to read DAC value");
goto exit_free_device;
return err;
}
pd = (inbuf[0] >> 1) & 0x3;
data->powerdown = pd > 0 ? true : false;
data->powerdown_mode = pd ? pd-1 : 2; /* 500kohm_to_gnd */
data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
err = iio_device_register(indio_dev);
if (err)
goto exit_free_device;
return err;
dev_info(&client->dev, "MCP4725 DAC registered\n");
return 0;
exit_free_device:
iio_device_free(indio_dev);
exit:
return err;
}
static int mcp4725_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
iio_device_free(indio_dev);
iio_device_unregister(i2c_get_clientdata(client));
return 0;
}

View File

@ -4,6 +4,7 @@
# Clock Distribution device drivers
# Phase-Locked Loop (PLL) frequency synthesizers
#
# When adding new entries keep the list in alphabetical order
menu "Frequency Synthesizers DDS/PLL"

View File

@ -2,5 +2,6 @@
# Makefile iio/frequency
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD9523) += ad9523.o
obj-$(CONFIG_ADF4350) += adf4350.o

View File

@ -961,17 +961,17 @@ static int ad9523_probe(struct spi_device *spi)
return -EINVAL;
}
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
}
spi_set_drvdata(spi, indio_dev);
@ -1001,11 +1001,6 @@ static int ad9523_probe(struct spi_device *spi)
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
regulator_put(st->reg);
iio_device_free(indio_dev);
return ret;
}
@ -1017,12 +1012,8 @@ static int ad9523_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
if (!IS_ERR(st->reg)) {
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}

View File

@ -515,7 +515,7 @@ static int adf4350_probe(struct spi_device *spi)
}
if (!pdata->clkin) {
clk = clk_get(&spi->dev, "clkin");
clk = devm_clk_get(&spi->dev, "clkin");
if (IS_ERR(clk))
return -EPROBE_DEFER;
@ -524,17 +524,17 @@ static int adf4350_probe(struct spi_device *spi)
return ret;
}
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
goto error_disable_clk;
}
spi_set_drvdata(spi, indio_dev);
@ -564,7 +564,8 @@ static int adf4350_probe(struct spi_device *spi)
memset(st->regs_hw, 0xFF, sizeof(st->regs_hw));
if (gpio_is_valid(pdata->gpio_lock_detect)) {
ret = gpio_request(pdata->gpio_lock_detect, indio_dev->name);
ret = devm_gpio_request(&spi->dev, pdata->gpio_lock_detect,
indio_dev->name);
if (ret) {
dev_err(&spi->dev, "fail to request lock detect GPIO-%d",
pdata->gpio_lock_detect);
@ -576,29 +577,21 @@ static int adf4350_probe(struct spi_device *spi)
if (pdata->power_up_frequency) {
ret = adf4350_set_freq(st, pdata->power_up_frequency);
if (ret)
goto error_free_gpio;
goto error_disable_reg;
}
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_gpio;
goto error_disable_reg;
return 0;
error_free_gpio:
if (gpio_is_valid(pdata->gpio_lock_detect))
gpio_free(pdata->gpio_lock_detect);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
regulator_put(st->reg);
error_disable_clk:
if (clk)
clk_disable_unprepare(clk);
iio_device_free(indio_dev);
return ret;
}
@ -619,14 +612,8 @@ static int adf4350_remove(struct spi_device *spi)
if (!IS_ERR(reg)) {
regulator_disable(reg);
regulator_put(reg);
}
if (gpio_is_valid(st->pdata->gpio_lock_detect))
gpio_free(st->pdata->gpio_lock_detect);
iio_device_free(indio_dev);
return 0;
}

View File

@ -1,6 +1,8 @@
#
# IIO Digital Gyroscope Sensor drivers configuration
#
# When adding new entries keep the list in alphabetical order
menu "Digital gyroscope sensors"
config ADIS16080
@ -26,6 +28,18 @@ config ADIS16136
Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
ADIS16136 gyroscope devices.
config ADIS16260
tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
depends on SPI
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices ADIS16260 ADIS16265
ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
This driver can also be built as a module. If so, the module
will be called adis16260.
config ADXRS450
tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
depends on SPI
@ -58,8 +72,8 @@ config IIO_ST_GYRO_3AXIS
Say yes here to build support for STMicroelectronics gyroscopes:
L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
This driver can also be built as a module. If so, will be created
these modules:
This driver can also be built as a module. If so, these modules
will be created:
- st_gyro (core functions for the driver [it is mandatory]);
- st_gyro_i2c (necessary for the I2C devices [optional*]);
- st_gyro_spi (necessary for the SPI devices [optional*]);

View File

@ -2,9 +2,11 @@
# Makefile for industrial I/O gyroscope sensor drivers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ADIS16080) += adis16080.o
obj-$(CONFIG_ADIS16130) += adis16130.o
obj-$(CONFIG_ADIS16136) += adis16136.o
obj-$(CONFIG_ADIS16260) += adis16260.o
obj-$(CONFIG_ADXRS450) += adxrs450.o
obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o

View File

@ -7,54 +7,119 @@
*/
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/imu/adis.h>
#include "adis16260.h"
#define ADIS16260_STARTUP_DELAY 220 /* ms */
static ssize_t adis16260_read_frequency_available(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16260_state *st = iio_priv(indio_dev);
if (spi_get_device_id(st->adis.spi)->driver_data)
return sprintf(buf, "%s\n", "0.129 ~ 256");
else
return sprintf(buf, "%s\n", "256 2048");
}
#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */
#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */
#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */
#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */
#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */
#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */
#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */
#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */
#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */
#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */
#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */
#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */
#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */
#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */
#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */
#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */
#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */
#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */
#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */
#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */
#define ADIS16260_PROD_ID 0x56 /* Product identifier;
* convert to decimal = 16,265/16,260 */
#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
#define ADIS16260_ERROR_ACTIVE (1<<14)
#define ADIS16260_NEW_DATA (1<<15)
/* MSC_CTRL */
#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11)
/* Internal self-test enable */
#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10)
#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9)
#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8)
#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2)
#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
/* SMPL_PRD */
/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7)
#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F
/* SLP_CNT */
#define ADIS16260_SLP_CNT_POWER_OFF 0x80
/* DIAG_STAT */
#define ADIS16260_DIAG_STAT_ALARM2 (1<<9)
#define ADIS16260_DIAG_STAT_ALARM1 (1<<8)
#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6
#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5
#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4
#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3
#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2
#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1
#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */
#define ADIS16260_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3)
#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2)
#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1)
#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0)
#define ADIS16260_SPI_SLOW (u32)(300 * 1000)
#define ADIS16260_SPI_BURST (u32)(1000 * 1000)
#define ADIS16260_SPI_FAST (u32)(2000 * 1000)
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
#define ADIS16260_SCAN_GYRO 0
#define ADIS16260_SCAN_SUPPLY 1
#define ADIS16260_SCAN_AUX_ADC 2
#define ADIS16260_SCAN_TEMP 3
#define ADIS16260_SCAN_ANGL 4
static ssize_t adis16260_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16260_state *st = iio_priv(indio_dev);
struct adis *adis = iio_priv(indio_dev);
int ret, len = 0;
u16 t;
int sps;
ret = adis_read_reg_16(&st->adis, ADIS16260_SMPL_PRD, &t);
ret = adis_read_reg_16(adis, ADIS16260_SMPL_PRD, &t);
if (ret)
return ret;
if (spi_get_device_id(st->adis.spi)->driver_data) /* If an adis16251 */
sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
if (spi_get_device_id(adis->spi)->driver_data) /* If an adis16251 */
sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
else
sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
len = sprintf(buf, "%d SPS\n", sps);
len = sprintf(buf, "%d\n", sps);
return len;
}
@ -64,36 +129,31 @@ static ssize_t adis16260_write_frequency(struct device *dev,
size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct adis16260_state *st = iio_priv(indio_dev);
long val;
struct adis *adis = iio_priv(indio_dev);
unsigned int val;
int ret;
u8 t;
ret = strict_strtol(buf, 10, &val);
ret = kstrtouint(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
return -EINVAL;
mutex_lock(&indio_dev->mlock);
if (spi_get_device_id(st->adis.spi)->driver_data) {
t = (256 / val);
if (t > 0)
t--;
t &= ADIS16260_SMPL_PRD_DIV_MASK;
} else {
t = (2048 / val);
if (t > 0)
t--;
t &= ADIS16260_SMPL_PRD_DIV_MASK;
}
if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A)
st->adis.spi->max_speed_hz = ADIS16260_SPI_SLOW;
if (spi_get_device_id(adis->spi)->driver_data)
t = 256 / val;
else
st->adis.spi->max_speed_hz = ADIS16260_SPI_FAST;
ret = adis_write_reg_8(&st->adis,
ADIS16260_SMPL_PRD,
t);
t = 2048 / val;
if (t > ADIS16260_SMPL_PRD_DIV_MASK)
t = ADIS16260_SMPL_PRD_DIV_MASK;
else if (t > 0)
t--;
if (t >= 0x0A)
adis->spi->max_speed_hz = ADIS16260_SPI_SLOW;
else
adis->spi->max_speed_hz = ADIS16260_SPI_FAST;
ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
mutex_unlock(&indio_dev->mlock);
@ -103,11 +163,11 @@ static ssize_t adis16260_write_frequency(struct device *dev,
/* Power down the device */
static int adis16260_stop_device(struct iio_dev *indio_dev)
{
struct adis16260_state *st = iio_priv(indio_dev);
struct adis *adis = iio_priv(indio_dev);
int ret;
u16 val = ADIS16260_SLP_CNT_POWER_OFF;
ret = adis_write_reg_16(&st->adis, ADIS16260_SLP_CNT, val);
ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val);
if (ret)
dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
@ -118,24 +178,16 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
adis16260_read_frequency,
adis16260_write_frequency);
static IIO_DEVICE_ATTR(sampling_frequency_available,
S_IRUGO, adis16260_read_frequency_available, NULL, 0);
#define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \
struct iio_chan_spec adis16260_channels_##axis[] = { \
ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \
BIT(IIO_CHAN_INFO_CALIBBIAS) | \
BIT(IIO_CHAN_INFO_CALIBSCALE), 14), \
ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \
ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \
ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \
ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), \
IIO_CHAN_SOFT_TIMESTAMP(5), \
}
static const ADIS16260_GYRO_CHANNEL_SET(x, X);
static const ADIS16260_GYRO_CHANNEL_SET(y, Y);
static const ADIS16260_GYRO_CHANNEL_SET(z, Z);
static const struct iio_chan_spec adis16260_channels[] = {
ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_CALIBSCALE), 14),
ADIS_INCLI_CHAN(X, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14),
ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12),
ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12),
ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
static const u8 adis16260_addresses[][2] = {
[ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
@ -146,9 +198,8 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
struct adis16260_state *st = iio_priv(indio_dev);
struct adis *adis = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
s16 val16;
@ -160,7 +211,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
switch (chan->type) {
case IIO_ANGL_VEL:
*val = 0;
if (spi_get_device_id(st->adis.spi)->driver_data) {
if (spi_get_device_id(adis->spi)->driver_data) {
/* 0.01832 degree / sec */
*val2 = IIO_DEGREE_TO_RAD(18320);
} else {
@ -168,6 +219,10 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
*val2 = IIO_DEGREE_TO_RAD(73260);
}
return IIO_VAL_INT_PLUS_MICRO;
case IIO_INCLI:
*val = 0;
*val2 = IIO_DEGREE_TO_RAD(36630);
return IIO_VAL_INT_PLUS_MICRO;
case IIO_VOLTAGE:
if (chan->channel == 0) {
*val = 1;
@ -189,42 +244,20 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
*val = 250000 / 1453; /* 25 C = 0x00 */
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBBIAS:
switch (chan->type) {
case IIO_ANGL_VEL:
bits = 12;
break;
default:
return -EINVAL;
}
mutex_lock(&indio_dev->mlock);
addr = adis16260_addresses[chan->scan_index][0];
ret = adis_read_reg_16(&st->adis, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
ret = adis_read_reg_16(adis, addr, &val16);
if (ret)
return ret;
}
val16 &= (1 << bits) - 1;
val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
*val = val16;
mutex_unlock(&indio_dev->mlock);
*val = sign_extend32(val16, 11);
return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBSCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
bits = 12;
break;
default:
return -EINVAL;
}
mutex_lock(&indio_dev->mlock);
addr = adis16260_addresses[chan->scan_index][1];
ret = adis_read_reg_16(&st->adis, addr, &val16);
if (ret) {
mutex_unlock(&indio_dev->mlock);
ret = adis_read_reg_16(adis, addr, &val16);
if (ret)
return ret;
}
*val = (1 << bits) - 1;
mutex_unlock(&indio_dev->mlock);
*val = val16;
return IIO_VAL_INT;
}
return -EINVAL;
@ -236,26 +269,28 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
struct adis16260_state *st = iio_priv(indio_dev);
int bits = 12;
s16 val16;
struct adis *adis = iio_priv(indio_dev);
u8 addr;
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
val16 = val & ((1 << bits) - 1);
if (val < -2048 || val >= 2048)
return -EINVAL;
addr = adis16260_addresses[chan->scan_index][0];
return adis_write_reg_16(&st->adis, addr, val16);
return adis_write_reg_16(adis, addr, val);
case IIO_CHAN_INFO_CALIBSCALE:
val16 = val & ((1 << bits) - 1);
if (val < 0 || val >= 4096)
return -EINVAL;
addr = adis16260_addresses[chan->scan_index][1];
return adis_write_reg_16(&st->adis, addr, val16);
return adis_write_reg_16(adis, addr, val);
}
return -EINVAL;
}
static struct attribute *adis16260_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
@ -303,71 +338,37 @@ static const struct adis_data adis16260_data = {
static int adis16260_probe(struct spi_device *spi)
{
int ret;
struct adis16260_platform_data *pd = spi->dev.platform_data;
struct adis16260_state *st;
struct iio_dev *indio_dev;
struct adis *adis;
int ret;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = iio_device_alloc(sizeof(*adis));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
st = iio_priv(indio_dev);
if (pd)
st->negate = pd->negate;
adis = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16260_info;
indio_dev->num_channels
= ARRAY_SIZE(adis16260_channels_x);
if (pd && pd->direction)
switch (pd->direction) {
case 'x':
indio_dev->channels = adis16260_channels_x;
break;
case 'y':
indio_dev->channels = adis16260_channels_y;
break;
case 'z':
indio_dev->channels = adis16260_channels_z;
break;
default:
return -EINVAL;
}
else
indio_dev->channels = adis16260_channels_x;
indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x);
indio_dev->channels = adis16260_channels;
indio_dev->num_channels = ARRAY_SIZE(adis16260_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
ret = adis_init(&st->adis, indio_dev, spi, &adis16260_data);
ret = adis_init(adis, indio_dev, spi, &adis16260_data);
if (ret)
goto error_free_dev;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
if (indio_dev->buffer) {
/* Set default scan mode */
iio_scan_mask_set(indio_dev, indio_dev->buffer,
ADIS16260_SCAN_SUPPLY);
iio_scan_mask_set(indio_dev, indio_dev->buffer,
ADIS16260_SCAN_GYRO);
iio_scan_mask_set(indio_dev, indio_dev->buffer,
ADIS16260_SCAN_AUX_ADC);
iio_scan_mask_set(indio_dev, indio_dev->buffer,
ADIS16260_SCAN_TEMP);
iio_scan_mask_set(indio_dev, indio_dev->buffer,
ADIS16260_SCAN_ANGL);
}
/* Get the device into a sane initial state */
ret = adis_initial_startup(&st->adis);
ret = adis_initial_startup(adis);
if (ret)
goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
@ -377,7 +378,7 @@ static int adis16260_probe(struct spi_device *spi)
return 0;
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
adis_cleanup_buffer_and_trigger(adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
@ -387,11 +388,11 @@ error_ret:
static int adis16260_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adis16260_state *st = iio_priv(indio_dev);
struct adis *adis = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis16260_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
adis_cleanup_buffer_and_trigger(adis, indio_dev);
iio_device_free(indio_dev);
return 0;

View File

@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
/*Format: HID-SENSOR-usage_id_in_hex*/
/*Usage ID from spec for Gyro-3D: 0x200076*/
#define DRIVER_NAME "HID-SENSOR-200076"
enum gyro_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
@ -389,9 +385,19 @@ static int hid_gyro_3d_remove(struct platform_device *pdev)
return 0;
}
static struct platform_device_id hid_gyro_3d_ids[] = {
{
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-200076",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_gyro_3d_ids);
static struct platform_driver hid_gyro_3d_platform_driver = {
.id_table = hid_gyro_3d_ids,
.driver = {
.name = DRIVER_NAME,
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_gyro_3d_probe,

View File

@ -23,7 +23,16 @@
#define L3G4IS_GYRO_DEV_NAME "l3g4is_ui"
#define LSM330_GYRO_DEV_NAME "lsm330_gyro"
int st_gyro_common_probe(struct iio_dev *indio_dev);
/**
* struct st_sensors_platform_data - gyro platform data
* @drdy_int_pin: DRDY on gyros is available only on INT2 pin.
*/
static const struct st_sensors_platform_data gyro_pdata = {
.drdy_int_pin = 2,
};
int st_gyro_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata);
void st_gyro_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER

View File

@ -60,7 +60,7 @@
#define ST_GYRO_1_BDU_ADDR 0x23
#define ST_GYRO_1_BDU_MASK 0x80
#define ST_GYRO_1_DRDY_IRQ_ADDR 0x22
#define ST_GYRO_1_DRDY_IRQ_MASK 0x08
#define ST_GYRO_1_DRDY_IRQ_INT2_MASK 0x08
#define ST_GYRO_1_MULTIREAD_BIT true
/* CUSTOM VALUES FOR SENSOR 2 */
@ -84,7 +84,7 @@
#define ST_GYRO_2_BDU_ADDR 0x23
#define ST_GYRO_2_BDU_MASK 0x80
#define ST_GYRO_2_DRDY_IRQ_ADDR 0x22
#define ST_GYRO_2_DRDY_IRQ_MASK 0x08
#define ST_GYRO_2_DRDY_IRQ_INT2_MASK 0x08
#define ST_GYRO_2_MULTIREAD_BIT true
static const struct iio_chan_spec st_gyro_16bit_channels[] = {
@ -158,7 +158,7 @@ static const struct st_sensors st_gyro_sensors[] = {
},
.drdy_irq = {
.addr = ST_GYRO_1_DRDY_IRQ_ADDR,
.mask = ST_GYRO_1_DRDY_IRQ_MASK,
.mask_int2 = ST_GYRO_1_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
.bootime = 2,
@ -221,7 +221,7 @@ static const struct st_sensors st_gyro_sensors[] = {
},
.drdy_irq = {
.addr = ST_GYRO_2_DRDY_IRQ_ADDR,
.mask = ST_GYRO_2_DRDY_IRQ_MASK,
.mask_int2 = ST_GYRO_2_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
.bootime = 2,
@ -302,7 +302,8 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
#define ST_GYRO_TRIGGER_OPS NULL
#endif
int st_gyro_common_probe(struct iio_dev *indio_dev)
int st_gyro_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *gdata = iio_priv(indio_dev);
@ -324,7 +325,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
&gdata->sensor->fs.fs_avl[0];
gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
err = st_sensors_init_sensor(indio_dev);
err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)
goto st_gyro_common_probe_error;

View File

@ -36,7 +36,8 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
st_sensors_i2c_configure(indio_dev, client, gdata);
err = st_gyro_common_probe(indio_dev);
err = st_gyro_common_probe(indio_dev,
(struct st_sensors_platform_data *)&gyro_pdata);
if (err < 0)
goto st_gyro_common_probe_error;

View File

@ -35,7 +35,8 @@ static int st_gyro_spi_probe(struct spi_device *spi)
st_sensors_spi_configure(indio_dev, spi, gdata);
err = st_gyro_common_probe(indio_dev);
err = st_gyro_common_probe(indio_dev,
(struct st_sensors_platform_data *)&gyro_pdata);
if (err < 0)
goto st_gyro_common_probe_error;

View File

@ -30,7 +30,7 @@ void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev);
static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
{
return 0;
};
}
/**
* iio_device_unregister_trigger_consumer() - reverse the registration process
@ -38,9 +38,6 @@ static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
**/
static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev)
{
};
}
#endif /* CONFIG_TRIGGER_CONSUMER */

View File

@ -1,6 +1,8 @@
#
# IIO imu drivers configuration
#
# When adding new entries keep the list in alphabetical order
menu "Inertial measurement units"
config ADIS16400

View File

@ -2,6 +2,7 @@
# Makefile for Inertial Measurement Units
#
# When adding new entries keep the list in alphabetical order
adis16400-y := adis16400_core.o
adis16400-$(CONFIG_IIO_BUFFER) += adis16400_buffer.o
obj-$(CONFIG_ADIS16400) += adis16400.o

View File

@ -871,7 +871,7 @@ static int adis16400_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -893,12 +893,12 @@ static int adis16400_probe(struct spi_device *spi)
ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
if (ret)
goto error_free_dev;
return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
adis16400_trigger_handler);
if (ret)
goto error_free_dev;
return ret;
/* Get the device into a sane initial state */
ret = adis16400_initial_setup(indio_dev);
@ -913,8 +913,6 @@ static int adis16400_probe(struct spi_device *spi)
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
return ret;
}
@ -928,8 +926,6 @@ static int adis16400_remove(struct spi_device *spi)
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -839,7 +839,7 @@ static int adis16480_probe(struct spi_device *spi)
struct adis16480 *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -857,11 +857,11 @@ static int adis16480_probe(struct spi_device *spi)
ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
if (ret)
goto error_free_dev;
return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
return ret;
ret = adis16480_initial_setup(indio_dev);
if (ret)
@ -879,8 +879,6 @@ error_stop_device:
adis16480_stop_device(indio_dev);
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
return ret;
}
@ -894,8 +892,6 @@ static int adis16480_remove(struct spi_device *spi)
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/spinlock.h>
#include <linux/iio/iio.h>
#include "inv_mpu_iio.h"
/*
@ -663,16 +664,13 @@ static int inv_mpu_probe(struct i2c_client *client,
int result;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK |
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
result = -ENOSYS;
goto out_no_free;
}
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
result = -ENOMEM;
goto out_no_free;
}
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENOSYS;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->client = client;
st->plat_data = *(struct inv_mpu6050_platform_data
@ -680,13 +678,13 @@ static int inv_mpu_probe(struct i2c_client *client,
/* power is turned on inside check chip type*/
result = inv_check_and_setup_chip(st, id);
if (result)
goto out_free;
return result;
result = inv_mpu6050_init_config(indio_dev);
if (result) {
dev_err(&client->dev,
"Could not initialize device.\n");
goto out_free;
return result;
}
i2c_set_clientdata(client, indio_dev);
@ -705,7 +703,7 @@ static int inv_mpu_probe(struct i2c_client *client,
if (result) {
dev_err(&st->client->dev, "configure buffer fail %d\n",
result);
goto out_free;
return result;
}
result = inv_mpu6050_probe_trigger(indio_dev);
if (result) {
@ -727,10 +725,6 @@ out_remove_trigger:
inv_mpu6050_remove_trigger(st);
out_unreg_ring:
iio_triggered_buffer_cleanup(indio_dev);
out_free:
iio_device_free(indio_dev);
out_no_free:
return result;
}
@ -742,7 +736,6 @@ static int inv_mpu_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
inv_mpu6050_remove_trigger(st);
iio_triggered_buffer_cleanup(indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -383,14 +383,14 @@ static ssize_t iio_read_channel_info(struct device *dev,
scale_db = true;
case IIO_VAL_INT_PLUS_MICRO:
if (val2 < 0)
return sprintf(buf, "-%d.%06u%s\n", val, -val2,
return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2,
scale_db ? " dB" : "");
else
return sprintf(buf, "%d.%06u%s\n", val, val2,
scale_db ? " dB" : "");
case IIO_VAL_INT_PLUS_NANO:
if (val2 < 0)
return sprintf(buf, "-%d.%09u\n", val, -val2);
return sprintf(buf, "-%ld.%09u\n", abs(val), -val2);
else
return sprintf(buf, "%d.%09u\n", val, val2);
case IIO_VAL_FRACTIONAL:
@ -912,6 +912,53 @@ void iio_device_free(struct iio_dev *dev)
}
EXPORT_SYMBOL(iio_device_free);
static void devm_iio_device_release(struct device *dev, void *res)
{
iio_device_free(*(struct iio_dev **)res);
}
static int devm_iio_device_match(struct device *dev, void *res, void *data)
{
struct iio_dev **r = res;
if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}
return *r == data;
}
struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
{
struct iio_dev **ptr, *iio_dev;
ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return NULL;
/* use raw alloc_dr for kmalloc caller tracing */
iio_dev = iio_device_alloc(sizeof_priv);
if (iio_dev) {
*ptr = iio_dev;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return iio_dev;
}
EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
{
int rc;
rc = devres_release(dev, devm_iio_device_release,
devm_iio_device_match, iio_dev);
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_iio_device_free);
/**
* iio_chrdev_open() - chrdev file open for buffer access and ioctls
**/

View File

@ -1,6 +1,8 @@
#
# Light sensors
#
# When adding new entries keep the list in alphabetical order
menu "Light sensors"
config ADJD_S311
@ -15,6 +17,27 @@ config ADJD_S311
This driver can also be built as a module. If so, the module
will be called adjd_s311.
config APDS9300
tristate "APDS9300 ambient light sensor"
depends on I2C
help
Say Y here if you want to build a driver for the Avago APDS9300
ambient light sensor.
To compile this driver as a module, choose M here: the
module will be called apds9300.
config HID_SENSOR_ALS
depends on HID_SENSOR_HUB
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select HID_SENSOR_IIO_COMMON
select HID_SENSOR_IIO_TRIGGER
tristate "HID ALS"
help
Say yes here to build support for the HID SENSOR
Ambient light sensor.
config SENSORS_LM3533
tristate "LM3533 ambient light sensor"
depends on MFD_LM3533
@ -52,15 +75,4 @@ config VCNL4000
To compile this driver as a module, choose M here: the
module will be called vcnl4000.
config HID_SENSOR_ALS
depends on HID_SENSOR_HUB
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select HID_SENSOR_IIO_COMMON
select HID_SENSOR_IIO_TRIGGER
tristate "HID ALS"
help
Say yes here to build support for the HID SENSOR
Ambient light sensor.
endmenu

View File

@ -2,8 +2,10 @@
# Makefile for IIO Light sensors
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
obj-$(CONFIG_APDS9300) += apds9300.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_VCNL4000) += vcnl4000.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o

View File

@ -293,11 +293,10 @@ static int adjd_s311_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int err;
indio_dev = iio_device_alloc(sizeof(*data));
if (indio_dev == NULL) {
err = -ENOMEM;
goto exit;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (indio_dev == NULL)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
@ -312,7 +311,7 @@ static int adjd_s311_probe(struct i2c_client *client,
err = iio_triggered_buffer_setup(indio_dev, NULL,
adjd_s311_trigger_handler, NULL);
if (err < 0)
goto exit_free_device;
return err;
err = iio_device_register(indio_dev);
if (err)
@ -324,9 +323,6 @@ static int adjd_s311_probe(struct i2c_client *client,
exit_unreg_buffer:
iio_triggered_buffer_cleanup(indio_dev);
exit_free_device:
iio_device_free(indio_dev);
exit:
return err;
}
@ -338,7 +334,6 @@ static int adjd_s311_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(data->buffer);
iio_device_free(indio_dev);
return 0;
}

View File

@ -0,0 +1,512 @@
/*
* apds9300.c - IIO driver for Avago APDS9300 ambient light sensor
*
* Copyright 2013 Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#define APDS9300_DRV_NAME "apds9300"
#define APDS9300_IRQ_NAME "apds9300_event"
/* Command register bits */
#define APDS9300_CMD BIT(7) /* Select command register. Must write as 1 */
#define APDS9300_WORD BIT(5) /* I2C write/read: if 1 word, if 0 byte */
#define APDS9300_CLEAR BIT(6) /* Interrupt clear. Clears pending interrupt */
/* Register set */
#define APDS9300_CONTROL 0x00 /* Control of basic functions */
#define APDS9300_THRESHLOWLOW 0x02 /* Low byte of low interrupt threshold */
#define APDS9300_THRESHHIGHLOW 0x04 /* Low byte of high interrupt threshold */
#define APDS9300_INTERRUPT 0x06 /* Interrupt control */
#define APDS9300_DATA0LOW 0x0c /* Low byte of ADC channel 0 */
#define APDS9300_DATA1LOW 0x0e /* Low byte of ADC channel 1 */
/* Power on/off value for APDS9300_CONTROL register */
#define APDS9300_POWER_ON 0x03
#define APDS9300_POWER_OFF 0x00
/* Interrupts */
#define APDS9300_INTR_ENABLE 0x10
/* Interrupt Persist Function: Any value outside of threshold range */
#define APDS9300_THRESH_INTR 0x01
#define APDS9300_THRESH_MAX 0xffff /* Max threshold value */
struct apds9300_data {
struct i2c_client *client;
struct mutex mutex;
int power_state;
int thresh_low;
int thresh_hi;
int intr_en;
};
/* Lux calculation */
/* Calculated values 1000 * (CH1/CH0)^1.4 for CH1/CH0 from 0 to 0.52 */
static const u16 apds9300_lux_ratio[] = {
0, 2, 4, 7, 11, 15, 19, 24, 29, 34, 40, 45, 51, 57, 64, 70, 77, 84, 91,
98, 105, 112, 120, 128, 136, 144, 152, 160, 168, 177, 185, 194, 203,
212, 221, 230, 239, 249, 258, 268, 277, 287, 297, 307, 317, 327, 337,
347, 358, 368, 379, 390, 400,
};
static unsigned long apds9300_calculate_lux(u16 ch0, u16 ch1)
{
unsigned long lux, tmp;
/* avoid division by zero */
if (ch0 == 0)
return 0;
tmp = DIV_ROUND_UP(ch1 * 100, ch0);
if (tmp <= 52) {
lux = 3150 * ch0 - (unsigned long)DIV_ROUND_UP_ULL(ch0
* apds9300_lux_ratio[tmp] * 5930ull, 1000);
} else if (tmp <= 65) {
lux = 2290 * ch0 - 2910 * ch1;
} else if (tmp <= 80) {
lux = 1570 * ch0 - 1800 * ch1;
} else if (tmp <= 130) {
lux = 338 * ch0 - 260 * ch1;
} else {
lux = 0;
}
return lux / 100000;
}
static int apds9300_get_adc_val(struct apds9300_data *data, int adc_number)
{
int ret;
u8 flags = APDS9300_CMD | APDS9300_WORD;
if (!data->power_state)
return -EBUSY;
/* Select ADC0 or ADC1 data register */
flags |= adc_number ? APDS9300_DATA1LOW : APDS9300_DATA0LOW;
ret = i2c_smbus_read_word_data(data->client, flags);
if (ret < 0)
dev_err(&data->client->dev,
"failed to read ADC%d value\n", adc_number);
return ret;
}
static int apds9300_set_thresh_low(struct apds9300_data *data, int value)
{
int ret;
if (!data->power_state)
return -EBUSY;
if (value > APDS9300_THRESH_MAX)
return -EINVAL;
ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHLOWLOW
| APDS9300_CMD | APDS9300_WORD, value);
if (ret) {
dev_err(&data->client->dev, "failed to set thresh_low\n");
return ret;
}
data->thresh_low = value;
return 0;
}
static int apds9300_set_thresh_hi(struct apds9300_data *data, int value)
{
int ret;
if (!data->power_state)
return -EBUSY;
if (value > APDS9300_THRESH_MAX)
return -EINVAL;
ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHHIGHLOW
| APDS9300_CMD | APDS9300_WORD, value);
if (ret) {
dev_err(&data->client->dev, "failed to set thresh_hi\n");
return ret;
}
data->thresh_hi = value;
return 0;
}
static int apds9300_set_intr_state(struct apds9300_data *data, int state)
{
int ret;
u8 cmd;
if (!data->power_state)
return -EBUSY;
cmd = state ? APDS9300_INTR_ENABLE | APDS9300_THRESH_INTR : 0x00;
ret = i2c_smbus_write_byte_data(data->client,
APDS9300_INTERRUPT | APDS9300_CMD, cmd);
if (ret) {
dev_err(&data->client->dev,
"failed to set interrupt state %d\n", state);
return ret;
}
data->intr_en = state;
return 0;
}
static int apds9300_set_power_state(struct apds9300_data *data, int state)
{
int ret;
u8 cmd;
cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF;
ret = i2c_smbus_write_byte_data(data->client,
APDS9300_CONTROL | APDS9300_CMD, cmd);
if (ret) {
dev_err(&data->client->dev,
"failed to set power state %d\n", state);
return ret;
}
data->power_state = state;
return 0;
}
static void apds9300_clear_intr(struct apds9300_data *data)
{
int ret;
ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD);
if (ret < 0)
dev_err(&data->client->dev, "failed to clear interrupt\n");
}
static int apds9300_chip_init(struct apds9300_data *data)
{
int ret;
/* Need to set power off to ensure that the chip is off */
ret = apds9300_set_power_state(data, 0);
if (ret < 0)
goto err;
/*
* Probe the chip. To do so we try to power up the device and then to
* read back the 0x03 code
*/
ret = apds9300_set_power_state(data, 1);
if (ret < 0)
goto err;
ret = i2c_smbus_read_byte_data(data->client,
APDS9300_CONTROL | APDS9300_CMD);
if (ret != APDS9300_POWER_ON) {
ret = -ENODEV;
goto err;
}
/*
* Disable interrupt to ensure thai it is doesn't enable
* i.e. after device soft reset
*/
ret = apds9300_set_intr_state(data, 0);
if (ret < 0)
goto err;
return 0;
err:
dev_err(&data->client->dev, "failed to init the chip\n");
return ret;
}
static int apds9300_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask)
{
int ch0, ch1, ret = -EINVAL;
struct apds9300_data *data = iio_priv(indio_dev);
mutex_lock(&data->mutex);
switch (chan->type) {
case IIO_LIGHT:
ch0 = apds9300_get_adc_val(data, 0);
if (ch0 < 0) {
ret = ch0;
break;
}
ch1 = apds9300_get_adc_val(data, 1);
if (ch1 < 0) {
ret = ch1;
break;
}
*val = apds9300_calculate_lux(ch0, ch1);
ret = IIO_VAL_INT;
break;
case IIO_INTENSITY:
ret = apds9300_get_adc_val(data, chan->channel);
if (ret < 0)
break;
*val = ret;
ret = IIO_VAL_INT;
break;
default:
break;
}
mutex_unlock(&data->mutex);
return ret;
}
static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
int *val)
{
struct apds9300_data *data = iio_priv(indio_dev);
switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
case IIO_EV_DIR_RISING:
*val = data->thresh_hi;
break;
case IIO_EV_DIR_FALLING:
*val = data->thresh_low;
break;
default:
return -EINVAL;
}
return 0;
}
static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
int val)
{
struct apds9300_data *data = iio_priv(indio_dev);
int ret;
mutex_lock(&data->mutex);
if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
ret = apds9300_set_thresh_hi(data, val);
else
ret = apds9300_set_thresh_low(data, val);
mutex_unlock(&data->mutex);
return ret;
}
static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
u64 event_code)
{
struct apds9300_data *data = iio_priv(indio_dev);
return data->intr_en;
}
static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
u64 event_code, int state)
{
struct apds9300_data *data = iio_priv(indio_dev);
int ret;
mutex_lock(&data->mutex);
ret = apds9300_set_intr_state(data, state);
mutex_unlock(&data->mutex);
return ret;
}
static const struct iio_info apds9300_info_no_irq = {
.driver_module = THIS_MODULE,
.read_raw = apds9300_read_raw,
};
static const struct iio_info apds9300_info = {
.driver_module = THIS_MODULE,
.read_raw = apds9300_read_raw,
.read_event_value = apds9300_read_thresh,
.write_event_value = apds9300_write_thresh,
.read_event_config = apds9300_read_interrupt_config,
.write_event_config = apds9300_write_interrupt_config,
};
static const struct iio_chan_spec apds9300_channels[] = {
{
.type = IIO_LIGHT,
.channel = 0,
.indexed = true,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
}, {
.type = IIO_INTENSITY,
.channel = 0,
.channel2 = IIO_MOD_LIGHT_BOTH,
.indexed = true,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
IIO_EV_DIR_RISING) |
IIO_EV_BIT(IIO_EV_TYPE_THRESH,
IIO_EV_DIR_FALLING)),
}, {
.type = IIO_INTENSITY,
.channel = 1,
.channel2 = IIO_MOD_LIGHT_IR,
.indexed = true,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
},
};
static irqreturn_t apds9300_interrupt_handler(int irq, void *private)
{
struct iio_dev *dev_info = private;
struct apds9300_data *data = iio_priv(dev_info);
iio_push_event(dev_info,
IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_EITHER),
iio_get_time_ns());
apds9300_clear_intr(data);
return IRQ_HANDLED;
}
static int apds9300_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct apds9300_data *data;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
ret = apds9300_chip_init(data);
if (ret < 0)
goto err;
mutex_init(&data->mutex);
indio_dev->dev.parent = &client->dev;
indio_dev->channels = apds9300_channels;
indio_dev->num_channels = ARRAY_SIZE(apds9300_channels);
indio_dev->name = APDS9300_DRV_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
if (client->irq)
indio_dev->info = &apds9300_info;
else
indio_dev->info = &apds9300_info_no_irq;
if (client->irq) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL, apds9300_interrupt_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
APDS9300_IRQ_NAME, indio_dev);
if (ret) {
dev_err(&client->dev, "irq request error %d\n", -ret);
goto err;
}
}
ret = iio_device_register(indio_dev);
if (ret < 0)
goto err;
return 0;
err:
/* Ensure that power off in case of error */
apds9300_set_power_state(data, 0);
return ret;
}
static int apds9300_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct apds9300_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
/* Ensure that power off and interrupts are disabled */
apds9300_set_intr_state(data, 0);
apds9300_set_power_state(data, 0);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int apds9300_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct apds9300_data *data = iio_priv(indio_dev);
int ret;
mutex_lock(&data->mutex);
ret = apds9300_set_power_state(data, 0);
mutex_unlock(&data->mutex);
return ret;
}
static int apds9300_resume(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct apds9300_data *data = iio_priv(indio_dev);
int ret;
mutex_lock(&data->mutex);
ret = apds9300_set_power_state(data, 1);
mutex_unlock(&data->mutex);
return ret;
}
static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume);
#define APDS9300_PM_OPS (&apds9300_pm_ops)
#else
#define APDS9300_PM_OPS NULL
#endif
static struct i2c_device_id apds9300_id[] = {
{ APDS9300_DRV_NAME, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, apds9300_id);
static struct i2c_driver apds9300_driver = {
.driver = {
.name = APDS9300_DRV_NAME,
.owner = THIS_MODULE,
.pm = APDS9300_PM_OPS,
},
.probe = apds9300_probe,
.remove = apds9300_remove,
.id_table = apds9300_id,
};
module_i2c_driver(apds9300_driver);
MODULE_AUTHOR("Kravchenko Oleksandr <o.v.kravchenko@globallogic.com>");
MODULE_AUTHOR("GlobalLogic inc.");
MODULE_DESCRIPTION("APDS9300 ambient light photo sensor driver");
MODULE_LICENSE("GPL");

View File

@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
/*Format: HID-SENSOR-usage_id_in_hex*/
/*Usage ID from spec for Ambiant-Light: 0x200041*/
#define DRIVER_NAME "HID-SENSOR-200041"
#define CHANNEL_SCAN_INDEX_ILLUM 0
struct als_state {
@ -253,11 +249,9 @@ static int hid_als_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
indio_dev = iio_device_alloc(sizeof(struct als_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state));
if (!indio_dev)
return -ENOMEM;
platform_set_drvdata(pdev, indio_dev);
als_state = iio_priv(indio_dev);
@ -268,14 +262,13 @@ static int hid_als_probe(struct platform_device *pdev)
&als_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
goto error_free_dev;
return ret;
}
channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
return -ENOMEM;
}
ret = als_parse_report(pdev, hsdev, channels,
@ -333,9 +326,6 @@ error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
@ -350,14 +340,23 @@ static int hid_als_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
iio_device_free(indio_dev);
return 0;
}
static struct platform_device_id hid_als_ids[] = {
{
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-200041",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_als_ids);
static struct platform_driver hid_als_platform_driver = {
.id_table = hid_als_ids,
.driver = {
.name = DRIVER_NAME,
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_als_probe,

View File

@ -847,7 +847,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
return -EINVAL;
}
indio_dev = iio_device_alloc(sizeof(*als));
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
if (!indio_dev)
return -ENOMEM;
@ -870,7 +870,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
if (als->irq) {
ret = lm3533_als_setup_irq(als, indio_dev);
if (ret)
goto err_free_dev;
return ret;
}
ret = lm3533_als_setup(als, pdata);
@ -894,8 +894,6 @@ err_disable:
err_free_irq:
if (als->irq)
free_irq(als->irq, indio_dev);
err_free_dev:
iio_device_free(indio_dev);
return ret;
}
@ -910,7 +908,6 @@ static int lm3533_als_remove(struct platform_device *pdev)
lm3533_als_disable(als);
if (als->irq)
free_irq(als->irq, indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -702,7 +702,7 @@ static int tsl2563_probe(struct i2c_client *client,
int err = 0;
u8 id = 0;
indio_dev = iio_device_alloc(sizeof(*chip));
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
@ -714,13 +714,13 @@ static int tsl2563_probe(struct i2c_client *client,
err = tsl2563_detect(chip);
if (err) {
dev_err(&client->dev, "detect error %d\n", -err);
goto fail1;
return err;
}
err = tsl2563_read_id(chip, &id);
if (err) {
dev_err(&client->dev, "read id error %d\n", -err);
goto fail1;
return err;
}
mutex_init(&chip->lock);
@ -751,7 +751,7 @@ static int tsl2563_probe(struct i2c_client *client,
indio_dev->info = &tsl2563_info_no_irq;
if (client->irq) {
err = request_threaded_irq(client->irq,
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL,
&tsl2563_event_handler,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@ -759,14 +759,14 @@ static int tsl2563_probe(struct i2c_client *client,
indio_dev);
if (err) {
dev_err(&client->dev, "irq request error %d\n", -err);
goto fail1;
return err;
}
}
err = tsl2563_configure(chip);
if (err) {
dev_err(&client->dev, "configure error %d\n", -err);
goto fail2;
return err;
}
INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
@ -777,19 +777,14 @@ static int tsl2563_probe(struct i2c_client *client,
err = iio_device_register(indio_dev);
if (err) {
dev_err(&client->dev, "iio registration error %d\n", -err);
goto fail3;
goto fail;
}
return 0;
fail3:
fail:
cancel_delayed_work(&chip->poweroff_work);
flush_scheduled_work();
fail2:
if (client->irq)
free_irq(client->irq, indio_dev);
fail1:
iio_device_free(indio_dev);
return err;
}
@ -807,10 +802,6 @@ static int tsl2563_remove(struct i2c_client *client)
chip->intr);
flush_scheduled_work();
tsl2563_set_power(chip, 0);
if (client->irq)
free_irq(client->irq, indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -157,7 +157,7 @@ static int vcnl4000_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int ret;
indio_dev = iio_device_alloc(sizeof(*data));
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@ -167,7 +167,7 @@ static int vcnl4000_probe(struct i2c_client *client,
ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
if (ret < 0)
goto error_free_dev;
return ret;
dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n",
ret >> 4, ret & 0xf);
@ -181,22 +181,14 @@ static int vcnl4000_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret < 0)
goto error_free_dev;
return ret;
return 0;
error_free_dev:
iio_device_free(indio_dev);
return ret;
}
static int vcnl4000_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
iio_device_free(indio_dev);
iio_device_unregister(i2c_get_clientdata(client));
return 0;
}

View File

@ -1,6 +1,8 @@
#
# Magnetometer sensors
#
# When adding new entries keep the list in alphabetical order
menu "Magnetometer sensors"
config AK8975
@ -36,8 +38,8 @@ config IIO_ST_MAGN_3AXIS
Say yes here to build support for STMicroelectronics magnetometers:
LSM303DLHC, LSM303DLM, LIS3MDL.
This driver can also be built as a module. If so, will be created
these modules:
This driver can also be built as a module. If so, these modules
will be created:
- st_magn (core functions for the driver [it is mandatory]);
- st_magn_i2c (necessary for the I2C devices [optional*]);
- st_magn_spi (necessary for the SPI devices [optional*]);

View File

@ -2,6 +2,7 @@
# Makefile for industrial I/O Magnetometer sensor drivers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AK8975) += ak8975.o
obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o

View File

@ -30,10 +30,6 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
/*Format: HID-SENSOR-usage_id_in_hex*/
/*Usage ID from spec for Magnetometer-3D: 0x200083*/
#define DRIVER_NAME "HID-SENSOR-200083"
enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
@ -287,11 +283,11 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
indio_dev = iio_device_alloc(sizeof(struct magn_3d_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&pdev->dev,
sizeof(struct magn_3d_state));
if (indio_dev == NULL)
return -ENOMEM;
platform_set_drvdata(pdev, indio_dev);
magn_state = iio_priv(indio_dev);
@ -303,15 +299,14 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
&magn_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
goto error_free_dev;
return ret;
}
channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
return -ENOMEM;
}
ret = magn_3d_parse_report(pdev, hsdev, channels,
@ -368,9 +363,6 @@ error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
@ -385,14 +377,23 @@ static int hid_magn_3d_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
iio_device_free(indio_dev);
return 0;
}
static struct platform_device_id hid_magn_3d_ids[] = {
{
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-200083",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_magn_3d_ids);
static struct platform_driver hid_magn_3d_platform_driver = {
.id_table = hid_magn_3d_ids,
.driver = {
.name = DRIVER_NAME,
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
},
.probe = hid_magn_3d_probe,

View File

@ -18,7 +18,8 @@
#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
#define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
int st_magn_common_probe(struct iio_dev *indio_dev);
int st_magn_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata);
void st_magn_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER

View File

@ -345,7 +345,8 @@ static const struct iio_info magn_info = {
.write_raw = &st_magn_write_raw,
};
int st_magn_common_probe(struct iio_dev *indio_dev)
int st_magn_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
int err;
struct st_sensor_data *mdata = iio_priv(indio_dev);
@ -367,7 +368,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
&mdata->sensor->fs.fs_avl[0];
mdata->odr = mdata->sensor->odr.odr_avl[0].hz;
err = st_sensors_init_sensor(indio_dev);
err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)
goto st_magn_common_probe_error;
@ -406,7 +407,6 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_magn_deallocate_ring(indio_dev);
}
iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_magn_common_remove);

View File

@ -25,27 +25,20 @@ static int st_magn_i2c_probe(struct i2c_client *client,
struct st_sensor_data *mdata;
int err;
indio_dev = iio_device_alloc(sizeof(*mdata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mdata));
if (!indio_dev)
return -ENOMEM;
mdata = iio_priv(indio_dev);
mdata->dev = &client->dev;
st_sensors_i2c_configure(indio_dev, client, mdata);
err = st_magn_common_probe(indio_dev);
err = st_magn_common_probe(indio_dev, NULL);
if (err < 0)
goto st_magn_common_probe_error;
return err;
return 0;
st_magn_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_magn_i2c_remove(struct i2c_client *client)

View File

@ -24,27 +24,20 @@ static int st_magn_spi_probe(struct spi_device *spi)
struct st_sensor_data *mdata;
int err;
indio_dev = iio_device_alloc(sizeof(*mdata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*mdata));
if (!indio_dev)
return -ENOMEM;
mdata = iio_priv(indio_dev);
mdata->dev = &spi->dev;
st_sensors_spi_configure(indio_dev, spi, mdata);
err = st_magn_common_probe(indio_dev);
err = st_magn_common_probe(indio_dev, NULL);
if (err < 0)
goto st_magn_common_probe_error;
return err;
return 0;
st_magn_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_magn_spi_remove(struct spi_device *spi)

View File

@ -1,21 +1,23 @@
#
# Pressure drivers
#
menu "Pressure Sensors"
# When adding new entries keep the list in alphabetical order
menu "Pressure sensors"
config IIO_ST_PRESS
tristate "STMicroelectronics pressures Driver"
tristate "STMicroelectronics pressure sensor Driver"
depends on (I2C || SPI_MASTER) && SYSFS
select IIO_ST_SENSORS_CORE
select IIO_ST_PRESS_I2C if (I2C)
select IIO_ST_PRESS_SPI if (SPI_MASTER)
select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
help
Say yes here to build support for STMicroelectronics pressures:
LPS331AP.
Say yes here to build support for STMicroelectronics pressure
sensors: LPS331AP.
This driver can also be built as a module. If so, will be created
these modules:
This driver can also be built as a module. If so, these modules
will be created:
- st_pressure (core functions for the driver [it is mandatory]);
- st_pressure_i2c (necessary for the I2C devices [optional*]);
- st_pressure_spi (necessary for the SPI devices [optional*]);

View File

@ -2,6 +2,7 @@
# Makefile for industrial I/O pressure drivers
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
st_pressure-y := st_pressure_core.o
st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o

View File

@ -16,7 +16,16 @@
#define LPS331AP_PRESS_DEV_NAME "lps331ap"
int st_press_common_probe(struct iio_dev *indio_dev);
/**
* struct st_sensors_platform_data - default press platform data
* @drdy_int_pin: default press DRDY is available on INT1 pin.
*/
static const struct st_sensors_platform_data default_press_pdata = {
.drdy_int_pin = 1,
};
int st_press_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata);
void st_press_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER

View File

@ -31,6 +31,9 @@
#define ST_PRESS_LSB_PER_MBAR 4096UL
#define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
ST_PRESS_LSB_PER_MBAR)
#define ST_PRESS_LSB_PER_CELSIUS 480UL
#define ST_PRESS_CELSIUS_NANO_SCALE (1000000000UL / \
ST_PRESS_LSB_PER_CELSIUS)
#define ST_PRESS_NUMBER_DATA_CHANNELS 1
/* DEFAULT VALUE FOR SENSORS */
@ -53,12 +56,13 @@
#define ST_PRESS_1_FS_ADDR 0x23
#define ST_PRESS_1_FS_MASK 0x30
#define ST_PRESS_1_FS_AVL_1260_VAL 0x00
#define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000
#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
#define ST_PRESS_1_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
#define ST_PRESS_1_BDU_ADDR 0x20
#define ST_PRESS_1_BDU_MASK 0x04
#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22
#define ST_PRESS_1_DRDY_IRQ_MASK 0x04
#define ST_PRESS_1_DRDY_IRQ_INT1_MASK 0x04
#define ST_PRESS_1_DRDY_IRQ_INT2_MASK 0x20
#define ST_PRESS_1_MULTIREAD_BIT true
#define ST_PRESS_1_TEMP_OFFSET 42500
@ -116,7 +120,8 @@ static const struct st_sensors st_press_sensors[] = {
},
.drdy_irq = {
.addr = ST_PRESS_1_DRDY_IRQ_ADDR,
.mask = ST_PRESS_1_DRDY_IRQ_MASK,
.mask_int1 = ST_PRESS_1_DRDY_IRQ_INT1_MASK,
.mask_int2 = ST_PRESS_1_DRDY_IRQ_INT2_MASK,
},
.multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
.bootime = 2,
@ -202,7 +207,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
#define ST_PRESS_TRIGGER_OPS NULL
#endif
int st_press_common_probe(struct iio_dev *indio_dev)
int st_press_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *plat_data)
{
int err;
struct st_sensor_data *pdata = iio_priv(indio_dev);
@ -224,7 +230,11 @@ int st_press_common_probe(struct iio_dev *indio_dev)
&pdata->sensor->fs.fs_avl[0];
pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
err = st_sensors_init_sensor(indio_dev);
if (!plat_data)
plat_data =
(struct st_sensors_platform_data *)&default_press_pdata;
err = st_sensors_init_sensor(indio_dev, plat_data);
if (err < 0)
goto st_press_common_probe_error;
@ -265,7 +275,6 @@ void st_press_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_press_deallocate_ring(indio_dev);
}
iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_press_common_remove);

View File

@ -25,27 +25,20 @@ static int st_press_i2c_probe(struct i2c_client *client,
struct st_sensor_data *pdata;
int err;
indio_dev = iio_device_alloc(sizeof(*pdata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*pdata));
if (!indio_dev)
return -ENOMEM;
pdata = iio_priv(indio_dev);
pdata->dev = &client->dev;
st_sensors_i2c_configure(indio_dev, client, pdata);
err = st_press_common_probe(indio_dev);
err = st_press_common_probe(indio_dev, client->dev.platform_data);
if (err < 0)
goto st_press_common_probe_error;
return err;
return 0;
st_press_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_press_i2c_remove(struct i2c_client *client)

View File

@ -24,27 +24,20 @@ static int st_press_spi_probe(struct spi_device *spi)
struct st_sensor_data *pdata;
int err;
indio_dev = iio_device_alloc(sizeof(*pdata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*pdata));
if (indio_dev == NULL)
return -ENOMEM;
pdata = iio_priv(indio_dev);
pdata->dev = &spi->dev;
st_sensors_spi_configure(indio_dev, spi, pdata);
err = st_press_common_probe(indio_dev);
err = st_press_common_probe(indio_dev, spi->dev.platform_data);
if (err < 0)
goto st_press_common_probe_error;
return err;
return 0;
st_press_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_press_spi_remove(struct spi_device *spi)

View File

@ -1,6 +1,8 @@
#
# Industrial I/O standalone triggers
#
# When adding new entries keep the list in alphabetical order
menu "Triggers - standalone"
config IIO_INTERRUPT_TRIGGER
@ -17,7 +19,7 @@ config IIO_SYSFS_TRIGGER
depends on SYSFS
select IRQ_WORK
help
Provides support for using SYSFS entry as IIO triggers.
Provides support for using SYSFS entries as IIO triggers.
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the

View File

@ -2,5 +2,6 @@
# Makefile for triggers not associated with iio-devices
#
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o

View File

@ -56,7 +56,7 @@ Then fill in the following:
- indio_dev->modes:
Specify whether direct access and / or ring buffer access is supported.
- indio_dev->ring:
- indio_dev->buffer:
An optional associated buffer.
- indio_dev->pollfunc:
Poll function related elements. This controls what occurs when a trigger
@ -67,7 +67,7 @@ Then fill in the following:
- indio_dev->num_channels:
How many channels are there?
Once these are set up, a call to iio_device_register(indio_dev),
Once these are set up, a call to iio_device_register(indio_dev)
will register the device with the iio core.
Worth noting here is that, if a ring buffer is to be used, it can be

View File

@ -841,14 +841,16 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = {
MXS_ADC_CHAN(15, IIO_VOLTAGE), /* VDD5V */
};
static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
{
/* The ADC always uses DELAY CHANNEL 0. */
const uint32_t adc_cfg =
(1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
(LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);
stmp_reset_block(lradc->base);
int ret = stmp_reset_block(lradc->base);
if (ret)
return ret;
/* Configure DELAY CHANNEL 0 for generic ADC sampling. */
writel(adc_cfg, lradc->base + LRADC_DELAY(0));
@ -869,6 +871,8 @@ static void mxs_lradc_hw_init(struct mxs_lradc *lradc)
/* Start internal temperature sensing. */
writel(0, lradc->base + LRADC_CTRL2);
return 0;
}
static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
@ -905,7 +909,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
int i;
/* Allocate the IIO device. */
iio = iio_device_alloc(sizeof(*lradc));
iio = devm_iio_device_alloc(dev, sizeof(*lradc));
if (!iio) {
dev_err(dev, "Failed to allocate IIO device\n");
return -ENOMEM;
@ -917,10 +921,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lradc->dev = &pdev->dev;
lradc->base = devm_ioremap_resource(dev, iores);
if (IS_ERR(lradc->base)) {
ret = PTR_ERR(lradc->base);
goto err_addr;
}
if (IS_ERR(lradc->base))
return PTR_ERR(lradc->base);
INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
@ -940,16 +942,14 @@ static int mxs_lradc_probe(struct platform_device *pdev)
/* 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 = -EINVAL;
goto err_addr;
}
if (lradc->irq[i] < 0)
return -EINVAL;
ret = devm_request_irq(dev, lradc->irq[i],
mxs_lradc_handle_irq, 0,
of_cfg->irq_name[i], iio);
if (ret)
goto err_addr;
return ret;
}
platform_set_drvdata(pdev, iio);
@ -969,14 +969,16 @@ static int mxs_lradc_probe(struct platform_device *pdev)
&mxs_lradc_trigger_handler,
&mxs_lradc_buffer_ops);
if (ret)
goto err_addr;
return ret;
ret = mxs_lradc_trigger_init(iio);
if (ret)
goto err_trig;
/* Configure the hardware. */
mxs_lradc_hw_init(lradc);
ret = mxs_lradc_hw_init(lradc);
if (ret)
goto err_dev;
/* Register the touchscreen input device. */
ret = mxs_lradc_ts_register(lradc);
@ -998,8 +1000,6 @@ err_dev:
mxs_lradc_trigger_remove(iio);
err_trig:
iio_triggered_buffer_cleanup(iio);
err_addr:
iio_device_free(iio);
return ret;
}
@ -1015,7 +1015,6 @@ static int mxs_lradc_remove(struct platform_device *pdev)
iio_device_unregister(iio);
iio_triggered_buffer_cleanup(iio);
mxs_lradc_trigger_remove(iio);
iio_device_free(iio);
return 0;
}

View File

@ -300,11 +300,10 @@ static int spear_adc_probe(struct platform_device *pdev)
int ret = -ENODEV;
int irq;
iodev = iio_device_alloc(sizeof(struct spear_adc_info));
iodev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_info));
if (!iodev) {
dev_err(dev, "failed allocating iio device\n");
ret = -ENOMEM;
goto errout1;
return -ENOMEM;
}
info = iio_priv(iodev);
@ -318,8 +317,7 @@ static int spear_adc_probe(struct platform_device *pdev)
info->adc_base_spear6xx = of_iomap(np, 0);
if (!info->adc_base_spear6xx) {
dev_err(dev, "failed mapping memory\n");
ret = -ENOMEM;
goto errout2;
return -ENOMEM;
}
info->adc_base_spear3xx =
(struct adc_regs_spear3xx *)info->adc_base_spear6xx;
@ -327,33 +325,33 @@ static int spear_adc_probe(struct platform_device *pdev)
info->clk = clk_get(dev, NULL);
if (IS_ERR(info->clk)) {
dev_err(dev, "failed getting clock\n");
goto errout3;
goto errout1;
}
ret = clk_prepare_enable(info->clk);
if (ret) {
dev_err(dev, "failed enabling clock\n");
goto errout4;
goto errout2;
}
irq = platform_get_irq(pdev, 0);
if ((irq < 0) || (irq >= NR_IRQS)) {
dev_err(dev, "failed getting interrupt resource\n");
ret = -EINVAL;
goto errout5;
goto errout3;
}
ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
goto errout5;
goto errout3;
}
if (of_property_read_u32(np, "sampling-frequency",
&info->sampling_freq)) {
dev_err(dev, "sampling-frequency missing in DT\n");
ret = -EINVAL;
goto errout5;
goto errout3;
}
/*
@ -383,21 +381,18 @@ static int spear_adc_probe(struct platform_device *pdev)
ret = iio_device_register(iodev);
if (ret)
goto errout5;
goto errout3;
dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
return 0;
errout5:
clk_disable_unprepare(info->clk);
errout4:
clk_put(info->clk);
errout3:
iounmap(info->adc_base_spear6xx);
clk_disable_unprepare(info->clk);
errout2:
iio_device_free(iodev);
clk_put(info->clk);
errout1:
iounmap(info->adc_base_spear6xx);
return ret;
}
@ -410,7 +405,6 @@ static int spear_adc_remove(struct platform_device *pdev)
clk_disable_unprepare(info->clk);
clk_put(info->clk);
iounmap(info->adc_base_spear6xx);
iio_device_free(iodev);
return 0;
}

View File

@ -551,31 +551,6 @@ static IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
adt7316_store_enable_smbus_timeout,
0);
static ssize_t adt7316_store_reset(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 config2;
int ret;
config2 = chip->config2 | ADT7316_RESET;
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
if (ret)
return -EIO;
return len;
}
static IIO_DEVICE_ATTR(reset, S_IWUSR,
NULL,
adt7316_store_reset,
0);
static ssize_t adt7316_show_powerdown(struct device *dev,
struct device_attribute *attr,
char *buf)
@ -1675,7 +1650,6 @@ static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
static struct attribute *adt7316_attributes[] = {
&iio_dev_attr_all_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_enabled.dev_attr.attr,
&iio_dev_attr_ad_channel.dev_attr.attr,
&iio_dev_attr_all_ad_channels.dev_attr.attr,
@ -1719,7 +1693,6 @@ static struct attribute *adt7516_attributes[] = {
&iio_dev_attr_all_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
&iio_dev_attr_select_ex_temp.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_enabled.dev_attr.attr,
&iio_dev_attr_ad_channel.dev_attr.attr,
&iio_dev_attr_all_ad_channels.dev_attr.attr,

View File

@ -10,16 +10,4 @@ config ADIS16060
Say yes here to build support for Analog Devices adis16060 wide bandwidth
yaw rate gyroscope with SPI.
config ADIS16260
tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
depends on SPI
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say yes here to build support for Analog Devices ADIS16260 ADIS16265
ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
This driver can also be built as a module. If so, the module
will be called adis16260.
endmenu

View File

@ -4,6 +4,3 @@
adis16060-y := adis16060_core.o
obj-$(CONFIG_ADIS16060) += adis16060.o
adis16260-y := adis16260_core.o
obj-$(CONFIG_ADIS16260) += adis16260.o

View File

@ -1,98 +0,0 @@
#ifndef SPI_ADIS16260_H_
#define SPI_ADIS16260_H_
#include "adis16260_platform_data.h"
#include <linux/iio/imu/adis.h>
#define ADIS16260_STARTUP_DELAY 220 /* ms */
#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */
#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */
#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */
#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */
#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */
#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */
#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */
#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */
#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */
#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */
#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */
#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */
#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */
#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */
#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */
#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */
#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */
#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */
#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */
#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */
#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */
#define ADIS16260_PROD_ID 0x56 /* Product identifier;
* convert to decimal = 16,265/16,260 */
#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
#define ADIS16260_ERROR_ACTIVE (1<<14)
#define ADIS16260_NEW_DATA (1<<15)
/* MSC_CTRL */
#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11)
/* Internal self-test enable */
#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10)
#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9)
#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8)
#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2)
#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
/* SMPL_PRD */
/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7)
#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F
/* SLP_CNT */
#define ADIS16260_SLP_CNT_POWER_OFF 0x80
/* DIAG_STAT */
#define ADIS16260_DIAG_STAT_ALARM2 (1<<9)
#define ADIS16260_DIAG_STAT_ALARM1 (1<<8)
#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6
#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5
#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4
#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3
#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2
#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1
#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */
#define ADIS16260_GLOB_CMD_SW_RESET (1<<7)
#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3)
#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2)
#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1)
#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0)
#define ADIS16260_SPI_SLOW (u32)(300 * 1000)
#define ADIS16260_SPI_BURST (u32)(1000 * 1000)
#define ADIS16260_SPI_FAST (u32)(2000 * 1000)
/**
* struct adis16260_state - device instance specific data
* @negate: negate the scale parameter
**/
struct adis16260_state {
unsigned negate:1;
struct adis adis;
};
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
#define ADIS16260_SCAN_GYRO 0
#define ADIS16260_SCAN_SUPPLY 1
#define ADIS16260_SCAN_AUX_ADC 2
#define ADIS16260_SCAN_TEMP 3
#define ADIS16260_SCAN_ANGL 4
#endif /* SPI_ADIS16260_H_ */

View File

@ -1,19 +0,0 @@
/*
* ADIS16260 Programmable Digital Gyroscope Sensor Driver Platform Data
*
* Based on adis16255.h Matthia Brugger <m_brugger&web.de>
*
* Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits
*
* Licensed under the GPL-2 or later.
*/
/**
* struct adis16260_platform_data - instance specific data
* @direction: x y or z
* @negate: flag to indicate value should be inverted.
**/
struct adis16260_platform_data {
char direction;
unsigned negate:1;
};

View File

@ -550,11 +550,10 @@ static int isl29018_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int err;
indio_dev = iio_device_alloc(sizeof(*chip));
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (indio_dev == NULL) {
dev_err(&client->dev, "iio allocation fails\n");
err = -ENOMEM;
goto exit;
return -ENOMEM;
}
chip = iio_priv(indio_dev);
@ -572,12 +571,12 @@ static int isl29018_probe(struct i2c_client *client,
if (IS_ERR(chip->regmap)) {
err = PTR_ERR(chip->regmap);
dev_err(chip->dev, "regmap initialization failed: %d\n", err);
goto exit;
return err;
}
err = isl29018_chip_init(chip);
if (err)
goto exit_iio_free;
return err;
indio_dev->info = &isl29108_info;
indio_dev->channels = isl29018_channels;
@ -588,14 +587,10 @@ static int isl29018_probe(struct i2c_client *client,
err = iio_device_register(indio_dev);
if (err) {
dev_err(&client->dev, "iio registration fails\n");
goto exit_iio_free;
return err;
}
return 0;
exit_iio_free:
iio_device_free(indio_dev);
exit:
return err;
}
static int isl29018_remove(struct i2c_client *client)
@ -604,7 +599,6 @@ static int isl29018_remove(struct i2c_client *client)
dev_dbg(&client->dev, "%s()\n", __func__);
iio_device_unregister(indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -482,7 +482,7 @@ static int isl29028_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int ret;
indio_dev = iio_device_alloc(sizeof(*chip));
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (!indio_dev) {
dev_err(&client->dev, "iio allocation fails\n");
return -ENOMEM;
@ -498,13 +498,13 @@ static int isl29028_probe(struct i2c_client *client,
if (IS_ERR(chip->regmap)) {
ret = PTR_ERR(chip->regmap);
dev_err(chip->dev, "regmap initialization failed: %d\n", ret);
goto exit_iio_free;
return ret;
}
ret = isl29028_chip_init(chip);
if (ret < 0) {
dev_err(chip->dev, "chip initialization failed: %d\n", ret);
goto exit_iio_free;
return ret;
}
indio_dev->info = &isl29028_info;
@ -517,13 +517,9 @@ static int isl29028_probe(struct i2c_client *client,
if (ret < 0) {
dev_err(chip->dev, "iio registration fails with error %d\n",
ret);
goto exit_iio_free;
return ret;
}
return 0;
exit_iio_free:
iio_device_free(indio_dev);
return ret;
}
static int isl29028_remove(struct i2c_client *client)
@ -531,7 +527,6 @@ static int isl29028_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
iio_device_free(indio_dev);
return 0;
}

View File

@ -20,12 +20,10 @@
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/delay.h>
#define HMC5843_CONFIG_REG_A 0x00
#define HMC5843_CONFIG_REG_B 0x01
@ -42,9 +40,6 @@
#define HMC5883_DATA_OUT_Y_MSB_REG 0x07
#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
#define HMC5843_STATUS_REG 0x09
#define HMC5843_ID_REG_A 0x0A
#define HMC5843_ID_REG_B 0x0B
#define HMC5843_ID_REG_C 0x0C
enum hmc5843_ids {
HMC5843_ID,
@ -52,14 +47,6 @@ enum hmc5843_ids {
HMC5883L_ID,
};
/*
* Beware: identification of the HMC5883 is still "H43";
* I2C address is also unchanged
*/
#define HMC5843_ID_REG_LENGTH 0x03
#define HMC5843_ID_STRING "H43"
#define HMC5843_I2C_ADDRESS 0x1E
/*
* Range gain settings in (+-)Ga
* Beware: HMC5843 and HMC5883 have different recommended sensor field
@ -185,14 +172,9 @@ static const char * const hmc5883_regval_to_sample_freq[] = {
"0.75", "1.5", "3", "7.5", "15", "30", "75",
};
/* Addresses to scan: 0x1E */
static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
I2C_CLIENT_END };
/* Describe chip variants */
struct hmc5843_chip_info {
const struct iio_chan_spec *channels;
int num_channels;
const char * const *regval_to_sample_freq;
const int *regval_to_input_field_mga;
const int *regval_to_nanoscale;
@ -225,18 +207,29 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev,
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct hmc5843_data *data = iio_priv(indio_dev);
s32 result;
int tries = 150;
mutex_lock(&data->lock);
result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
while (!(result & HMC5843_DATA_READY))
result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
while (tries-- > 0) {
result = i2c_smbus_read_byte_data(client,
HMC5843_STATUS_REG);
if (result & HMC5843_DATA_READY)
break;
msleep(20);
}
result = i2c_smbus_read_word_data(client, address);
if (tries < 0) {
dev_err(&client->dev, "data not ready\n");
mutex_unlock(&data->lock);
return -EIO;
}
result = i2c_smbus_read_word_swapped(client, address);
mutex_unlock(&data->lock);
if (result < 0)
return -EINVAL;
*val = (s16)swab16((u16)result);
*val = result;
return IIO_VAL_INT;
}
@ -559,14 +552,14 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
#define HMC5843_CHANNEL(axis, add) \
#define HMC5843_CHANNEL(axis, addr) \
{ \
.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), \
.address = add \
.address = addr \
}
static const struct iio_chan_spec hmc5843_channels[] = {
@ -597,7 +590,6 @@ static const struct attribute_group hmc5843_group = {
static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = {
.channels = hmc5843_channels,
.num_channels = ARRAY_SIZE(hmc5843_channels),
.regval_to_sample_freq = hmc5843_regval_to_sample_freq,
.regval_to_input_field_mga =
hmc5843_regval_to_input_field_mga,
@ -605,7 +597,6 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
},
[HMC5883_ID] = {
.channels = hmc5883_channels,
.num_channels = ARRAY_SIZE(hmc5883_channels),
.regval_to_sample_freq = hmc5883_regval_to_sample_freq,
.regval_to_input_field_mga =
hmc5883_regval_to_input_field_mga,
@ -613,7 +604,6 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
},
[HMC5883L_ID] = {
.channels = hmc5883_channels,
.num_channels = ARRAY_SIZE(hmc5883_channels),
.regval_to_sample_freq = hmc5883_regval_to_sample_freq,
.regval_to_input_field_mga =
hmc5883l_regval_to_input_field_mga,
@ -621,25 +611,6 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
},
};
static int hmc5843_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
unsigned char id_str[HMC5843_ID_REG_LENGTH];
if (client->addr != HMC5843_I2C_ADDRESS)
return -ENODEV;
if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
HMC5843_ID_REG_LENGTH, id_str)
!= HMC5843_ID_REG_LENGTH)
return -ENODEV;
if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
return -ENODEV;
return 0;
}
/* Called when we have found a new HMC58X3 */
static void hmc5843_init_client(struct i2c_client *client,
const struct i2c_device_id *id)
@ -649,7 +620,7 @@ static void hmc5843_init_client(struct i2c_client *client,
data->variant = &hmc5843_chip_info_tbl[id->driver_data];
indio_dev->channels = data->variant->channels;
indio_dev->num_channels = data->variant->num_channels;
indio_dev->num_channels = 3;
hmc5843_set_meas_conf(client, data->meas_conf);
hmc5843_set_rate(client, data->rate);
hmc5843_configure(client, data->operating_mode);
@ -756,8 +727,6 @@ static struct i2c_driver hmc5843_driver = {
.id_table = hmc5843_id,
.probe = hmc5843_probe,
.remove = hmc5843_remove,
.detect = hmc5843_detect,
.address_list = normal_i2c,
};
module_i2c_driver(hmc5843_driver);

View File

@ -225,21 +225,6 @@ static int ade7753_reset(struct device *dev)
return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val);
}
static ssize_t ade7753_write_reset(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
if (len < 1)
return -1;
switch (buf[0]) {
case '1':
case 'y':
case 'Y':
return ade7753_reset(dev);
}
return -1;
}
static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
@ -458,8 +443,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7753_read_frequency,
ade7753_write_frequency);
static IIO_DEV_ATTR_RESET(ade7753_write_reset);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
static struct attribute *ade7753_attributes[] = {
@ -468,7 +451,6 @@ static struct attribute *ade7753_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_phcal.dev_attr.attr,
&iio_dev_attr_cfden.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,

View File

@ -224,22 +224,6 @@ static int ade7754_reset(struct device *dev)
return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val);
}
static ssize_t ade7754_write_reset(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
if (len < 1)
return -1;
switch (buf[0]) {
case '1':
case 'y':
case 'Y':
return ade7754_reset(dev);
}
return -1;
}
static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
@ -478,8 +462,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7754_read_frequency,
ade7754_write_frequency);
static IIO_DEV_ATTR_RESET(ade7754_write_reset);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
static struct attribute *ade7754_attributes[] = {
@ -488,7 +470,6 @@ static struct attribute *ade7754_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_aenergy.dev_attr.attr,
&iio_dev_attr_laenergy.dev_attr.attr,
&iio_dev_attr_vaenergy.dev_attr.attr,

View File

@ -313,21 +313,6 @@ static int ade7758_reset(struct device *dev)
return ret;
}
static ssize_t ade7758_write_reset(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
if (len < 1)
return -1;
switch (buf[0]) {
case '1':
case 'y':
case 'Y':
return ade7758_reset(dev);
}
return len;
}
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
ade7758_read_8bit,
ade7758_write_8bit,
@ -591,8 +576,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ade7758_read_frequency,
ade7758_write_frequency);
static IIO_DEV_ATTR_RESET(ade7758_write_reset);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
static struct attribute *ade7758_attributes[] = {
@ -601,7 +584,6 @@ static struct attribute *ade7758_attributes[] = {
&iio_const_attr_in_temp_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_awatthr.dev_attr.attr,
&iio_dev_attr_bwatthr.dev_attr.attr,
&iio_dev_attr_cwatthr.dev_attr.attr,

View File

@ -54,7 +54,7 @@ out:
return ret;
}
/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
/* Whilst this makes a lot of calls to iio_sw_ring functions - it is too device
* specific to be rolled into the core.
*/
static irqreturn_t ade7758_trigger_handler(int irq, void *p)

Some files were not shown because too many files have changed in this diff Show More