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:
commit
a083c4f215
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>");
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#
|
||||
# Gain Amplifiers, etc.
|
||||
#
|
||||
# When adding new entries keep the list in alphabetical order
|
||||
|
||||
menu "Amplifiers"
|
||||
|
||||
config AD8366
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
# Makefile iio/amplifiers
|
||||
#
|
||||
|
||||
# When adding new entries keep the list in alphabetical order
|
||||
obj-$(CONFIG_AD8366) += ad8366.o
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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*]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#
|
||||
# IIO imu drivers configuration
|
||||
#
|
||||
# When adding new entries keep the list in alphabetical order
|
||||
|
||||
menu "Inertial measurement units"
|
||||
|
||||
config ADIS16400
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
**/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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*]);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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*]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,6 +4,3 @@
|
|||
|
||||
adis16060-y := adis16060_core.o
|
||||
obj-$(CONFIG_ADIS16060) += adis16060.o
|
||||
|
||||
adis16260-y := adis16260_core.o
|
||||
obj-$(CONFIG_ADIS16260) += adis16260.o
|
||||
|
|
|
@ -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_ */
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue