Merge tag 'iio-for-4.12a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Mar 2017 12:17:21 +0000 (13:17 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Mar 2017 12:17:21 +0000 (13:17 +0100)
Jonathan writes:

First set of IIO new device support, features and cleanup for the 4.12 cycle.

Quite a bit of outreachy activity here with a driver from a current intern
and a number of cleanup patches as part of the next round.

Getting a pull request in early this cycle as it's looking like another large
cycle for IIO.

New device support
* adxl345
  - initial device support. Note, once complete support is done the intent
    is to superceded the driver in input/misc.
  - bindings.
  - conversion from i2c direct calls to regmap and driver split.
  - spi support.
* chromeos light and proximity.
  - new driver.
* devantech srf04 ultrasonic ranger
  - new driver with device tree bindings.
* hid temperature
  - new driver for environemntal temperature support from hid devices.
* max30102 oximeter
  - new driver with device tree bindings.
* st lsm6dsx
  - refactor and addition of device support for lsm6dsl and lsm6ds3h.

Staging graduation
* isl29028 including copyright notice update to reflect Brian's work.
* lpc32xx_adc.
* spear adc. It's not perfect and there are some datasheet disagreements, but
  it works and is good enough to graduate.

New features
* documentation
  - abi docs for in_proximity_sampling_frequency_available.
  - generalise counting direction ABI docs as a second driver is going to
  use them.
* hid-sensor-prox
  - Add support for HID_USAGE_SENSOR_HUMAN_PRESENCE if used on a particular
  device.
* isl29028
  - runtime pm.
* meson-saradc
  - switch from polling to interrupt mode and improved read_raw_sample function
  to avoid unnecessary loop.
* tmp007
  - interrupt and threshold event support.

Cleanups and minor fixes
* ad2s1210
  - permissions to octal.
* ad7192
  - permissions to octal.
  - use BIT macro.
* ad9832
  - merge header definitions into source file.
* ad9834
  - merge header definitions into source file.
* ade7753
  - merge header definitions into source file.
  - cleanup include ordering.
* ade7854
  - simplify return logic.
* adis16201
  - merge header definitions into source file.
  - rename _core.c to .c as there is nothing else.
* adis16203
  - merge header definitions into source file.
  - rename _core.c to .c as there is nothing else.
* adis16209
  - merge header definitions into source file.
  - rename _core.c to .c as there is nothing else.
* adis16240
  - permissions to octal.
  - merge header definitions into source file.
  - rename _core.c to .c as there is nothing else.
* adt7136
  - permissions to octal.
* cio-dac
  - set missing parent device.
* documentation
  - update version numbers on sysfs ABI for counter bits that didn't quite.
  make 4.9.
* isl29028
  - mdelay to msleep.
  - incorrrect sleep time when taking first proximity reading.
* lmp91000
  - set missing parent device.
* lpc32xx
  - Consistent prefixes for defines.
  - rename local state structure to _state.
* max30100
  - set missing parent device.
* max30102
  - set missing parent device.
* maxim-thermocouple
  - set missing parent device.
* meter driver header
  - permissions to octal.
* pulsedlight-lidar-lite-v2
  - set missing parent device.
* quad-8
  - set missing parent device.
* st104
  - set missing parent device.

Other
* Mailmap
  - update Matt Ranostay's email address to the Konsolko one.

74 files changed:
.mailmap
Documentation/ABI/testing/sysfs-bus-iio
Documentation/ABI/testing/sysfs-bus-iio-counter-104-quad-8
Documentation/devicetree/bindings/iio/accel/adxl345.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
Documentation/devicetree/bindings/iio/health/max30102.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
Documentation/devicetree/bindings/iio/proximity/devantech-srf04.txt [new file with mode: 0644]
MAINTAINERS
drivers/iio/accel/Kconfig
drivers/iio/accel/Makefile
drivers/iio/accel/adxl345.h [new file with mode: 0644]
drivers/iio/accel/adxl345_core.c [new file with mode: 0644]
drivers/iio/accel/adxl345_i2c.c [new file with mode: 0644]
drivers/iio/accel/adxl345_spi.c [new file with mode: 0644]
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/lpc32xx_adc.c [moved from drivers/staging/iio/adc/lpc32xx_adc.c with 68% similarity]
drivers/iio/adc/meson_saradc.c
drivers/iio/adc/spear_adc.c [moved from drivers/staging/iio/adc/spear_adc.c with 100% similarity]
drivers/iio/adc/stx104.c
drivers/iio/common/hid-sensors/hid-sensor-attributes.c
drivers/iio/counter/104-quad-8.c
drivers/iio/dac/cio-dac.c
drivers/iio/health/Kconfig
drivers/iio/health/Makefile
drivers/iio/health/max30100.c
drivers/iio/health/max30102.c [new file with mode: 0644]
drivers/iio/imu/st_lsm6dsx/Kconfig
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
drivers/iio/light/Kconfig
drivers/iio/light/Makefile
drivers/iio/light/cros_ec_light_prox.c [new file with mode: 0644]
drivers/iio/light/hid-sensor-prox.c
drivers/iio/potentiostat/lmp91000.c
drivers/iio/proximity/Kconfig
drivers/iio/proximity/Makefile
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
drivers/iio/proximity/srf04.c [new file with mode: 0644]
drivers/iio/temperature/Kconfig
drivers/iio/temperature/Makefile
drivers/iio/temperature/hid-sensor-temperature.c [new file with mode: 0644]
drivers/iio/temperature/maxim_thermocouple.c
drivers/iio/temperature/tmp007.c
drivers/staging/iio/accel/Makefile
drivers/staging/iio/accel/adis16201.c [moved from drivers/staging/iio/accel/adis16201_core.c with 64% similarity]
drivers/staging/iio/accel/adis16201.h [deleted file]
drivers/staging/iio/accel/adis16203.c [moved from drivers/staging/iio/accel/adis16203_core.c with 64% similarity]
drivers/staging/iio/accel/adis16203.h [deleted file]
drivers/staging/iio/accel/adis16209.c [moved from drivers/staging/iio/accel/adis16209_core.c with 63% similarity]
drivers/staging/iio/accel/adis16209.h [deleted file]
drivers/staging/iio/accel/adis16240.c [moved from drivers/staging/iio/accel/adis16240_core.c with 62% similarity]
drivers/staging/iio/accel/adis16240.h [deleted file]
drivers/staging/iio/adc/Kconfig
drivers/staging/iio/adc/Makefile
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/addac/adt7316.c
drivers/staging/iio/cdc/ad7152.c
drivers/staging/iio/frequency/ad9832.c
drivers/staging/iio/frequency/ad9832.h
drivers/staging/iio/frequency/ad9834.c
drivers/staging/iio/frequency/ad9834.h
drivers/staging/iio/impedance-analyzer/ad5933.c
drivers/staging/iio/light/isl29028.c
drivers/staging/iio/meter/ade7753.c
drivers/staging/iio/meter/ade7753.h [deleted file]
drivers/staging/iio/meter/ade7854.c
drivers/staging/iio/meter/meter.h
drivers/staging/iio/resolver/ad2s1210.c
include/linux/hid-sensor-ids.h

index 67dc22f..e775f79 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -109,6 +109,7 @@ Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
 Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.com>
 Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com>
+Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
 Mayuresh Janorkar <mayur@ti.com>
 Michael Buesch <m@bues.ch>
 Michel Dänzer <michel@tungstengraphics.com>
index 530809c..8c24d08 100644 (file)
@@ -55,6 +55,7 @@ Description:
                then it is to be found in the base device directory.
 
 What:          /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available
+What:          /sys/bus/iio/devices/iio:deviceX/in_proximity_sampling_frequency_available
 What:          /sys/.../iio:deviceX/buffer/sampling_frequency_available
 What:          /sys/bus/iio/devices/triggerX/sampling_frequency_available
 KernelVersion: 2.6.35
@@ -1593,7 +1594,7 @@ Description:
                can be processed to siemens per meter.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_countY_raw
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Raw counter device counts from channel Y. For quadrature
@@ -1601,10 +1602,24 @@ Description:
                the counts of a single quadrature signal phase from channel Y.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_indexY_raw
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Raw counter device index value from channel Y. This attribute
                provides an absolute positional reference (e.g. a pulse once per
                revolution) which may be used to home positional systems as
                required.
+
+What:          /sys/bus/iio/devices/iio:deviceX/in_count_count_direction_available
+KernelVersion: 4.12
+Contact:       linux-iio@vger.kernel.org
+Description:
+               A list of possible counting directions which are:
+               - "up"  : counter device is increasing.
+               - "down": counter device is decreasing.
+
+What:          /sys/bus/iio/devices/iio:deviceX/in_countY_count_direction
+KernelVersion: 4.12
+Contact:       linux-iio@vger.kernel.org
+Description:
+               Raw counter device counters direction for channel Y.
index ba67652..7fac2c2 100644 (file)
@@ -1,24 +1,16 @@
-What:          /sys/bus/iio/devices/iio:deviceX/in_count_count_direction_available
 What:          /sys/bus/iio/devices/iio:deviceX/in_count_count_mode_available
 What:          /sys/bus/iio/devices/iio:deviceX/in_count_noise_error_available
 What:          /sys/bus/iio/devices/iio:deviceX/in_count_quadrature_mode_available
 What:          /sys/bus/iio/devices/iio:deviceX/in_index_index_polarity_available
 What:          /sys/bus/iio/devices/iio:deviceX/in_index_synchronous_mode_available
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Discrete set of available values for the respective counter
                configuration are listed in this file.
 
-What:          /sys/bus/iio/devices/iio:deviceX/in_countY_count_direction
-KernelVersion: 4.9
-Contact:       linux-iio@vger.kernel.org
-Description:
-               Read-only attribute that indicates whether the counter for
-               channel Y is counting up or down.
-
 What:          /sys/bus/iio/devices/iio:deviceX/in_countY_count_mode
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Count mode for channel Y. Four count modes are available:
@@ -52,7 +44,7 @@ Description:
                        continuously throughout.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_countY_noise_error
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Read-only attribute that indicates whether excessive noise is
@@ -60,14 +52,14 @@ Description:
                irrelevant in non-quadrature clock mode.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_countY_preset
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                If the counter device supports preset registers, the preset
                count for channel Y is provided by this attribute.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_countY_quadrature_mode
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Configure channel Y counter for non-quadrature or quadrature
@@ -88,7 +80,7 @@ Description:
                        decoded for UP/DN clock.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_countY_set_to_preset_on_index
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Whether to set channel Y counter with channel Y preset value
@@ -96,14 +88,14 @@ Description:
                Valid attribute values are boolean.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_indexY_index_polarity
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Active level of channel Y index input; irrelevant in
                non-synchronous load mode.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_indexY_synchronous_mode
-KernelVersion: 4.9
+KernelVersion: 4.10
 Contact:       linux-iio@vger.kernel.org
 Description:
                Configure channel Y counter for non-synchronous or synchronous
diff --git a/Documentation/devicetree/bindings/iio/accel/adxl345.txt b/Documentation/devicetree/bindings/iio/accel/adxl345.txt
new file mode 100644 (file)
index 0000000..e7111b0
--- /dev/null
@@ -0,0 +1,38 @@
+Analog Devices ADXL345 3-Axis, +/-(2g/4g/8g/16g) Digital Accelerometer
+
+http://www.analog.com/en/products/mems/accelerometers/adxl345.html
+
+Required properties:
+ - compatible : should be "adi,adxl345"
+ - reg : the I2C address or SPI chip select number of the sensor
+
+Required properties for SPI bus usage:
+ - spi-max-frequency : set maximum clock frequency, must be 5000000
+ - spi-cpol and spi-cpha : must be defined for adxl345 to enable SPI mode 3
+
+Optional properties:
+ - interrupt-parent : phandle to the parent interrupt controller as documented
+   in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+       accelerometer@2a {
+               compatible = "adi,adxl345";
+               reg = <0x53>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+Example for a SPI device node:
+
+       accelerometer@0 {
+               compatible = "adi,adxl345";
+               reg = <0>;
+               spi-max-frequency = <5000000>;
+               spi-cpol;
+               spi-cpha;
+               interrupt-parent = <&gpio1>;
+               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+       };
index f9e3ff2..0471891 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
                        - "amlogic,meson-gxm-saradc" for GXM
                along with the generic "amlogic,meson-saradc"
 - reg:         the physical base address and length of the registers
+- interrupts:  the interrupt indicating end of sampling
 - clocks:      phandle and clock identifier (see clock-names)
 - clock-names: mandatory clocks:
                        - "clkin" for the reference clock (typically XTAL)
@@ -23,6 +24,7 @@ Example:
                compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc";
                #io-channel-cells = <1>;
                reg = <0x0 0x8680 0x0 0x34>;
+               interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
                clocks = <&xtal>,
                         <&clkc CLKID_SAR_ADC>,
                         <&clkc CLKID_SANA>,
diff --git a/Documentation/devicetree/bindings/iio/health/max30102.txt b/Documentation/devicetree/bindings/iio/health/max30102.txt
new file mode 100644 (file)
index 0000000..c695e7c
--- /dev/null
@@ -0,0 +1,30 @@
+Maxim MAX30102 heart rate and pulse oximeter sensor
+
+* https://datasheets.maximintegrated.com/en/ds/MAX30102.pdf
+
+Required properties:
+  - compatible: must be "maxim,max30102"
+  - reg: the I2C address of the sensor
+  - interrupt-parent: should be the phandle for the interrupt controller
+  - interrupts: the sole interrupt generated by the device
+
+  Refer to interrupt-controller/interrupts.txt for generic
+  interrupt client node bindings.
+
+Optional properties:
+  - maxim,red-led-current-microamp: configuration for RED LED current
+  - maxim,ir-led-current-microamp: configuration for IR LED current
+
+    Note that each step is approximately 200 microamps, ranging from 0 uA to
+    50800 uA.
+
+Example:
+
+max30100@57 {
+       compatible = "maxim,max30102";
+       reg = <0x57>;
+       maxim,red-led-current-microamp = <7000>;
+       maxim,ir-led-current-microamp = <7000>;
+       interrupt-parent = <&gpio1>;
+       interrupts = <16 2>;
+};
index cf81afd..8305fb0 100644 (file)
@@ -3,6 +3,8 @@
 Required properties:
 - compatible: must be one of:
   "st,lsm6ds3"
+  "st,lsm6ds3h"
+  "st,lsm6dsl"
   "st,lsm6dsm"
 - reg: i2c address of the sensor / spi cs line
 
diff --git a/Documentation/devicetree/bindings/iio/proximity/devantech-srf04.txt b/Documentation/devicetree/bindings/iio/proximity/devantech-srf04.txt
new file mode 100644 (file)
index 0000000..d4dc7a2
--- /dev/null
@@ -0,0 +1,28 @@
+* Devantech SRF04 ultrasonic range finder
+  Bit-banging driver using two GPIOs
+
+Required properties:
+ - compatible: Should be "devantech,srf04"
+
+ - trig-gpios: Definition of the GPIO for the triggering (output)
+               This GPIO is set for about 10 us by the driver to tell the
+               device it should initiate the measurement cycle.
+
+ - echo-gpios: Definition of the GPIO for the echo (input)
+               This GPIO is set by the device as soon as an ultrasonic
+               burst is sent out and reset when the first echo is
+               received.
+               Thus this GPIO is set while the ultrasonic waves are doing
+               one round trip.
+               It needs to be an GPIO which is able to deliver an
+               interrupt because the time between two interrupts is
+               measured in the driver.
+               See Documentation/devicetree/bindings/gpio/gpio.txt for
+               information on how to specify a consumer gpio.
+
+Example:
+srf04@0 {
+       compatible = "devantech,srf04";
+       trig-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+       echo-gpios = <&gpio2  6 GPIO_ACTIVE_HIGH>;
+};
index c265a5f..8aec906 100644 (file)
@@ -3853,6 +3853,12 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
 S:     Maintained
 F:     drivers/usb/dwc3/
 
+DEVANTECH SRF ULTRASONIC RANGER IIO DRIVER
+M:     Andreas Klinger <ak@it-klinger.de>
+L:     linux-iio@vger.kernel.org
+S:     Maintained
+F:     drivers/iio/proximity/srf*.c
+
 DEVICE COREDUMP (DEV_COREDUMP)
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-kernel@vger.kernel.org
index ef8401a..15de262 100644 (file)
@@ -5,6 +5,37 @@
 
 menu "Accelerometers"
 
+config ADXL345
+       tristate
+
+config ADXL345_I2C
+       tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C Driver"
+       depends on INPUT_ADXL34X=n
+       depends on I2C
+       select ADXL345
+       select REGMAP_I2C
+       help
+         Say Y here if you want to build support for the Analog Devices
+         ADXL345 3-axis digital accelerometer.
+
+         To compile this driver as a module, choose M here: the module
+         will be called adxl345_i2c and you will also get adxl345_core
+         for the core module.
+
+config ADXL345_SPI
+       tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI Driver"
+       depends on INPUT_ADXL34X=n
+       depends on SPI
+       select ADXL345
+       select REGMAP_SPI
+       help
+         Say Y here if you want to build support for the Analog Devices
+         ADXL345 3-axis digital accelerometer.
+
+         To compile this driver as a module, choose M here: the module
+         will be called adxl345_spi and you will also get adxl345_core
+         for the core module.
+
 config BMA180
        tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
        depends on I2C
index 69fe8ed..31fba19 100644 (file)
@@ -3,6 +3,9 @@
 #
 
 # When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_ADXL345) += adxl345_core.o
+obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
+obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
new file mode 100644 (file)
index 0000000..c1ddf39
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraretuya@gmail.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.
+ */
+
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+                      const char *name);
+int adxl345_core_remove(struct device *dev);
+
+#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
new file mode 100644 (file)
index 0000000..9ccb582
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer IIO core driver
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraretuya@gmail.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/regmap.h>
+
+#include <linux/iio/iio.h>
+
+#include "adxl345.h"
+
+#define ADXL345_REG_DEVID              0x00
+#define ADXL345_REG_POWER_CTL          0x2D
+#define ADXL345_REG_DATA_FORMAT                0x31
+#define ADXL345_REG_DATAX0             0x32
+#define ADXL345_REG_DATAY0             0x34
+#define ADXL345_REG_DATAZ0             0x36
+
+#define ADXL345_POWER_CTL_MEASURE      BIT(3)
+#define ADXL345_POWER_CTL_STANDBY      0x00
+
+#define ADXL345_DATA_FORMAT_FULL_RES   BIT(3) /* Up to 13-bits resolution */
+#define ADXL345_DATA_FORMAT_2G         0
+#define ADXL345_DATA_FORMAT_4G         1
+#define ADXL345_DATA_FORMAT_8G         2
+#define ADXL345_DATA_FORMAT_16G                3
+
+#define ADXL345_DEVID                  0xE5
+
+/*
+ * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
+ * in all g ranges.
+ *
+ * At +/- 16g with 13-bit resolution, scale is computed as:
+ * (16 + 16) * 9.81 / (2^13 - 1) = 0.0383
+ */
+static const int adxl345_uscale = 38300;
+
+struct adxl345_data {
+       struct regmap *regmap;
+       u8 data_range;
+};
+
+#define ADXL345_CHANNEL(reg, axis) {                                   \
+       .type = IIO_ACCEL,                                              \
+       .modified = 1,                                                  \
+       .channel2 = IIO_MOD_##axis,                                     \
+       .address = reg,                                                 \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),           \
+}
+
+static const struct iio_chan_spec adxl345_channels[] = {
+       ADXL345_CHANNEL(ADXL345_REG_DATAX0, X),
+       ADXL345_CHANNEL(ADXL345_REG_DATAY0, Y),
+       ADXL345_CHANNEL(ADXL345_REG_DATAZ0, Z),
+};
+
+static int adxl345_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long mask)
+{
+       struct adxl345_data *data = iio_priv(indio_dev);
+       __le16 regval;
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               /*
+                * Data is stored in adjacent registers:
+                * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
+                * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
+                */
+               ret = regmap_bulk_read(data->regmap, chan->address, &regval,
+                                      sizeof(regval));
+               if (ret < 0)
+                       return ret;
+
+               *val = sign_extend32(le16_to_cpu(regval), 12);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = adxl345_uscale;
+
+               return IIO_VAL_INT_PLUS_MICRO;
+       }
+
+       return -EINVAL;
+}
+
+static const struct iio_info adxl345_info = {
+       .driver_module  = THIS_MODULE,
+       .read_raw       = adxl345_read_raw,
+};
+
+int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+                      const char *name)
+{
+       struct adxl345_data *data;
+       struct iio_dev *indio_dev;
+       u32 regval;
+       int ret;
+
+       ret = regmap_read(regmap, ADXL345_REG_DEVID, &regval);
+       if (ret < 0) {
+               dev_err(dev, "Error reading device ID: %d\n", ret);
+               return ret;
+       }
+
+       if (regval != ADXL345_DEVID) {
+               dev_err(dev, "Invalid device ID: %x, expected %x\n",
+                       regval, ADXL345_DEVID);
+               return -ENODEV;
+       }
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       dev_set_drvdata(dev, indio_dev);
+       data->regmap = regmap;
+       /* Enable full-resolution mode */
+       data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
+
+       ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
+                          data->data_range);
+       if (ret < 0) {
+               dev_err(dev, "Failed to set data range: %d\n", ret);
+               return ret;
+       }
+
+       indio_dev->dev.parent = dev;
+       indio_dev->name = name;
+       indio_dev->info = &adxl345_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = adxl345_channels;
+       indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
+
+       /* Enable measurement mode */
+       ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
+                          ADXL345_POWER_CTL_MEASURE);
+       if (ret < 0) {
+               dev_err(dev, "Failed to enable measurement mode: %d\n", ret);
+               return ret;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret < 0) {
+               dev_err(dev, "iio_device_register failed: %d\n", ret);
+               regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
+                            ADXL345_POWER_CTL_STANDBY);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(adxl345_core_probe);
+
+int adxl345_core_remove(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct adxl345_data *data = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       return regmap_write(data->regmap, ADXL345_REG_POWER_CTL,
+                           ADXL345_POWER_CTL_STANDBY);
+}
+EXPORT_SYMBOL_GPL(adxl345_core_remove);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer core driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c
new file mode 100644 (file)
index 0000000..05e1ec4
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer I2C driver
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraretuya@gmail.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.
+ *
+ * 7-bit I2C slave address: 0x1D (ALT ADDRESS pin tied to VDDIO) or
+ * 0x53 (ALT ADDRESS pin grounded)
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "adxl345.h"
+
+static const struct regmap_config adxl345_i2c_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static int adxl345_i2c_probe(struct i2c_client *client,
+                            const struct i2c_device_id *id)
+{
+       struct regmap *regmap;
+
+       regmap = devm_regmap_init_i2c(client, &adxl345_i2c_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
+                       PTR_ERR(regmap));
+               return PTR_ERR(regmap);
+       }
+
+       return adxl345_core_probe(&client->dev, regmap, id ? id->name : NULL);
+}
+
+static int adxl345_i2c_remove(struct i2c_client *client)
+{
+       return adxl345_core_remove(&client->dev);
+}
+
+static const struct i2c_device_id adxl345_i2c_id[] = {
+       { "adxl345", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+       { .compatible = "adi,adxl345" },
+       { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct i2c_driver adxl345_i2c_driver = {
+       .driver = {
+               .name   = "adxl345_i2c",
+               .of_match_table = adxl345_of_match,
+       },
+       .probe          = adxl345_i2c_probe,
+       .remove         = adxl345_i2c_remove,
+       .id_table       = adxl345_i2c_id,
+};
+
+module_i2c_driver(adxl345_i2c_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer I2C driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
new file mode 100644 (file)
index 0000000..6d65819
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * ADXL345 3-Axis Digital Accelerometer SPI driver
+ *
+ * Copyright (c) 2017 Eva Rachel Retuya <eraretuya@gmail.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/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "adxl345.h"
+
+#define ADXL345_MAX_SPI_FREQ_HZ                5000000
+
+static const struct regmap_config adxl345_spi_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+        /* Setting bits 7 and 6 enables multiple-byte read */
+       .read_flag_mask = BIT(7) | BIT(6),
+};
+
+static int adxl345_spi_probe(struct spi_device *spi)
+{
+       const struct spi_device_id *id = spi_get_device_id(spi);
+       struct regmap *regmap;
+
+       /* Bail out if max_speed_hz exceeds 5 MHz */
+       if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ) {
+               dev_err(&spi->dev, "SPI CLK, %d Hz exceeds 5 MHz\n",
+                       spi->max_speed_hz);
+               return -EINVAL;
+       }
+
+       regmap = devm_regmap_init_spi(spi, &adxl345_spi_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
+                       PTR_ERR(regmap));
+               return PTR_ERR(regmap);
+       }
+
+       return adxl345_core_probe(&spi->dev, regmap, id->name);
+}
+
+static int adxl345_spi_remove(struct spi_device *spi)
+{
+       return adxl345_core_remove(&spi->dev);
+}
+
+static const struct spi_device_id adxl345_spi_id[] = {
+       { "adxl345", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(spi, adxl345_spi_id);
+
+static const struct of_device_id adxl345_of_match[] = {
+       { .compatible = "adi,adxl345" },
+       { },
+};
+
+MODULE_DEVICE_TABLE(of, adxl345_of_match);
+
+static struct spi_driver adxl345_spi_driver = {
+       .driver = {
+               .name   = "adxl345_spi",
+               .of_match_table = adxl345_of_match,
+       },
+       .probe          = adxl345_spi_probe,
+       .remove         = adxl345_spi_remove,
+       .id_table       = adxl345_spi_id,
+};
+
+module_spi_driver(adxl345_spi_driver);
+
+MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
+MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
index dedae7a..d777a97 100644 (file)
@@ -305,6 +305,18 @@ config LPC18XX_ADC
          To compile this driver as a module, choose M here: the module will be
          called lpc18xx_adc.
 
+config LPC32XX_ADC
+       tristate "NXP LPC32XX ADC"
+       depends on ARCH_LPC32XX || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         Say yes here to build support for the integrated ADC inside the
+         LPC32XX SoC. Note that this feature uses the same hardware as the
+         touchscreen driver, so you should either select only one of the two
+         drivers (lpc32xx_adc or lpc32xx_ts) or, in the OpenFirmware case,
+         activate only one via device tree selection.  Provides direct access
+         via sysfs.
+
 config LTC2485
        tristate "Linear Technology LTC2485 ADC driver"
        depends on I2C
@@ -494,6 +506,17 @@ config ROCKCHIP_SARADC
          To compile this driver as a module, choose M here: the
          module will be called rockchip_saradc.
 
+config SPEAR_ADC
+       tristate "ST SPEAr ADC"
+       depends on PLAT_SPEAR || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         Say yes here to build support for the integrated ADC inside the
+         ST SPEAr SoC. Provides direct access via sysfs.
+
+         To compile this driver as a module, choose M here: the
+         module will be called spear_adc.
+
 config STM32_ADC_CORE
        tristate "STMicroelectronics STM32 adc core"
        depends on ARCH_STM32 || COMPILE_TEST
index d001262..b11bb57 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
 obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
+obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
 obj-$(CONFIG_LTC2485) += ltc2485.o
 obj-$(CONFIG_MAX1027) += max1027.o
 obj-$(CONFIG_MAX11100) += max11100.o
@@ -46,6 +47,7 @@ obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
 obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
 obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
 obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
+obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
 obj-$(CONFIG_STX104) += stx104.o
 obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
 obj-$(CONFIG_STM32_ADC) += stm32-adc.o
similarity index 68%
rename from drivers/staging/iio/adc/lpc32xx_adc.c
rename to drivers/iio/adc/lpc32xx_adc.c
index b51f237..0de709b 100644 (file)
 /*
  * LPC32XX registers definitions
  */
-#define LPC32XX_ADC_SELECT(x)  ((x) + 0x04)
-#define LPC32XX_ADC_CTRL(x)    ((x) + 0x08)
-#define LPC32XX_ADC_VALUE(x)   ((x) + 0x48)
-
-/* Bit definitions for LPC32XX_ADC_SELECT: */
-#define AD_REFm         0x00000200 /* constant, always write this value! */
-#define AD_REFp                0x00000080 /* constant, always write this value! */
-#define AD_IN          0x00000010 /* multiple of this is the */
-                                  /* channel number: 0, 1, 2 */
-#define AD_INTERNAL    0x00000004 /* constant, always write this value! */
-
-/* Bit definitions for LPC32XX_ADC_CTRL: */
-#define AD_STROBE      0x00000002
-#define AD_PDN_CTRL    0x00000004
-
-/* Bit definitions for LPC32XX_ADC_VALUE: */
-#define ADC_VALUE_MASK 0x000003FF
-
-#define MOD_NAME "lpc32xx-adc"
-
-struct lpc32xx_adc_info {
+#define LPC32XXAD_SELECT(x)    ((x) + 0x04)
+#define LPC32XXAD_CTRL(x)      ((x) + 0x08)
+#define LPC32XXAD_VALUE(x)     ((x) + 0x48)
+
+/* Bit definitions for LPC32XXAD_SELECT: */
+/* constant, always write this value! */
+#define LPC32XXAD_REFm         0x00000200
+/* constant, always write this value! */
+#define LPC32XXAD_REFp         0x00000080
+ /* multiple of this is the channel number: 0, 1, 2 */
+#define LPC32XXAD_IN           0x00000010
+/* constant, always write this value! */
+#define LPC32XXAD_INTERNAL     0x00000004
+
+/* Bit definitions for LPC32XXAD_CTRL: */
+#define LPC32XXAD_STROBE       0x00000002
+#define LPC32XXAD_PDN_CTRL     0x00000004
+
+/* Bit definitions for LPC32XXAD_VALUE: */
+#define LPC32XXAD_VALUE_MASK   0x000003FF
+
+#define LPC32XXAD_NAME "lpc32xx-adc"
+
+struct lpc32xx_adc_state {
        void __iomem *adc_base;
        struct clk *clk;
        struct completion completion;
@@ -72,20 +75,21 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev,
                            int *val2,
                            long mask)
 {
-       struct lpc32xx_adc_info *info = iio_priv(indio_dev);
+       struct lpc32xx_adc_state *st = iio_priv(indio_dev);
 
        if (mask == IIO_CHAN_INFO_RAW) {
                mutex_lock(&indio_dev->mlock);
-               clk_prepare_enable(info->clk);
+               clk_prepare_enable(st->clk);
                /* Measurement setup */
-               __raw_writel(AD_INTERNAL | (chan->address) | AD_REFp | AD_REFm,
-                            LPC32XX_ADC_SELECT(info->adc_base));
+               __raw_writel(LPC32XXAD_INTERNAL | (chan->address) |
+                            LPC32XXAD_REFp | LPC32XXAD_REFm,
+                            LPC32XXAD_SELECT(st->adc_base));
                /* Trigger conversion */
-               __raw_writel(AD_PDN_CTRL | AD_STROBE,
-                            LPC32XX_ADC_CTRL(info->adc_base));
-               wait_for_completion(&info->completion); /* set by ISR */
-               clk_disable_unprepare(info->clk);
-               *val = info->value;
+               __raw_writel(LPC32XXAD_PDN_CTRL | LPC32XXAD_STROBE,
+                            LPC32XXAD_CTRL(st->adc_base));
+               wait_for_completion(&st->completion); /* set by ISR */
+               clk_disable_unprepare(st->clk);
+               *val = st->value;
                mutex_unlock(&indio_dev->mlock);
 
                return IIO_VAL_INT;
@@ -104,7 +108,7 @@ static const struct iio_info lpc32xx_adc_iio_info = {
        .indexed = 1,                                   \
        .channel = _index,                              \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
-       .address = AD_IN * _index,                      \
+       .address = LPC32XXAD_IN * _index,               \
        .scan_index = _index,                           \
 }
 
@@ -116,19 +120,19 @@ static const struct iio_chan_spec lpc32xx_adc_iio_channels[] = {
 
 static irqreturn_t lpc32xx_adc_isr(int irq, void *dev_id)
 {
-       struct lpc32xx_adc_info *info = dev_id;
+       struct lpc32xx_adc_state *st = dev_id;
 
        /* Read value and clear irq */
-       info->value = __raw_readl(LPC32XX_ADC_VALUE(info->adc_base)) &
-                               ADC_VALUE_MASK;
-       complete(&info->completion);
+       st->value = __raw_readl(LPC32XXAD_VALUE(st->adc_base)) &
+               LPC32XXAD_VALUE_MASK;
+       complete(&st->completion);
 
        return IRQ_HANDLED;
 }
 
 static int lpc32xx_adc_probe(struct platform_device *pdev)
 {
-       struct lpc32xx_adc_info *info = NULL;
+       struct lpc32xx_adc_state *st = NULL;
        struct resource *res;
        int retval = -ENODEV;
        struct iio_dev *iodev = NULL;
@@ -140,23 +144,23 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+       iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
        if (!iodev)
                return -ENOMEM;
 
-       info = iio_priv(iodev);
+       st = iio_priv(iodev);
 
-       info->adc_base = devm_ioremap(&pdev->dev, res->start,
-                                               resource_size(res));
-       if (!info->adc_base) {
+       st->adc_base = devm_ioremap(&pdev->dev, res->start,
+                                   resource_size(res));
+       if (!st->adc_base) {
                dev_err(&pdev->dev, "failed mapping memory\n");
                return -EBUSY;
        }
 
-       info->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(info->clk)) {
+       st->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(st->clk)) {
                dev_err(&pdev->dev, "failed getting clock\n");
-               return PTR_ERR(info->clk);
+               return PTR_ERR(st->clk);
        }
 
        irq = platform_get_irq(pdev, 0);
@@ -166,7 +170,7 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
        }
 
        retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
-                                 MOD_NAME, info);
+                                 LPC32XXAD_NAME, st);
        if (retval < 0) {
                dev_err(&pdev->dev, "failed requesting interrupt\n");
                return retval;
@@ -174,9 +178,9 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, iodev);
 
-       init_completion(&info->completion);
+       init_completion(&st->completion);
 
-       iodev->name = MOD_NAME;
+       iodev->name = LPC32XXAD_NAME;
        iodev->dev.parent = &pdev->dev;
        iodev->info = &lpc32xx_adc_iio_info;
        iodev->modes = INDIO_DIRECT_MODE;
@@ -203,7 +207,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_adc_match);
 static struct platform_driver lpc32xx_adc_driver = {
        .probe          = lpc32xx_adc_probe,
        .driver         = {
-               .name   = MOD_NAME,
+               .name   = LPC32XXAD_NAME,
                .of_match_table = of_match_ptr(lpc32xx_adc_match),
        },
 };
index 89def60..cde9ca7 100644 (file)
@@ -18,7 +18,9 @@
 #include <linux/io.h>
 #include <linux/iio/iio.h>
 #include <linux/module.h>
+#include <linux/interrupt.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
        #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK      GENMASK(13, 8)
 
 #define MESON_SAR_ADC_MAX_FIFO_SIZE                            32
+#define MESON_SAR_ADC_TIMEOUT                                  100 /* ms */
 
 #define MESON_SAR_ADC_CHAN(_chan) {                                    \
        .type = IIO_VOLTAGE,                                            \
@@ -229,6 +232,7 @@ struct meson_sar_adc_priv {
        struct clk_gate                         clk_gate;
        struct clk                              *adc_div_clk;
        struct clk_divider                      clk_div;
+       struct completion                       done;
 };
 
 static const struct regmap_config meson_sar_adc_regmap_config = {
@@ -274,33 +278,31 @@ static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
                                         int *val)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
-       int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0;
+       int regval, fifo_chan, fifo_val, count;
 
-       ret = meson_sar_adc_wait_busy_clear(indio_dev);
-       if (ret)
-               return ret;
-
-       while (meson_sar_adc_get_fifo_count(indio_dev) > 0 &&
-              count < MESON_SAR_ADC_MAX_FIFO_SIZE) {
-               regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
-
-               fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK,
-                                     regval);
-               if (fifo_chan != chan->channel)
-                       continue;
-
-               fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK,
-                                    regval);
-               fifo_val &= (BIT(priv->data->resolution) - 1);
+       if(!wait_for_completion_timeout(&priv->done,
+                               msecs_to_jiffies(MESON_SAR_ADC_TIMEOUT)))
+               return -ETIMEDOUT;
 
-               sum += fifo_val;
-               count++;
+       count = meson_sar_adc_get_fifo_count(indio_dev);
+       if (count != 1) {
+               dev_err(&indio_dev->dev,
+                       "ADC FIFO has %d element(s) instead of one\n", count);
+               return -EINVAL;
        }
 
-       if (!count)
-               return -ENOENT;
+       regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
+       fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval);
+       if (fifo_chan != chan->channel) {
+               dev_err(&indio_dev->dev,
+                       "ADC FIFO entry belongs to channel %d instead of %d\n",
+                       fifo_chan, chan->channel);
+               return -EINVAL;
+       }
 
-       *val = sum / count;
+       fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, regval);
+       fifo_val &= GENMASK(priv->data->resolution - 1, 0);
+       *val = fifo_val;
 
        return 0;
 }
@@ -378,6 +380,12 @@ static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
 
+       reinit_completion(&priv->done);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_FIFO_IRQ_EN,
+                          MESON_SAR_ADC_REG0_FIFO_IRQ_EN);
+
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
                           MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
                           MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
@@ -392,6 +400,9 @@ static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev)
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
 
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_FIFO_IRQ_EN, 0);
+
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
                           MESON_SAR_ADC_REG0_SAMPLING_STOP,
                           MESON_SAR_ADC_REG0_SAMPLING_STOP);
 
@@ -643,6 +654,7 @@ static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
        int ret;
+       u32 regval;
 
        ret = meson_sar_adc_lock(indio_dev);
        if (ret)
@@ -667,6 +679,9 @@ static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev)
                goto err_sana_clk;
        }
 
+       regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1);
+       regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+                          MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval);
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
                           MESON_SAR_ADC_REG11_BANDGAP_EN,
                           MESON_SAR_ADC_REG11_BANDGAP_EN);
@@ -728,6 +743,25 @@ static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
        return 0;
 }
 
+static irqreturn_t meson_sar_adc_irq(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+       unsigned int cnt, threshold;
+       u32 regval;
+
+       regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
+       cnt = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval);
+       threshold = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval);
+
+       if (cnt < threshold)
+               return IRQ_NONE;
+
+       complete(&priv->done);
+
+       return IRQ_HANDLED;
+}
+
 static const struct iio_info meson_sar_adc_iio_info = {
        .read_raw = meson_sar_adc_iio_info_read_raw,
        .driver_module = THIS_MODULE,
@@ -770,7 +804,7 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
        struct resource *res;
        void __iomem *base;
        const struct of_device_id *match;
-       int ret;
+       int irq, ret;
 
        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
        if (!indio_dev) {
@@ -779,6 +813,7 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
        }
 
        priv = iio_priv(indio_dev);
+       init_completion(&priv->done);
 
        match = of_match_device(meson_sar_adc_of_match, &pdev->dev);
        priv->data = match->data;
@@ -797,6 +832,15 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
        if (IS_ERR(base))
                return PTR_ERR(base);
 
+       irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+       if (!irq)
+               return -EINVAL;
+
+       ret = devm_request_irq(&pdev->dev, irq, meson_sar_adc_irq, IRQF_SHARED,
+                              dev_name(&pdev->dev), indio_dev);
+       if (ret)
+               return ret;
+
        priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
                                             &meson_sar_adc_regmap_config);
        if (IS_ERR(priv->regmap))
index be2de48..2df84fa 100644 (file)
@@ -318,6 +318,7 @@ static int stx104_probe(struct device *dev, unsigned int id)
        }
 
        indio_dev->name = dev_name(dev);
+       indio_dev->dev.parent = dev;
 
        priv = iio_priv(indio_dev);
        priv->base = base[id];
index 7afdac4..9338f94 100644 (file)
@@ -62,6 +62,9 @@ static struct {
        {HID_USAGE_SENSOR_TIME_TIMESTAMP, 0, 1000000000, 0},
        {HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND,
                1000000, 0},
+
+       {HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0},
+       {HID_USAGE_SENSOR_TEMPERATURE, HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0},
 };
 
 static int pow_10(unsigned power)
index f9b8fc9..ba3d903 100644 (file)
@@ -551,6 +551,7 @@ static int quad8_probe(struct device *dev, unsigned int id)
        indio_dev->num_channels = ARRAY_SIZE(quad8_channels);
        indio_dev->channels = quad8_channels;
        indio_dev->name = dev_name(dev);
+       indio_dev->dev.parent = dev;
 
        priv = iio_priv(indio_dev);
        priv->base = base[id];
index 5a743e2..a046422 100644 (file)
@@ -119,6 +119,7 @@ static int cio_dac_probe(struct device *dev, unsigned int id)
        indio_dev->channels = cio_dac_channels;
        indio_dev->num_channels = CIO_DAC_NUM_CHAN;
        indio_dev->name = dev_name(dev);
+       indio_dev->dev.parent = dev;
 
        priv = iio_priv(indio_dev);
        priv->base = base[id];
index c5f004a..a2ecb4c 100644 (file)
@@ -46,6 +46,19 @@ config MAX30100
          To compile this driver as a module, choose M here: the
          module will be called max30100.
 
+config MAX30102
+       tristate "MAX30102 heart rate and pulse oximeter sensor"
+       depends on I2C
+       select REGMAP_I2C
+       select IIO_BUFFER
+       select IIO_KFIFO_BUF
+       help
+         Say Y here to build I2C interface support for the Maxim
+         MAX30102 heart rate, and pulse oximeter sensor.
+
+         To compile this driver as a module, choose M here: the
+         module will be called max30102.
+
 endmenu
 
 endmenu
index 9955a2a..3558f9d 100644 (file)
@@ -7,3 +7,4 @@
 obj-$(CONFIG_AFE4403)          += afe4403.o
 obj-$(CONFIG_AFE4404)          += afe4404.o
 obj-$(CONFIG_MAX30100)         += max30100.o
+obj-$(CONFIG_MAX30102)         += max30102.o
index f6e283c..849d717 100644 (file)
@@ -449,6 +449,7 @@ static int max30100_probe(struct i2c_client *client,
        indio_dev->available_scan_masks = max30100_scan_masks;
        indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE);
        indio_dev->setup_ops = &max30100_buffer_setup_ops;
+       indio_dev->dev.parent = &client->dev;
 
        data = iio_priv(indio_dev);
        data->indio_dev = indio_dev;
diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c
new file mode 100644 (file)
index 0000000..839b875
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * max30102.c - Support for MAX30102 heart rate and pulse oximeter sensor
+ *
+ * Copyright (C) 2017 Matt Ranostay <matt@ranostay.consulting>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * TODO: proximity power saving feature
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/kfifo_buf.h>
+
+#define MAX30102_REGMAP_NAME   "max30102_regmap"
+#define MAX30102_DRV_NAME      "max30102"
+
+#define MAX30102_REG_INT_STATUS                        0x00
+#define MAX30102_REG_INT_STATUS_PWR_RDY                BIT(0)
+#define MAX30102_REG_INT_STATUS_PROX_INT       BIT(4)
+#define MAX30102_REG_INT_STATUS_ALC_OVF                BIT(5)
+#define MAX30102_REG_INT_STATUS_PPG_RDY                BIT(6)
+#define MAX30102_REG_INT_STATUS_FIFO_RDY       BIT(7)
+
+#define MAX30102_REG_INT_ENABLE                        0x02
+#define MAX30102_REG_INT_ENABLE_PROX_INT_EN    BIT(4)
+#define MAX30102_REG_INT_ENABLE_ALC_OVF_EN     BIT(5)
+#define MAX30102_REG_INT_ENABLE_PPG_EN         BIT(6)
+#define MAX30102_REG_INT_ENABLE_FIFO_EN                BIT(7)
+#define MAX30102_REG_INT_ENABLE_MASK           0xf0
+#define MAX30102_REG_INT_ENABLE_MASK_SHIFT     4
+
+#define MAX30102_REG_FIFO_WR_PTR               0x04
+#define MAX30102_REG_FIFO_OVR_CTR              0x05
+#define MAX30102_REG_FIFO_RD_PTR               0x06
+#define MAX30102_REG_FIFO_DATA                 0x07
+#define MAX30102_REG_FIFO_DATA_ENTRY_LEN       6
+
+#define MAX30102_REG_FIFO_CONFIG               0x08
+#define MAX30102_REG_FIFO_CONFIG_AVG_4SAMPLES  BIT(1)
+#define MAX30102_REG_FIFO_CONFIG_AVG_SHIFT     5
+#define MAX30102_REG_FIFO_CONFIG_AFULL         BIT(0)
+
+#define MAX30102_REG_MODE_CONFIG               0x09
+#define MAX30102_REG_MODE_CONFIG_MODE_SPO2_EN  BIT(0)
+#define MAX30102_REG_MODE_CONFIG_MODE_HR_EN    BIT(1)
+#define MAX30102_REG_MODE_CONFIG_MODE_MASK     0x03
+#define MAX30102_REG_MODE_CONFIG_PWR           BIT(7)
+
+#define MAX30102_REG_SPO2_CONFIG               0x0a
+#define MAX30102_REG_SPO2_CONFIG_PULSE_411_US  0x03
+#define MAX30102_REG_SPO2_CONFIG_SR_400HZ      0x03
+#define MAX30102_REG_SPO2_CONFIG_SR_MASK       0x07
+#define MAX30102_REG_SPO2_CONFIG_SR_MASK_SHIFT 2
+#define MAX30102_REG_SPO2_CONFIG_ADC_4096_STEPS        BIT(0)
+#define MAX30102_REG_SPO2_CONFIG_ADC_MASK_SHIFT        5
+
+#define MAX30102_REG_RED_LED_CONFIG            0x0c
+#define MAX30102_REG_IR_LED_CONFIG             0x0d
+
+#define MAX30102_REG_TEMP_CONFIG               0x21
+#define MAX30102_REG_TEMP_CONFIG_TEMP_EN       BIT(0)
+
+#define MAX30102_REG_TEMP_INTEGER              0x1f
+#define MAX30102_REG_TEMP_FRACTION             0x20
+
+struct max30102_data {
+       struct i2c_client *client;
+       struct iio_dev *indio_dev;
+       struct mutex lock;
+       struct regmap *regmap;
+
+       u8 buffer[8];
+       __be32 processed_buffer[2]; /* 2 x 18-bit (padded to 32-bits) */
+};
+
+static const struct regmap_config max30102_regmap_config = {
+       .name = MAX30102_REGMAP_NAME,
+
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static const unsigned long max30102_scan_masks[] = {0x3, 0};
+
+static const struct iio_chan_spec max30102_channels[] = {
+       {
+               .type = IIO_INTENSITY,
+               .channel2 = IIO_MOD_LIGHT_RED,
+               .modified = 1,
+
+               .scan_index = 0,
+               .scan_type = {
+                       .sign = 'u',
+                       .shift = 8,
+                       .realbits = 18,
+                       .storagebits = 32,
+                       .endianness = IIO_BE,
+               },
+       },
+       {
+               .type = IIO_INTENSITY,
+               .channel2 = IIO_MOD_LIGHT_IR,
+               .modified = 1,
+
+               .scan_index = 1,
+               .scan_type = {
+                       .sign = 'u',
+                       .shift = 8,
+                       .realbits = 18,
+                       .storagebits = 32,
+                       .endianness = IIO_BE,
+               },
+       },
+       {
+               .type = IIO_TEMP,
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+               .scan_index = -1,
+       },
+};
+
+static int max30102_set_powermode(struct max30102_data *data, bool state)
+{
+       return regmap_update_bits(data->regmap, MAX30102_REG_MODE_CONFIG,
+                                 MAX30102_REG_MODE_CONFIG_PWR,
+                                 state ? 0 : MAX30102_REG_MODE_CONFIG_PWR);
+}
+
+static int max30102_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct max30102_data *data = iio_priv(indio_dev);
+
+       return max30102_set_powermode(data, true);
+}
+
+static int max30102_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct max30102_data *data = iio_priv(indio_dev);
+
+       return max30102_set_powermode(data, false);
+}
+
+static const struct iio_buffer_setup_ops max30102_buffer_setup_ops = {
+       .postenable = max30102_buffer_postenable,
+       .predisable = max30102_buffer_predisable,
+};
+
+static inline int max30102_fifo_count(struct max30102_data *data)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(data->regmap, MAX30102_REG_INT_STATUS, &val);
+       if (ret)
+               return ret;
+
+       /* FIFO has one sample slot left */
+       if (val & MAX30102_REG_INT_STATUS_FIFO_RDY)
+               return 1;
+
+       return 0;
+}
+
+static int max30102_read_measurement(struct max30102_data *data)
+{
+       int ret;
+       u8 *buffer = (u8 *) &data->buffer;
+
+       ret = i2c_smbus_read_i2c_block_data(data->client,
+                                           MAX30102_REG_FIFO_DATA,
+                                           MAX30102_REG_FIFO_DATA_ENTRY_LEN,
+                                           buffer);
+
+       memcpy(&data->processed_buffer[0], &buffer[0], 3);
+       memcpy(&data->processed_buffer[1], &buffer[3], 3);
+
+       return (ret == MAX30102_REG_FIFO_DATA_ENTRY_LEN) ? 0 : -EINVAL;
+}
+
+static irqreturn_t max30102_interrupt_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct max30102_data *data = iio_priv(indio_dev);
+       int ret, cnt = 0;
+
+       mutex_lock(&data->lock);
+
+       while (cnt || (cnt = max30102_fifo_count(data)) > 0) {
+               ret = max30102_read_measurement(data);
+               if (ret)
+                       break;
+
+               iio_push_to_buffers(data->indio_dev, data->processed_buffer);
+               cnt--;
+       }
+
+       mutex_unlock(&data->lock);
+
+       return IRQ_HANDLED;
+}
+
+static int max30102_get_current_idx(unsigned int val, int *reg)
+{
+       /* each step is 0.200 mA */
+       *reg = val / 200;
+
+       return *reg > 0xff ? -EINVAL : 0;
+}
+
+static int max30102_led_init(struct max30102_data *data)
+{
+       struct device *dev = &data->client->dev;
+       struct device_node *np = dev->of_node;
+       unsigned int val;
+       int reg, ret;
+
+       ret = of_property_read_u32(np, "maxim,red-led-current-microamp", &val);
+       if (ret) {
+               dev_info(dev, "no red-led-current-microamp set\n");
+
+               /* Default to 7 mA RED LED */
+               val = 7000;
+       }
+
+       ret = max30102_get_current_idx(val, &reg);
+       if (ret) {
+               dev_err(dev, "invalid RED LED current setting %d\n", val);
+               return ret;
+       }
+
+       ret = regmap_write(data->regmap, MAX30102_REG_RED_LED_CONFIG, reg);
+       if (ret)
+               return ret;
+
+       ret = of_property_read_u32(np, "maxim,ir-led-current-microamp", &val);
+       if (ret) {
+               dev_info(dev, "no ir-led-current-microamp set\n");
+
+               /* Default to 7 mA IR LED */
+               val = 7000;
+       }
+
+       ret = max30102_get_current_idx(val, &reg);
+       if (ret) {
+               dev_err(dev, "invalid IR LED current setting %d", val);
+               return ret;
+       }
+
+       return regmap_write(data->regmap, MAX30102_REG_IR_LED_CONFIG, reg);
+}
+
+static int max30102_chip_init(struct max30102_data *data)
+{
+       int ret;
+
+       /* setup LED current settings */
+       ret = max30102_led_init(data);
+       if (ret)
+               return ret;
+
+       /* enable 18-bit HR + SPO2 readings at 400Hz */
+       ret = regmap_write(data->regmap, MAX30102_REG_SPO2_CONFIG,
+                               (MAX30102_REG_SPO2_CONFIG_ADC_4096_STEPS
+                                << MAX30102_REG_SPO2_CONFIG_ADC_MASK_SHIFT) |
+                               (MAX30102_REG_SPO2_CONFIG_SR_400HZ
+                                << MAX30102_REG_SPO2_CONFIG_SR_MASK_SHIFT) |
+                                MAX30102_REG_SPO2_CONFIG_PULSE_411_US);
+       if (ret)
+               return ret;
+
+       /* enable SPO2 mode */
+       ret = regmap_update_bits(data->regmap, MAX30102_REG_MODE_CONFIG,
+                                MAX30102_REG_MODE_CONFIG_MODE_MASK,
+                                MAX30102_REG_MODE_CONFIG_MODE_HR_EN |
+                                MAX30102_REG_MODE_CONFIG_MODE_SPO2_EN);
+       if (ret)
+               return ret;
+
+       /* average 4 samples + generate FIFO interrupt */
+       ret = regmap_write(data->regmap, MAX30102_REG_FIFO_CONFIG,
+                               (MAX30102_REG_FIFO_CONFIG_AVG_4SAMPLES
+                                << MAX30102_REG_FIFO_CONFIG_AVG_SHIFT) |
+                                MAX30102_REG_FIFO_CONFIG_AFULL);
+       if (ret)
+               return ret;
+
+       /* enable FIFO interrupt */
+       return regmap_update_bits(data->regmap, MAX30102_REG_INT_ENABLE,
+                                MAX30102_REG_INT_ENABLE_MASK,
+                                MAX30102_REG_INT_ENABLE_FIFO_EN);
+}
+
+static int max30102_read_temp(struct max30102_data *data, int *val)
+{
+       int ret;
+       unsigned int reg;
+
+       ret = regmap_read(data->regmap, MAX30102_REG_TEMP_INTEGER, &reg);
+       if (ret < 0)
+               return ret;
+       *val = reg << 4;
+
+       ret = regmap_read(data->regmap, MAX30102_REG_TEMP_FRACTION, &reg);
+       if (ret < 0)
+               return ret;
+
+       *val |= reg & 0xf;
+       *val = sign_extend32(*val, 11);
+
+       return 0;
+}
+
+static int max30102_get_temp(struct max30102_data *data, int *val)
+{
+       int ret;
+
+       /* start acquisition */
+       ret = regmap_update_bits(data->regmap, MAX30102_REG_TEMP_CONFIG,
+                                MAX30102_REG_TEMP_CONFIG_TEMP_EN,
+                                MAX30102_REG_TEMP_CONFIG_TEMP_EN);
+       if (ret)
+               return ret;
+
+       msleep(35);
+
+       return max30102_read_temp(data, val);
+}
+
+static int max30102_read_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int *val, int *val2, long mask)
+{
+       struct max30102_data *data = iio_priv(indio_dev);
+       int ret = -EINVAL;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               /*
+                * Temperature reading can only be acquired while engine
+                * is running
+                */
+               mutex_lock(&indio_dev->mlock);
+
+               if (!iio_buffer_enabled(indio_dev))
+                       ret = -EBUSY;
+               else {
+                       ret = max30102_get_temp(data, val);
+                       if (!ret)
+                               ret = IIO_VAL_INT;
+               }
+
+               mutex_unlock(&indio_dev->mlock);
+               break;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 1;  /* 0.0625 */
+               *val2 = 16;
+               ret = IIO_VAL_FRACTIONAL;
+               break;
+       }
+
+       return ret;
+}
+
+static const struct iio_info max30102_info = {
+       .driver_module = THIS_MODULE,
+       .read_raw = max30102_read_raw,
+};
+
+static int max30102_probe(struct i2c_client *client,
+                         const struct i2c_device_id *id)
+{
+       struct max30102_data *data;
+       struct iio_buffer *buffer;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       buffer = devm_iio_kfifo_allocate(&client->dev);
+       if (!buffer)
+               return -ENOMEM;
+
+       iio_device_attach_buffer(indio_dev, buffer);
+
+       indio_dev->name = MAX30102_DRV_NAME;
+       indio_dev->channels = max30102_channels;
+       indio_dev->info = &max30102_info;
+       indio_dev->num_channels = ARRAY_SIZE(max30102_channels);
+       indio_dev->available_scan_masks = max30102_scan_masks;
+       indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE);
+       indio_dev->setup_ops = &max30102_buffer_setup_ops;
+       indio_dev->dev.parent = &client->dev;
+
+       data = iio_priv(indio_dev);
+       data->indio_dev = indio_dev;
+       data->client = client;
+
+       mutex_init(&data->lock);
+       i2c_set_clientdata(client, indio_dev);
+
+       data->regmap = devm_regmap_init_i2c(client, &max30102_regmap_config);
+       if (IS_ERR(data->regmap)) {
+               dev_err(&client->dev, "regmap initialization failed.\n");
+               return PTR_ERR(data->regmap);
+       }
+       max30102_set_powermode(data, false);
+
+       ret = max30102_chip_init(data);
+       if (ret)
+               return ret;
+
+       if (client->irq <= 0) {
+               dev_err(&client->dev, "no valid irq defined\n");
+               return -EINVAL;
+       }
+
+       ret = devm_request_threaded_irq(&client->dev, client->irq,
+                                       NULL, max30102_interrupt_handler,
+                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                       "max30102_irq", indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
+               return ret;
+       }
+
+       return iio_device_register(indio_dev);
+}
+
+static int max30102_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct max30102_data *data = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       max30102_set_powermode(data, false);
+
+       return 0;
+}
+
+static const struct i2c_device_id max30102_id[] = {
+       { "max30102", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, max30102_id);
+
+static const struct of_device_id max30102_dt_ids[] = {
+       { .compatible = "maxim,max30102" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, max30102_dt_ids);
+
+static struct i2c_driver max30102_driver = {
+       .driver = {
+               .name   = MAX30102_DRV_NAME,
+               .of_match_table = of_match_ptr(max30102_dt_ids),
+       },
+       .probe          = max30102_probe,
+       .remove         = max30102_remove,
+       .id_table       = max30102_id,
+};
+module_i2c_driver(max30102_driver);
+
+MODULE_AUTHOR("Matt Ranostay <matt@ranostay.consulting>");
+MODULE_DESCRIPTION("MAX30102 heart rate and pulse oximeter sensor");
+MODULE_LICENSE("GPL");
index 935d4cd..e573371 100644 (file)
@@ -8,7 +8,7 @@ config IIO_ST_LSM6DSX
        select IIO_ST_LSM6DSX_SPI if (SPI_MASTER)
        help
          Say yes here to build support for STMicroelectronics LSM6DSx imu
-         sensor. Supported devices: lsm6ds3, lsm6dsm
+         sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm
 
          To compile this driver as a module, choose M here: the module
          will be called st_lsm6dsx.
index 69deafe..6a9849e 100644 (file)
 #include <linux/device.h>
 
 #define ST_LSM6DS3_DEV_NAME    "lsm6ds3"
+#define ST_LSM6DS3H_DEV_NAME   "lsm6ds3h"
+#define ST_LSM6DSL_DEV_NAME    "lsm6dsl"
 #define ST_LSM6DSM_DEV_NAME    "lsm6dsm"
 
 enum st_lsm6dsx_hw_id {
        ST_LSM6DS3_ID,
+       ST_LSM6DS3H_ID,
+       ST_LSM6DSL_ID,
        ST_LSM6DSM_ID,
+       ST_LSM6DSX_MAX_ID,
 };
 
 #define ST_LSM6DSX_CHAN_SIZE           2
@@ -50,7 +55,7 @@ struct st_lsm6dsx_reg {
 struct st_lsm6dsx_settings {
        u8 wai;
        u16 max_fifo_size;
-       enum st_lsm6dsx_hw_id id;
+       enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID];
 };
 
 enum st_lsm6dsx_sensor_id {
index 78532ce..e71ecce 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * STMicroelectronics st_lsm6dsx FIFO buffer library driver
  *
- * LSM6DS3/LSM6DSM: The FIFO buffer can be configured to store data
- * from gyroscope and accelerometer. Samples are queued without any tag
- * according to a specific pattern based on 'FIFO data sets' (6 bytes each):
+ * LSM6DS3/LSM6DS3H/LSM6DSL/LSM6DSM: The FIFO buffer can be configured
+ * to store data from gyroscope and accelerometer. Samples are queued
+ * without any tag according to a specific pattern based on 'FIFO data sets'
+ * (6 bytes each):
  *  - 1st data set is reserved for gyroscope data
  *  - 2nd data set is reserved for accelerometer data
  * The FIFO pattern changes depending on the ODRs and decimation factors
@@ -206,7 +207,7 @@ out:
 }
 
 /**
- * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DSM read FIFO routine
+ * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DS3H-LSM6DSL-LSM6DSM read FIFO routine
  * @hw: Pointer to instance of struct st_lsm6dsx_hw.
  *
  * Read samples from the hw FIFO and push them to IIO buffers.
index c92ddcc..c433223 100644 (file)
@@ -17,7 +17,7 @@
  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
  *   - FIFO size: 8KB
  *
- * - LSM6DSM:
+ * - LSM6DS3H/LSM6DSL/LSM6DSM:
  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
 #define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR       0x24
 #define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR       0x26
 
-#define ST_LSM6DS3_WHOAMI                      0x69
-#define ST_LSM6DSM_WHOAMI                      0x6a
-
-#define ST_LSM6DS3_MAX_FIFO_SIZE               8192
-#define ST_LSM6DSM_MAX_FIFO_SIZE               4096
-
 #define ST_LSM6DSX_ACC_FS_2G_GAIN              IIO_G_TO_M_S_2(61)
 #define ST_LSM6DSX_ACC_FS_4G_GAIN              IIO_G_TO_M_S_2(122)
 #define ST_LSM6DSX_ACC_FS_8G_GAIN              IIO_G_TO_M_S_2(244)
@@ -164,14 +158,26 @@ static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
 
 static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
        {
-               .wai = ST_LSM6DS3_WHOAMI,
-               .max_fifo_size = ST_LSM6DS3_MAX_FIFO_SIZE,
-               .id = ST_LSM6DS3_ID,
+               .wai = 0x69,
+               .max_fifo_size = 8192,
+               .id = {
+                       [0] = ST_LSM6DS3_ID,
+               },
        },
        {
-               .wai = ST_LSM6DSM_WHOAMI,
-               .max_fifo_size = ST_LSM6DSM_MAX_FIFO_SIZE,
-               .id = ST_LSM6DSM_ID,
+               .wai = 0x69,
+               .max_fifo_size = 4096,
+               .id = {
+                       [0] = ST_LSM6DS3H_ID,
+               },
+       },
+       {
+               .wai = 0x6a,
+               .max_fifo_size = 4096,
+               .id = {
+                       [0] = ST_LSM6DSL_ID,
+                       [1] = ST_LSM6DSM_ID,
+               },
        },
 };
 
@@ -241,11 +247,15 @@ out:
 
 static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id)
 {
-       int err, i;
+       int err, i, j;
        u8 data;
 
        for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
-               if (id == st_lsm6dsx_sensor_settings[i].id)
+               for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
+                       if (id == st_lsm6dsx_sensor_settings[i].id[j])
+                               break;
+               }
+               if (j < ST_LSM6DSX_MAX_ID)
                        break;
        }
 
index ea30411..2e4ed26 100644 (file)
@@ -71,6 +71,14 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
                .data = (void *)ST_LSM6DS3_ID,
        },
        {
+               .compatible = "st,lsm6ds3h",
+               .data = (void *)ST_LSM6DS3H_ID,
+       },
+       {
+               .compatible = "st,lsm6dsl",
+               .data = (void *)ST_LSM6DSL_ID,
+       },
+       {
                .compatible = "st,lsm6dsm",
                .data = (void *)ST_LSM6DSM_ID,
        },
@@ -80,6 +88,8 @@ MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
 
 static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
        { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
+       { ST_LSM6DS3H_DEV_NAME, ST_LSM6DS3H_ID },
+       { ST_LSM6DSL_DEV_NAME, ST_LSM6DSL_ID },
        { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
        {},
 };
index fbe7247..1bf4a58 100644 (file)
@@ -88,6 +88,14 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
                .data = (void *)ST_LSM6DS3_ID,
        },
        {
+               .compatible = "st,lsm6ds3h",
+               .data = (void *)ST_LSM6DS3H_ID,
+       },
+       {
+               .compatible = "st,lsm6dsl",
+               .data = (void *)ST_LSM6DSL_ID,
+       },
+       {
                .compatible = "st,lsm6dsm",
                .data = (void *)ST_LSM6DSM_ID,
        },
@@ -97,6 +105,8 @@ MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
 
 static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
        { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
+       { ST_LSM6DS3H_DEV_NAME, ST_LSM6DS3H_ID },
+       { ST_LSM6DSL_DEV_NAME, ST_LSM6DSL_ID },
        { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
        {},
 };
index 5f731ea..2afcbac 100644 (file)
@@ -136,6 +136,16 @@ config CM36651
         To compile this driver as a module, choose M here:
         the module will be called cm36651.
 
+config IIO_CROS_EC_LIGHT_PROX
+       tristate "ChromeOS EC Light and Proximity Sensors"
+       depends on IIO_CROS_EC_SENSORS_CORE
+       help
+         Say Y here if you use the light and proximity sensors
+         presented by the ChromeOS EC Sensor hub.
+
+         To compile this driver as a module, choose M here:
+         the module will be called cros_ec_light_prox.
+
 config GP2AP020A00F
        tristate "Sharp GP2AP020A00F Proximity/ALS sensor"
        depends on I2C
index c13a239..edfd69b 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_CM3232)          += cm3232.o
 obj-$(CONFIG_CM3323)           += cm3323.o
 obj-$(CONFIG_CM3605)           += cm3605.o
 obj-$(CONFIG_CM36651)          += cm36651.o
+obj-$(CONFIG_IIO_CROS_EC_LIGHT_PROX) += cros_ec_light_prox.o
 obj-$(CONFIG_GP2AP020A00F)     += gp2ap020a00f.o
 obj-$(CONFIG_HID_SENSOR_ALS)   += hid-sensor-als.o
 obj-$(CONFIG_HID_SENSOR_PROX)  += hid-sensor-prox.o
diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c
new file mode 100644 (file)
index 0000000..7217223
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * cros_ec_light_prox - Driver for light and prox sensors behing CrosEC.
+ *
+ * Copyright (C) 2017 Google, Inc
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/kernel.h>
+#include <linux/mfd/cros_ec.h>
+#include <linux/mfd/cros_ec_commands.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../common/cros_ec_sensors/cros_ec_sensors_core.h"
+
+/*
+ * We only represent one entry for light or proximity. EC is merging different
+ * light sensors to return the what the eye would see. For proximity, we
+ * currently support only one light source.
+ */
+#define CROS_EC_LIGHT_PROX_MAX_CHANNELS (1 + 1)
+
+/* State data for ec_sensors iio driver. */
+struct cros_ec_light_prox_state {
+       /* Shared by all sensors */
+       struct cros_ec_sensors_core_state core;
+
+       struct iio_chan_spec channels[CROS_EC_LIGHT_PROX_MAX_CHANNELS];
+};
+
+static int cros_ec_light_prox_read(struct iio_dev *indio_dev,
+                                  struct iio_chan_spec const *chan,
+                                  int *val, int *val2, long mask)
+{
+       struct cros_ec_light_prox_state *st = iio_priv(indio_dev);
+       u16 data = 0;
+       s64 val64;
+       int ret = IIO_VAL_INT;
+       int idx = chan->scan_index;
+
+       mutex_lock(&st->core.cmd_lock);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (chan->type == IIO_PROXIMITY) {
+                       if (cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
+                                                    (s16 *)&data) < 0) {
+                               ret = -EIO;
+                               break;
+                       }
+                       *val = data;
+               } else {
+                       ret = -EINVAL;
+               }
+               break;
+       case IIO_CHAN_INFO_PROCESSED:
+               if (chan->type == IIO_LIGHT) {
+                       if (cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
+                                                    (s16 *)&data) < 0) {
+                               ret = -EIO;
+                               break;
+                       }
+                       /*
+                        * The data coming from the light sensor is
+                        * pre-processed and represents the ambient light
+                        * illuminance reading expressed in lux.
+                        */
+                       *val = data;
+                       ret = IIO_VAL_INT;
+               } else {
+                       ret = -EINVAL;
+               }
+               break;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
+               st->core.param.sensor_offset.flags = 0;
+
+               if (cros_ec_motion_send_host_cmd(&st->core, 0)) {
+                       ret = -EIO;
+                       break;
+               }
+
+               /* Save values */
+               st->core.calib[0] = st->core.resp->sensor_offset.offset[0];
+
+               *val = st->core.calib[idx];
+               break;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               /*
+                * RANGE is used for calibration
+                * scale is a number x.y, where x is coded on 16 bits,
+                * y coded on 16 bits, between 0 and 9999.
+                */
+               st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
+               st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
+
+               if (cros_ec_motion_send_host_cmd(&st->core, 0)) {
+                       ret = -EIO;
+                       break;
+               }
+
+               val64 = st->core.resp->sensor_range.ret;
+               *val = val64 >> 16;
+               *val2 = (val64 & 0xffff) * 100;
+               ret = IIO_VAL_INT_PLUS_MICRO;
+               break;
+       default:
+               ret = cros_ec_sensors_core_read(&st->core, chan, val, val2,
+                                               mask);
+               break;
+       }
+
+       mutex_unlock(&st->core.cmd_lock);
+
+       return ret;
+}
+
+static int cros_ec_light_prox_write(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val, int val2, long mask)
+{
+       struct cros_ec_light_prox_state *st = iio_priv(indio_dev);
+       int ret = 0;
+       int idx = chan->scan_index;
+
+       mutex_lock(&st->core.cmd_lock);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_CALIBBIAS:
+               st->core.calib[idx] = val;
+               /* Send to EC for each axis, even if not complete */
+               st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
+               st->core.param.sensor_offset.flags = MOTION_SENSE_SET_OFFSET;
+               st->core.param.sensor_offset.offset[0] = st->core.calib[0];
+               st->core.param.sensor_offset.temp =
+                                       EC_MOTION_SENSE_INVALID_CALIB_TEMP;
+               if (cros_ec_motion_send_host_cmd(&st->core, 0))
+                       ret = -EIO;
+               break;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
+               st->core.param.sensor_range.data = (val << 16) | (val2 / 100);
+               if (cros_ec_motion_send_host_cmd(&st->core, 0))
+                       ret = -EIO;
+               break;
+       default:
+               ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
+                                                mask);
+               break;
+       }
+
+       mutex_unlock(&st->core.cmd_lock);
+
+       return ret;
+}
+
+static const struct iio_info cros_ec_light_prox_info = {
+       .read_raw = &cros_ec_light_prox_read,
+       .write_raw = &cros_ec_light_prox_write,
+       .driver_module = THIS_MODULE,
+};
+
+static int cros_ec_light_prox_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
+       struct cros_ec_device *ec_device;
+       struct iio_dev *indio_dev;
+       struct cros_ec_light_prox_state *state;
+       struct iio_chan_spec *channel;
+       int ret;
+
+       if (!ec_dev || !ec_dev->ec_dev) {
+               dev_warn(dev, "No CROS EC device found.\n");
+               return -EINVAL;
+       }
+       ec_device = ec_dev->ec_dev;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
+       if (ret)
+               return ret;
+
+       indio_dev->info = &cros_ec_light_prox_info;
+       state = iio_priv(indio_dev);
+       state->core.type = state->core.resp->info.type;
+       state->core.loc = state->core.resp->info.location;
+       channel = state->channels;
+
+       /* Common part */
+       channel->info_mask_shared_by_all =
+               BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+               BIT(IIO_CHAN_INFO_FREQUENCY);
+       channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
+       channel->scan_type.storagebits = CROS_EC_SENSOR_BITS;
+       channel->scan_type.shift = 0;
+       channel->scan_index = 0;
+       channel->ext_info = cros_ec_sensors_ext_info;
+       channel->scan_type.sign = 'u';
+
+       state->core.calib[0] = 0;
+
+       /* Sensor specific */
+       switch (state->core.type) {
+       case MOTIONSENSE_TYPE_LIGHT:
+               channel->type = IIO_LIGHT;
+               channel->info_mask_separate =
+                       BIT(IIO_CHAN_INFO_PROCESSED) |
+                       BIT(IIO_CHAN_INFO_CALIBBIAS) |
+                       BIT(IIO_CHAN_INFO_CALIBSCALE);
+               break;
+       case MOTIONSENSE_TYPE_PROX:
+               channel->type = IIO_PROXIMITY;
+               channel->info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_CALIBBIAS) |
+                       BIT(IIO_CHAN_INFO_CALIBSCALE);
+               break;
+       default:
+               dev_warn(dev, "Unknown motion sensor\n");
+               return -EINVAL;
+       }
+
+       /* Timestamp */
+       channel++;
+       channel->type = IIO_TIMESTAMP;
+       channel->channel = -1;
+       channel->scan_index = 1;
+       channel->scan_type.sign = 's';
+       channel->scan_type.realbits = 64;
+       channel->scan_type.storagebits = 64;
+
+       indio_dev->channels = state->channels;
+
+       indio_dev->num_channels = CROS_EC_LIGHT_PROX_MAX_CHANNELS;
+
+       state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+
+       ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
+                                             cros_ec_sensors_capture, NULL);
+       if (ret)
+               return ret;
+
+       return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct platform_device_id cros_ec_light_prox_ids[] = {
+       {
+               .name = "cros-ec-prox",
+       },
+       {
+               .name = "cros-ec-light",
+       },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, cros_ec_light_prox_ids);
+
+static struct platform_driver cros_ec_light_prox_platform_driver = {
+       .driver = {
+               .name   = "cros-ec-light-prox",
+       },
+       .probe          = cros_ec_light_prox_probe,
+       .id_table       = cros_ec_light_prox_ids,
+};
+module_platform_driver(cros_ec_light_prox_platform_driver);
+
+MODULE_DESCRIPTION("ChromeOS EC light/proximity sensors driver");
+MODULE_LICENSE("GPL v2");
index 45ca056..73fced8 100644 (file)
@@ -240,6 +240,13 @@ static int prox_parse_report(struct platform_device *pdev,
                        st->common_attributes.sensitivity.index,
                        st->common_attributes.sensitivity.report_id);
        }
+       if (st->common_attributes.sensitivity.index < 0)
+               sensor_hub_input_get_attribute_info(hsdev,
+                       HID_FEATURE_REPORT, usage_id,
+                       HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+                       HID_USAGE_SENSOR_HUMAN_PRESENCE,
+                       &st->common_attributes.sensitivity);
+
        return ret;
 }
 
index e227143..afa8de3 100644 (file)
@@ -325,6 +325,7 @@ static int lmp91000_probe(struct i2c_client *client,
        indio_dev->channels = lmp91000_channels;
        indio_dev->num_channels = ARRAY_SIZE(lmp91000_channels);
        indio_dev->name = LMP91000_DRV_NAME;
+       indio_dev->dev.parent = &client->dev;
        indio_dev->modes = INDIO_DIRECT_MODE;
        i2c_set_clientdata(client, indio_dev);
 
index ab96cb7..5b81a8c 100644 (file)
@@ -32,6 +32,17 @@ config LIDAR_LITE_V2
          To compile this driver as a module, choose M here: the
          module will be called pulsedlight-lite-v2
 
+config SRF04
+       tristate "Devantech SRF04 ultrasonic ranger sensor"
+       depends on GPIOLIB
+       help
+         Say Y here to build a driver for Devantech SRF04 ultrasonic
+         ranger sensor. This driver can be used to measure the distance
+         of objects. It is using two GPIOs.
+
+         To compile this driver as a module, choose M here: the
+         module will be called srf04.
+
 config SX9500
        tristate "SX9500 Semtech proximity sensor"
        select IIO_BUFFER
index e914c2a..ed1b6f4 100644 (file)
@@ -5,5 +5,6 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AS3935)           += as3935.o
 obj-$(CONFIG_LIDAR_LITE_V2)    += pulsedlight-lidar-lite-v2.o
+obj-$(CONFIG_SRF04)            += srf04.o
 obj-$(CONFIG_SRF08)            += srf08.o
 obj-$(CONFIG_SX9500)           += sx9500.o
index 20c16a0..36c1ddc 100644 (file)
@@ -278,6 +278,7 @@ static int lidar_probe(struct i2c_client *client,
        indio_dev->name = LIDAR_DRV_NAME;
        indio_dev->channels = lidar_channels;
        indio_dev->num_channels = ARRAY_SIZE(lidar_channels);
+       indio_dev->dev.parent = &client->dev;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
        i2c_set_clientdata(client, indio_dev);
diff --git a/drivers/iio/proximity/srf04.c b/drivers/iio/proximity/srf04.c
new file mode 100644 (file)
index 0000000..e37667f
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * SRF04: ultrasonic sensor for distance measuring by using GPIOs
+ *
+ * Copyright (c) 2017 Andreas Klinger <ak@it-klinger.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * For details about the device see:
+ * http://www.robot-electronics.co.uk/htm/srf04tech.htm
+ *
+ * the measurement cycle as timing diagram looks like:
+ *
+ *          +---+
+ * GPIO     |   |
+ * trig:  --+   +------------------------------------------------------
+ *          ^   ^
+ *          |<->|
+ *         udelay(10)
+ *
+ * ultra           +-+ +-+ +-+
+ * sonic           | | | | | |
+ * burst: ---------+ +-+ +-+ +-----------------------------------------
+ *                           .
+ * ultra                     .              +-+ +-+ +-+
+ * sonic                     .              | | | | | |
+ * echo:  ----------------------------------+ +-+ +-+ +----------------
+ *                           .                        .
+ *                           +------------------------+
+ * GPIO                      |                        |
+ * echo:  -------------------+                        +---------------
+ *                           ^                        ^
+ *                           interrupt                interrupt
+ *                           (ts_rising)              (ts_falling)
+ *                           |<---------------------->|
+ *                              pulse time measured
+ *                              --> one round trip of ultra sonic waves
+ */
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+struct srf04_data {
+       struct device           *dev;
+       struct gpio_desc        *gpiod_trig;
+       struct gpio_desc        *gpiod_echo;
+       struct mutex            lock;
+       int                     irqnr;
+       ktime_t                 ts_rising;
+       ktime_t                 ts_falling;
+       struct completion       rising;
+       struct completion       falling;
+};
+
+static irqreturn_t srf04_handle_irq(int irq, void *dev_id)
+{
+       struct iio_dev *indio_dev = dev_id;
+       struct srf04_data *data = iio_priv(indio_dev);
+       ktime_t now = ktime_get();
+
+       if (gpiod_get_value(data->gpiod_echo)) {
+               data->ts_rising = now;
+               complete(&data->rising);
+       } else {
+               data->ts_falling = now;
+               complete(&data->falling);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static int srf04_read(struct srf04_data *data)
+{
+       int ret;
+       ktime_t ktime_dt;
+       u64 dt_ns;
+       u32 time_ns, distance_mm;
+
+       /*
+        * just one read-echo-cycle can take place at a time
+        * ==> lock against concurrent reading calls
+        */
+       mutex_lock(&data->lock);
+
+       reinit_completion(&data->rising);
+       reinit_completion(&data->falling);
+
+       gpiod_set_value(data->gpiod_trig, 1);
+       udelay(10);
+       gpiod_set_value(data->gpiod_trig, 0);
+
+       /* it cannot take more than 20 ms */
+       ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               return ret;
+       } else if (ret == 0) {
+               mutex_unlock(&data->lock);
+               return -ETIMEDOUT;
+       }
+
+       ret = wait_for_completion_killable_timeout(&data->falling, HZ/50);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               return ret;
+       } else if (ret == 0) {
+               mutex_unlock(&data->lock);
+               return -ETIMEDOUT;
+       }
+
+       ktime_dt = ktime_sub(data->ts_falling, data->ts_rising);
+
+       mutex_unlock(&data->lock);
+
+       dt_ns = ktime_to_ns(ktime_dt);
+       /*
+        * measuring more than 3 meters is beyond the capabilities of
+        * the sensor
+        * ==> filter out invalid results for not measuring echos of
+        *     another us sensor
+        *
+        * formula:
+        *         distance       3 m
+        * time = ---------- = --------- = 9404389 ns
+        *          speed       319 m/s
+        *
+        * using a minimum speed at -20 Â°C of 319 m/s
+        */
+       if (dt_ns > 9404389)
+               return -EIO;
+
+       time_ns = dt_ns;
+
+       /*
+        * the speed as function of the temperature is approximately:
+        *
+        * speed = 331,5 + 0,6 * Temp
+        *   with Temp in Â°C
+        *   and speed in m/s
+        *
+        * use 343 m/s as ultrasonic speed at 20 Â°C here in absence of the
+        * temperature
+        *
+        * therefore:
+        *             time     343
+        * distance = ------ * -----
+        *             10^6       2
+        *   with time in ns
+        *   and distance in mm (one way)
+        *
+        * because we limit to 3 meters the multiplication with 343 just
+        * fits into 32 bit
+        */
+       distance_mm = time_ns * 343 / 2000000;
+
+       return distance_mm;
+}
+
+static int srf04_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *channel, int *val,
+                           int *val2, long info)
+{
+       struct srf04_data *data = iio_priv(indio_dev);
+       int ret;
+
+       if (channel->type != IIO_DISTANCE)
+               return -EINVAL;
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+               ret = srf04_read(data);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /*
+                * theoretical maximum resolution is 3 mm
+                * 1 LSB is 1 mm
+                */
+               *val = 0;
+               *val2 = 1000;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info srf04_iio_info = {
+       .driver_module          = THIS_MODULE,
+       .read_raw               = srf04_read_raw,
+};
+
+static const struct iio_chan_spec srf04_chan_spec[] = {
+       {
+               .type = IIO_DISTANCE,
+               .info_mask_separate =
+                               BIT(IIO_CHAN_INFO_RAW) |
+                               BIT(IIO_CHAN_INFO_SCALE),
+       },
+};
+
+static int srf04_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct srf04_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(struct srf04_data));
+       if (!indio_dev) {
+               dev_err(dev, "failed to allocate IIO device\n");
+               return -ENOMEM;
+       }
+
+       data = iio_priv(indio_dev);
+       data->dev = dev;
+
+       mutex_init(&data->lock);
+       init_completion(&data->rising);
+       init_completion(&data->falling);
+
+       data->gpiod_trig = devm_gpiod_get(dev, "trig", GPIOD_OUT_LOW);
+       if (IS_ERR(data->gpiod_trig)) {
+               dev_err(dev, "failed to get trig-gpios: err=%ld\n",
+                                       PTR_ERR(data->gpiod_trig));
+               return PTR_ERR(data->gpiod_trig);
+       }
+
+       data->gpiod_echo = devm_gpiod_get(dev, "echo", GPIOD_IN);
+       if (IS_ERR(data->gpiod_echo)) {
+               dev_err(dev, "failed to get echo-gpios: err=%ld\n",
+                                       PTR_ERR(data->gpiod_echo));
+               return PTR_ERR(data->gpiod_echo);
+       }
+
+       if (gpiod_cansleep(data->gpiod_echo)) {
+               dev_err(data->dev, "cansleep-GPIOs not supported\n");
+               return -ENODEV;
+       }
+
+       data->irqnr = gpiod_to_irq(data->gpiod_echo);
+       if (data->irqnr < 0) {
+               dev_err(data->dev, "gpiod_to_irq: %d\n", data->irqnr);
+               return data->irqnr;
+       }
+
+       ret = devm_request_irq(dev, data->irqnr, srf04_handle_irq,
+                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                       pdev->name, indio_dev);
+       if (ret < 0) {
+               dev_err(data->dev, "request_irq: %d\n", ret);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, indio_dev);
+
+       indio_dev->name = "srf04";
+       indio_dev->dev.parent = &pdev->dev;
+       indio_dev->info = &srf04_iio_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = srf04_chan_spec;
+       indio_dev->num_channels = ARRAY_SIZE(srf04_chan_spec);
+
+       return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct of_device_id of_srf04_match[] = {
+       { .compatible = "devantech,srf04", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, of_srf04_match);
+
+static struct platform_driver srf04_driver = {
+       .probe          = srf04_probe,
+       .driver         = {
+               .name           = "srf04-gpio",
+               .of_match_table = of_srf04_match,
+       },
+};
+
+module_platform_driver(srf04_driver);
+
+MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
+MODULE_DESCRIPTION("SRF04 ultrasonic sensor for distance measuring using GPIOs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:srf04");
index 3089e8d..5378976 100644 (file)
@@ -19,6 +19,20 @@ config MAXIM_THERMOCOUPLE
          This driver can also be built as a module. If so, the module will
          be called maxim_thermocouple.
 
+config HID_SENSOR_TEMP
+       tristate "HID Environmental temperature sensor"
+       depends on HID_SENSOR_HUB
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       select HID_SENSOR_IIO_COMMON
+       select HID_SENSOR_IIO_TRIGGER
+       help
+         Say yes here to build support for the HID SENSOR
+         temperature driver
+
+         To compile this driver as a module, choose M here: the module
+         will be called hid-sensor-temperature.
+
 config MLX90614
        tristate "MLX90614 contact-less infrared sensor"
        depends on I2C
index 4c43774..ad1d668 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for industrial I/O temperature drivers
 #
 
+obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o
 obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o
 obj-$(CONFIG_MLX90614) += mlx90614.o
 obj-$(CONFIG_TMP006) += tmp006.o
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
new file mode 100644 (file)
index 0000000..c01efec
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * HID Sensors Driver
+ * Copyright (c) 2017, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.
+ */
+#include <linux/device.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "../common/hid-sensors/hid-sensor-trigger.h"
+
+struct temperature_state {
+       struct hid_sensor_common common_attributes;
+       struct hid_sensor_hub_attribute_info temperature_attr;
+       s32 temperature_data;
+       int scale_pre_decml;
+       int scale_post_decml;
+       int scale_precision;
+       int value_offset;
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec temperature_channels[] = {
+       {
+               .type = IIO_TEMP,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+                       BIT(IIO_CHAN_INFO_HYSTERESIS),
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+/* Adjust channel real bits based on report descriptor */
+static void temperature_adjust_channel_bit_mask(struct iio_chan_spec *channels,
+                                       int channel, int size)
+{
+       channels[channel].scan_type.sign = 's';
+       /* Real storage bits will change based on the report desc. */
+       channels[channel].scan_type.realbits = size * 8;
+       /* Maximum size of a sample to capture is s32 */
+       channels[channel].scan_type.storagebits = sizeof(s32) * 8;
+}
+
+static int temperature_read_raw(struct iio_dev *indio_dev,
+                               struct iio_chan_spec const *chan,
+                               int *val, int *val2, long mask)
+{
+       struct temperature_state *temp_st = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (chan->type != IIO_TEMP)
+                       return -EINVAL;
+               hid_sensor_power_state(
+                       &temp_st->common_attributes, true);
+               *val = sensor_hub_input_attr_get_raw_value(
+                       temp_st->common_attributes.hsdev,
+                       HID_USAGE_SENSOR_TEMPERATURE,
+                       HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                       temp_st->temperature_attr.report_id,
+                       SENSOR_HUB_SYNC);
+               hid_sensor_power_state(
+                               &temp_st->common_attributes,
+                               false);
+
+               return IIO_VAL_INT;
+
+       case IIO_CHAN_INFO_SCALE:
+               *val = temp_st->scale_pre_decml;
+               *val2 = temp_st->scale_post_decml;
+               return temp_st->scale_precision;
+
+       case IIO_CHAN_INFO_OFFSET:
+               *val = temp_st->value_offset;
+               return IIO_VAL_INT;
+
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return hid_sensor_read_samp_freq_value(
+                               &temp_st->common_attributes, val, val2);
+
+       case IIO_CHAN_INFO_HYSTERESIS:
+               return hid_sensor_read_raw_hyst_value(
+                               &temp_st->common_attributes, val, val2);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int temperature_write_raw(struct iio_dev *indio_dev,
+                               struct iio_chan_spec const *chan,
+                               int val, int val2, long mask)
+{
+       struct temperature_state *temp_st = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return hid_sensor_write_samp_freq_value(
+                               &temp_st->common_attributes, val, val2);
+       case IIO_CHAN_INFO_HYSTERESIS:
+               return hid_sensor_write_raw_hyst_value(
+                               &temp_st->common_attributes, val, val2);
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info temperature_info = {
+       .driver_module = THIS_MODULE,
+       .read_raw = &temperature_read_raw,
+       .write_raw = &temperature_write_raw,
+};
+
+/* Callback handler to send event after all samples are received and captured */
+static int temperature_proc_event(struct hid_sensor_hub_device *hsdev,
+                               unsigned int usage_id, void *pdev)
+{
+       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct temperature_state *temp_st = iio_priv(indio_dev);
+
+       if (atomic_read(&temp_st->common_attributes.data_ready))
+               iio_push_to_buffers_with_timestamp(indio_dev,
+                               &temp_st->temperature_data,
+                               iio_get_time_ns(indio_dev));
+
+       return 0;
+}
+
+/* Capture samples in local storage */
+static int temperature_capture_sample(struct hid_sensor_hub_device *hsdev,
+                               unsigned int usage_id, size_t raw_len,
+                               char *raw_data, void *pdev)
+{
+       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct temperature_state *temp_st = iio_priv(indio_dev);
+
+       switch (usage_id) {
+       case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE:
+               temp_st->temperature_data = *(s32 *)raw_data;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+/* Parse report which is specific to an usage id*/
+static int temperature_parse_report(struct platform_device *pdev,
+                               struct hid_sensor_hub_device *hsdev,
+                               struct iio_chan_spec *channels,
+                               unsigned int usage_id,
+                               struct temperature_state *st)
+{
+       int ret;
+
+       ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
+                       usage_id,
+                       HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                       &st->temperature_attr);
+       if (ret < 0)
+               return ret;
+
+       temperature_adjust_channel_bit_mask(channels, 0,
+                                       st->temperature_attr.size);
+
+       st->scale_precision = hid_sensor_format_scale(
+                               HID_USAGE_SENSOR_TEMPERATURE,
+                               &st->temperature_attr,
+                               &st->scale_pre_decml, &st->scale_post_decml);
+
+       /* Set Sensitivity field ids, when there is no individual modifier */
+       if (st->common_attributes.sensitivity.index < 0)
+               sensor_hub_input_get_attribute_info(hsdev,
+                       HID_FEATURE_REPORT, usage_id,
+                       HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+                       HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                       &st->common_attributes.sensitivity);
+
+       return ret;
+}
+
+static struct hid_sensor_hub_callbacks temperature_callbacks = {
+       .send_event = &temperature_proc_event,
+       .capture_sample = &temperature_capture_sample,
+};
+
+/* Function to initialize the processing for usage id */
+static int hid_temperature_probe(struct platform_device *pdev)
+{
+       static const char *name = "temperature";
+       struct iio_dev *indio_dev;
+       struct temperature_state *temp_st;
+       struct iio_chan_spec *temp_chans;
+       struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*temp_st));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       temp_st = iio_priv(indio_dev);
+       temp_st->common_attributes.hsdev = hsdev;
+       temp_st->common_attributes.pdev = pdev;
+
+       ret = hid_sensor_parse_common_attributes(hsdev,
+                                       HID_USAGE_SENSOR_TEMPERATURE,
+                                       &temp_st->common_attributes);
+       if (ret)
+               return ret;
+
+       temp_chans = devm_kmemdup(&indio_dev->dev, temperature_channels,
+                               sizeof(temperature_channels), GFP_KERNEL);
+       if (!temp_chans)
+               return -ENOMEM;
+
+       ret = temperature_parse_report(pdev, hsdev, temp_chans,
+                               HID_USAGE_SENSOR_TEMPERATURE, temp_st);
+       if (ret)
+               return ret;
+
+       indio_dev->channels = temp_chans;
+       indio_dev->num_channels = ARRAY_SIZE(temperature_channels);
+       indio_dev->dev.parent = &pdev->dev;
+       indio_dev->info = &temperature_info;
+       indio_dev->name = name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = devm_iio_triggered_buffer_setup(&pdev->dev, indio_dev,
+                                       &iio_pollfunc_store_time, NULL, NULL);
+       if (ret)
+               return ret;
+
+       atomic_set(&temp_st->common_attributes.data_ready, 0);
+       ret = hid_sensor_setup_trigger(indio_dev, name,
+                               &temp_st->common_attributes);
+       if (ret)
+               return ret;
+
+       platform_set_drvdata(pdev, indio_dev);
+
+       temperature_callbacks.pdev = pdev;
+       ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE,
+                                       &temperature_callbacks);
+       if (ret)
+               goto error_remove_trigger;
+
+       ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
+       if (ret)
+               goto error_remove_callback;
+
+       return ret;
+
+error_remove_callback:
+       sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
+error_remove_trigger:
+       hid_sensor_remove_trigger(&temp_st->common_attributes);
+       return ret;
+}
+
+/* Function to deinitialize the processing for usage id */
+static int hid_temperature_remove(struct platform_device *pdev)
+{
+       struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct temperature_state *temp_st = iio_priv(indio_dev);
+
+       sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
+       hid_sensor_remove_trigger(&temp_st->common_attributes);
+
+       return 0;
+}
+
+static const struct platform_device_id hid_temperature_ids[] = {
+       {
+               /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+               .name = "HID-SENSOR-200033",
+       },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_temperature_ids);
+
+static struct platform_driver hid_temperature_platform_driver = {
+       .id_table = hid_temperature_ids,
+       .driver = {
+               .name   = "temperature-sensor",
+               .pm     = &hid_sensor_pm_ops,
+       },
+       .probe          = hid_temperature_probe,
+       .remove         = hid_temperature_remove,
+};
+module_platform_driver(hid_temperature_platform_driver);
+
+MODULE_DESCRIPTION("HID Environmental temperature sensor");
+MODULE_AUTHOR("Song Hongyan <hongyan.song@intel.com>");
+MODULE_LICENSE("GPL v2");
index f962f31..5572142 100644 (file)
@@ -231,6 +231,7 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
        indio_dev->available_scan_masks = chip->scan_masks;
        indio_dev->num_channels = chip->num_channels;
        indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->dev.parent = &spi->dev;
 
        data = iio_priv(indio_dev);
        data->spi = spi;
index f04d0d1..0615324 100644 (file)
  *
  * (7-bit I2C slave address (0x40 - 0x47), changeable via ADR pins)
  *
- * Note: This driver assumes that the sensor has been calibrated beforehand
- *
- * TODO: ALERT irq, limit threshold events
+ * Note:
+ * 1. This driver assumes that the sensor has been calibrated beforehand
+ * 2. Limit threshold events are enabled at the start
+ * 3. Operating mode: INT
  *
  */
 
 #include <linux/pm.h>
 #include <linux/bitops.h>
 #include <linux/of.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
 
 #define TMP007_TDIE 0x01
 #define TMP007_CONFIG 0x02
 #define TMP007_TOBJECT 0x03
 #define TMP007_STATUS 0x04
 #define TMP007_STATUS_MASK 0x05
+#define TMP007_TOBJ_HIGH_LIMIT 0x06
+#define TMP007_TOBJ_LOW_LIMIT 0x07
+#define TMP007_TDIE_HIGH_LIMIT 0x08
+#define TMP007_TDIE_LOW_LIMIT 0x09
 #define TMP007_MANUFACTURER_ID 0x1e
 #define TMP007_DEVICE_ID 0x1f
 
 #define TMP007_CONFIG_CONV_EN BIT(12)
-#define TMP007_CONFIG_COMP_EN BIT(5)
 #define TMP007_CONFIG_TC_EN BIT(6)
 #define TMP007_CONFIG_CR_MASK GENMASK(11, 9)
+#define TMP007_CONFIG_ALERT_EN BIT(8)
 #define TMP007_CONFIG_CR_SHIFT 9
 
+/* Status register flags */
+#define TMP007_STATUS_ALERT BIT(15)
 #define TMP007_STATUS_CONV_READY BIT(14)
+#define TMP007_STATUS_OHF BIT(13)
+#define TMP007_STATUS_OLF BIT(12)
+#define TMP007_STATUS_LHF BIT(11)
+#define TMP007_STATUS_LLF BIT(10)
 #define TMP007_STATUS_DATA_VALID BIT(9)
 
 #define TMP007_MANUFACTURER_MAGIC 0x5449
@@ -52,7 +66,9 @@
 
 struct tmp007_data {
        struct i2c_client *client;
+       struct mutex lock;
        u16 config;
+       u16 status_mask;
 };
 
 static const int tmp007_avgs[5][2] = { {4, 0}, {2, 0}, {1, 0},
@@ -156,6 +172,188 @@ static int tmp007_write_raw(struct iio_dev *indio_dev,
        return -EINVAL;
 }
 
+static irqreturn_t tmp007_interrupt_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct tmp007_data *data = iio_priv(indio_dev);
+       int ret;
+
+       ret = i2c_smbus_read_word_swapped(data->client, TMP007_STATUS);
+       if ((ret < 0) || !(ret & (TMP007_STATUS_OHF | TMP007_STATUS_OLF |
+                               TMP007_STATUS_LHF | TMP007_STATUS_LLF)))
+               return IRQ_NONE;
+
+       if (ret & TMP007_STATUS_OHF)
+               iio_push_event(indio_dev,
+                               IIO_MOD_EVENT_CODE(IIO_TEMP, 0,
+                                       IIO_MOD_TEMP_OBJECT,
+                                       IIO_EV_TYPE_THRESH,
+                                       IIO_EV_DIR_RISING),
+                               iio_get_time_ns(indio_dev));
+
+       if (ret & TMP007_STATUS_OLF)
+               iio_push_event(indio_dev,
+                               IIO_MOD_EVENT_CODE(IIO_TEMP, 0,
+                                       IIO_MOD_TEMP_OBJECT,
+                                       IIO_EV_TYPE_THRESH,
+                                       IIO_EV_DIR_FALLING),
+                               iio_get_time_ns(indio_dev));
+
+       if (ret & TMP007_STATUS_LHF)
+               iio_push_event(indio_dev,
+                               IIO_MOD_EVENT_CODE(IIO_TEMP, 0,
+                                       IIO_MOD_TEMP_AMBIENT,
+                                       IIO_EV_TYPE_THRESH,
+                                       IIO_EV_DIR_RISING),
+                               iio_get_time_ns(indio_dev));
+
+       if (ret & TMP007_STATUS_LLF)
+               iio_push_event(indio_dev,
+                               IIO_MOD_EVENT_CODE(IIO_TEMP, 0,
+                                       IIO_MOD_TEMP_AMBIENT,
+                                       IIO_EV_TYPE_THRESH,
+                                       IIO_EV_DIR_FALLING),
+                               iio_get_time_ns(indio_dev));
+
+       return IRQ_HANDLED;
+}
+
+static int tmp007_write_event_config(struct iio_dev *indio_dev,
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, int state)
+{
+       struct tmp007_data *data = iio_priv(indio_dev);
+       unsigned int status_mask;
+       int ret;
+
+       switch (chan->channel2) {
+       case IIO_MOD_TEMP_AMBIENT:
+       if (dir == IIO_EV_DIR_RISING)
+                       status_mask = TMP007_STATUS_LHF;
+               else
+                       status_mask = TMP007_STATUS_LLF;
+               break;
+       case IIO_MOD_TEMP_OBJECT:
+               if (dir == IIO_EV_DIR_RISING)
+                       status_mask = TMP007_STATUS_OHF;
+               else
+                       status_mask = TMP007_STATUS_OLF;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_read_word_swapped(data->client, TMP007_STATUS_MASK);
+       mutex_unlock(&data->lock);
+       if (ret < 0)
+               return ret;
+
+       if (state)
+               ret |= status_mask;
+       else
+               ret &= ~status_mask;
+
+       return i2c_smbus_write_word_swapped(data->client, TMP007_STATUS_MASK,
+                                       data->status_mask = ret);
+}
+
+static int tmp007_read_event_config(struct iio_dev *indio_dev,
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir)
+{
+       struct tmp007_data *data = iio_priv(indio_dev);
+       unsigned int mask;
+
+       switch (chan->channel2) {
+       case IIO_MOD_TEMP_AMBIENT:
+               if (dir == IIO_EV_DIR_RISING)
+                       mask = TMP007_STATUS_LHF;
+               else
+                       mask = TMP007_STATUS_LLF;
+               break;
+       case IIO_MOD_TEMP_OBJECT:
+               if (dir == IIO_EV_DIR_RISING)
+                       mask = TMP007_STATUS_OHF;
+               else
+                       mask = TMP007_STATUS_OLF;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return !!(data->status_mask & mask);
+}
+
+static int tmp007_read_thresh(struct iio_dev *indio_dev,
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, enum iio_event_info info,
+               int *val, int *val2)
+{
+       struct tmp007_data *data = iio_priv(indio_dev);
+       int ret;
+       u8 reg;
+
+       switch (chan->channel2) {
+       case IIO_MOD_TEMP_AMBIENT: /* LSB: 0.5 degree Celsius */
+               if (dir == IIO_EV_DIR_RISING)
+                       reg = TMP007_TDIE_HIGH_LIMIT;
+               else
+                       reg = TMP007_TDIE_LOW_LIMIT;
+               break;
+       case IIO_MOD_TEMP_OBJECT:
+               if (dir == IIO_EV_DIR_RISING)
+                       reg = TMP007_TOBJ_HIGH_LIMIT;
+       else
+                       reg = TMP007_TOBJ_LOW_LIMIT;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = i2c_smbus_read_word_swapped(data->client, reg);
+       if (ret < 0)
+               return ret;
+
+       /* Shift length 7 bits = 6(15:6) + 1(0.5 LSB) */
+       *val = sign_extend32(ret, 15) >> 7;
+
+       return IIO_VAL_INT;
+}
+
+static int tmp007_write_thresh(struct iio_dev *indio_dev,
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, enum iio_event_info info,
+               int val, int val2)
+{
+       struct tmp007_data *data = iio_priv(indio_dev);
+       u8 reg;
+
+       switch (chan->channel2) {
+       case IIO_MOD_TEMP_AMBIENT:
+               if (dir == IIO_EV_DIR_RISING)
+                       reg = TMP007_TDIE_HIGH_LIMIT;
+               else
+                       reg = TMP007_TDIE_LOW_LIMIT;
+               break;
+       case IIO_MOD_TEMP_OBJECT:
+               if (dir == IIO_EV_DIR_RISING)
+                       reg = TMP007_TOBJ_HIGH_LIMIT;
+               else
+                       reg = TMP007_TOBJ_LOW_LIMIT;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Full scale threshold value is +/- 256 degree Celsius */
+       if (val < -256 || val > 255)
+               return -EINVAL;
+
+       /* Shift length 7 bits = 6(15:6) + 1(0.5 LSB) */
+       return i2c_smbus_write_word_swapped(data->client, reg, (val << 7));
+}
+
 static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
 
 static struct attribute *tmp007_attributes[] = {
@@ -167,6 +365,36 @@ static const struct attribute_group tmp007_attribute_group = {
        .attrs = tmp007_attributes,
 };
 
+static const struct iio_event_spec tmp007_obj_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
+static const struct iio_event_spec tmp007_die_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
 static const struct iio_chan_spec tmp007_channels[] = {
        {
                .type = IIO_TEMP,
@@ -175,6 +403,8 @@ static const struct iio_chan_spec tmp007_channels[] = {
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_SCALE),
                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+               .event_spec = tmp007_die_event,
+               .num_event_specs = ARRAY_SIZE(tmp007_die_event),
        },
        {
                .type = IIO_TEMP,
@@ -183,12 +413,18 @@ static const struct iio_chan_spec tmp007_channels[] = {
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_SCALE),
                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+               .event_spec = tmp007_obj_event,
+               .num_event_specs = ARRAY_SIZE(tmp007_obj_event),
        }
 };
 
 static const struct iio_info tmp007_info = {
        .read_raw = tmp007_read_raw,
        .write_raw = tmp007_write_raw,
+       .read_event_config = tmp007_read_event_config,
+       .write_event_config = tmp007_write_event_config,
+       .read_event_value = tmp007_read_thresh,
+       .write_event_value = tmp007_write_thresh,
        .attrs = &tmp007_attribute_group,
        .driver_module = THIS_MODULE,
 };
@@ -214,7 +450,6 @@ static int tmp007_probe(struct i2c_client *client,
        struct tmp007_data *data;
        struct iio_dev *indio_dev;
        int ret;
-       u16  status;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
                return -EOPNOTSUPP;
@@ -231,6 +466,7 @@ static int tmp007_probe(struct i2c_client *client,
        data = iio_priv(indio_dev);
        i2c_set_clientdata(client, indio_dev);
        data->client = client;
+       mutex_init(&data->lock);
 
        indio_dev->dev.parent = &client->dev;
        indio_dev->name = "tmp007";
@@ -243,7 +479,7 @@ static int tmp007_probe(struct i2c_client *client,
        /*
         * Set Configuration register:
         * 1. Conversion ON
-        * 2. Comparator mode
+        * 2. ALERT enable
         * 3. Transient correction enable
         */
 
@@ -252,7 +488,7 @@ static int tmp007_probe(struct i2c_client *client,
                return ret;
 
        data->config = ret;
-       data->config |= (TMP007_CONFIG_CONV_EN | TMP007_CONFIG_COMP_EN | TMP007_CONFIG_TC_EN);
+       data->config |= (TMP007_CONFIG_CONV_EN | TMP007_CONFIG_ALERT_EN | TMP007_CONFIG_TC_EN);
 
        ret = i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
                                        data->config);
@@ -260,22 +496,39 @@ static int tmp007_probe(struct i2c_client *client,
                return ret;
 
        /*
+        * Only the following flags can activate ALERT pin. Data conversion/validity flags
+        * flags can still be polled for getting temperature data
+        *
         * Set Status Mask register:
-        * 1. Conversion ready enable
-        * 2. Data valid enable
+        * 1. Object temperature high limit enable
+        * 2. Object temperature low limit enable
+        * 3. TDIE temperature high limit enable
+        * 4. TDIE temperature low limit enable
         */
 
        ret = i2c_smbus_read_word_swapped(data->client, TMP007_STATUS_MASK);
        if (ret < 0)
                goto error_powerdown;
 
-       status = ret;
-       status |= (TMP007_STATUS_CONV_READY | TMP007_STATUS_DATA_VALID);
+       data->status_mask = ret;
+       data->status_mask |= (TMP007_STATUS_OHF | TMP007_STATUS_OLF
+                               | TMP007_STATUS_LHF | TMP007_STATUS_LLF);
 
-       ret = i2c_smbus_write_word_swapped(data->client, TMP007_STATUS_MASK, status);
+       ret = i2c_smbus_write_word_swapped(data->client, TMP007_STATUS_MASK, data->status_mask);
        if (ret < 0)
                goto error_powerdown;
 
+       if (client->irq) {
+               ret = devm_request_threaded_irq(&client->dev, client->irq,
+                               NULL, tmp007_interrupt_handler,
+                               IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                               tmp007_id->name, indio_dev);
+               if (ret) {
+                       dev_err(&client->dev, "irq request error %d\n", -ret);
+                       goto error_powerdown;
+               }
+       }
+
        return iio_device_register(indio_dev);
 
 error_powerdown:
index febb137..5d8ad21 100644 (file)
@@ -2,14 +2,7 @@
 # Makefile for industrial I/O accelerometer drivers
 #
 
-adis16201-y             := adis16201_core.o
 obj-$(CONFIG_ADIS16201) += adis16201.o
-
-adis16203-y             := adis16203_core.o
 obj-$(CONFIG_ADIS16203) += adis16203.o
-
-adis16209-y             := adis16209_core.o
 obj-$(CONFIG_ADIS16209) += adis16209.o
-
-adis16240-y             := adis16240_core.o
 obj-$(CONFIG_ADIS16240) += adis16240.o
similarity index 64%
rename from drivers/staging/iio/accel/adis16201_core.c
rename to drivers/staging/iio/accel/adis16201.c
index 7963d4a..d6c8658 100644 (file)
 #include <linux/iio/buffer.h>
 #include <linux/iio/imu/adis.h>
 
-#include "adis16201.h"
+#define ADIS16201_STARTUP_DELAY        220 /* ms */
+
+/* Flash memory write count */
+#define ADIS16201_FLASH_CNT      0x00
+
+/* Output, power supply */
+#define ADIS16201_SUPPLY_OUT     0x02
+
+/* Output, x-axis accelerometer */
+#define ADIS16201_XACCL_OUT      0x04
+
+/* Output, y-axis accelerometer */
+#define ADIS16201_YACCL_OUT      0x06
+
+/* Output, auxiliary ADC input */
+#define ADIS16201_AUX_ADC        0x08
+
+/* Output, temperature */
+#define ADIS16201_TEMP_OUT       0x0A
+
+/* Output, x-axis inclination */
+#define ADIS16201_XINCL_OUT      0x0C
+
+/* Output, y-axis inclination */
+#define ADIS16201_YINCL_OUT      0x0E
+
+/* Calibration, x-axis acceleration offset */
+#define ADIS16201_XACCL_OFFS     0x10
+
+/* Calibration, y-axis acceleration offset */
+#define ADIS16201_YACCL_OFFS     0x12
+
+/* x-axis acceleration scale factor */
+#define ADIS16201_XACCL_SCALE    0x14
+
+/* y-axis acceleration scale factor */
+#define ADIS16201_YACCL_SCALE    0x16
+
+/* Calibration, x-axis inclination offset */
+#define ADIS16201_XINCL_OFFS     0x18
+
+/* Calibration, y-axis inclination offset */
+#define ADIS16201_YINCL_OFFS     0x1A
+
+/* x-axis inclination scale factor */
+#define ADIS16201_XINCL_SCALE    0x1C
+
+/* y-axis inclination scale factor */
+#define ADIS16201_YINCL_SCALE    0x1E
+
+/* Alarm 1 amplitude threshold */
+#define ADIS16201_ALM_MAG1       0x20
+
+/* Alarm 2 amplitude threshold */
+#define ADIS16201_ALM_MAG2       0x22
+
+/* Alarm 1, sample period */
+#define ADIS16201_ALM_SMPL1      0x24
+
+/* Alarm 2, sample period */
+#define ADIS16201_ALM_SMPL2      0x26
+
+/* Alarm control */
+#define ADIS16201_ALM_CTRL       0x28
+
+/* Auxiliary DAC data */
+#define ADIS16201_AUX_DAC        0x30
+
+/* General-purpose digital input/output control */
+#define ADIS16201_GPIO_CTRL      0x32
+
+/* Miscellaneous control */
+#define ADIS16201_MSC_CTRL       0x34
+
+/* Internal sample period (rate) control */
+#define ADIS16201_SMPL_PRD       0x36
+
+/* Operation, filter configuration */
+#define ADIS16201_AVG_CNT        0x38
+
+/* Operation, sleep mode control */
+#define ADIS16201_SLP_CNT        0x3A
+
+/* Diagnostics, system status register */
+#define ADIS16201_DIAG_STAT      0x3C
+
+/* Operation, system command register */
+#define ADIS16201_GLOB_CMD       0x3E
+
+/* MSC_CTRL */
+
+/* Self-test enable */
+#define ADIS16201_MSC_CTRL_SELF_TEST_EN                BIT(8)
+
+/* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16201_MSC_CTRL_DATA_RDY_EN         BIT(2)
+
+/* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16201_MSC_CTRL_ACTIVE_HIGH         BIT(1)
+
+/* Data-ready line selection: 1 = DIO1, 0 = DIO0 */
+#define ADIS16201_MSC_CTRL_DATA_RDY_DIO1       BIT(0)
+
+/* DIAG_STAT */
+
+/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16201_DIAG_STAT_ALARM2        BIT(9)
+
+/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16201_DIAG_STAT_ALARM1        BIT(8)
+
+/* SPI communications failure */
+#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT   3
+
+/* Flash update failure */
+#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT  2
+
+/* Power supply above 3.625 V */
+#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1
+
+/* Power supply below 3.15 V */
+#define ADIS16201_DIAG_STAT_POWER_LOW_BIT  0
+
+/* GLOB_CMD */
+
+#define ADIS16201_GLOB_CMD_SW_RESET    BIT(7)
+#define ADIS16201_GLOB_CMD_FACTORY_CAL BIT(1)
+
+#define ADIS16201_ERROR_ACTIVE          BIT(14)
+
+enum adis16201_scan {
+       ADIS16201_SCAN_ACC_X,
+       ADIS16201_SCAN_ACC_Y,
+       ADIS16201_SCAN_INCLI_X,
+       ADIS16201_SCAN_INCLI_Y,
+       ADIS16201_SCAN_SUPPLY,
+       ADIS16201_SCAN_AUX_ADC,
+       ADIS16201_SCAN_TEMP,
+};
 
 static const u8 adis16201_addresses[] = {
        [ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS,
diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h
deleted file mode 100644 (file)
index 64844ad..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-#ifndef SPI_ADIS16201_H_
-#define SPI_ADIS16201_H_
-
-#define ADIS16201_STARTUP_DELAY        220 /* ms */
-
-/* Flash memory write count */
-#define ADIS16201_FLASH_CNT      0x00
-
-/* Output, power supply */
-#define ADIS16201_SUPPLY_OUT     0x02
-
-/* Output, x-axis accelerometer */
-#define ADIS16201_XACCL_OUT      0x04
-
-/* Output, y-axis accelerometer */
-#define ADIS16201_YACCL_OUT      0x06
-
-/* Output, auxiliary ADC input */
-#define ADIS16201_AUX_ADC        0x08
-
-/* Output, temperature */
-#define ADIS16201_TEMP_OUT       0x0A
-
-/* Output, x-axis inclination */
-#define ADIS16201_XINCL_OUT      0x0C
-
-/* Output, y-axis inclination */
-#define ADIS16201_YINCL_OUT      0x0E
-
-/* Calibration, x-axis acceleration offset */
-#define ADIS16201_XACCL_OFFS     0x10
-
-/* Calibration, y-axis acceleration offset */
-#define ADIS16201_YACCL_OFFS     0x12
-
-/* x-axis acceleration scale factor */
-#define ADIS16201_XACCL_SCALE    0x14
-
-/* y-axis acceleration scale factor */
-#define ADIS16201_YACCL_SCALE    0x16
-
-/* Calibration, x-axis inclination offset */
-#define ADIS16201_XINCL_OFFS     0x18
-
-/* Calibration, y-axis inclination offset */
-#define ADIS16201_YINCL_OFFS     0x1A
-
-/* x-axis inclination scale factor */
-#define ADIS16201_XINCL_SCALE    0x1C
-
-/* y-axis inclination scale factor */
-#define ADIS16201_YINCL_SCALE    0x1E
-
-/* Alarm 1 amplitude threshold */
-#define ADIS16201_ALM_MAG1       0x20
-
-/* Alarm 2 amplitude threshold */
-#define ADIS16201_ALM_MAG2       0x22
-
-/* Alarm 1, sample period */
-#define ADIS16201_ALM_SMPL1      0x24
-
-/* Alarm 2, sample period */
-#define ADIS16201_ALM_SMPL2      0x26
-
-/* Alarm control */
-#define ADIS16201_ALM_CTRL       0x28
-
-/* Auxiliary DAC data */
-#define ADIS16201_AUX_DAC        0x30
-
-/* General-purpose digital input/output control */
-#define ADIS16201_GPIO_CTRL      0x32
-
-/* Miscellaneous control */
-#define ADIS16201_MSC_CTRL       0x34
-
-/* Internal sample period (rate) control */
-#define ADIS16201_SMPL_PRD       0x36
-
-/* Operation, filter configuration */
-#define ADIS16201_AVG_CNT        0x38
-
-/* Operation, sleep mode control */
-#define ADIS16201_SLP_CNT        0x3A
-
-/* Diagnostics, system status register */
-#define ADIS16201_DIAG_STAT      0x3C
-
-/* Operation, system command register */
-#define ADIS16201_GLOB_CMD       0x3E
-
-/* MSC_CTRL */
-
-/* Self-test enable */
-#define ADIS16201_MSC_CTRL_SELF_TEST_EN                BIT(8)
-
-/* Data-ready enable: 1 = enabled, 0 = disabled */
-#define ADIS16201_MSC_CTRL_DATA_RDY_EN         BIT(2)
-
-/* Data-ready polarity: 1 = active high, 0 = active low */
-#define ADIS16201_MSC_CTRL_ACTIVE_HIGH         BIT(1)
-
-/* Data-ready line selection: 1 = DIO1, 0 = DIO0 */
-#define ADIS16201_MSC_CTRL_DATA_RDY_DIO1       BIT(0)
-
-/* DIAG_STAT */
-
-/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16201_DIAG_STAT_ALARM2        BIT(9)
-
-/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16201_DIAG_STAT_ALARM1        BIT(8)
-
-/* SPI communications failure */
-#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT   3
-
-/* Flash update failure */
-#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT  2
-
-/* Power supply above 3.625 V */
-#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1
-
-/* Power supply below 3.15 V */
-#define ADIS16201_DIAG_STAT_POWER_LOW_BIT  0
-
-/* GLOB_CMD */
-
-#define ADIS16201_GLOB_CMD_SW_RESET    BIT(7)
-#define ADIS16201_GLOB_CMD_FACTORY_CAL BIT(1)
-
-#define ADIS16201_ERROR_ACTIVE          BIT(14)
-
-enum adis16201_scan {
-       ADIS16201_SCAN_ACC_X,
-       ADIS16201_SCAN_ACC_Y,
-       ADIS16201_SCAN_INCLI_X,
-       ADIS16201_SCAN_INCLI_Y,
-       ADIS16201_SCAN_SUPPLY,
-       ADIS16201_SCAN_AUX_ADC,
-       ADIS16201_SCAN_TEMP,
-};
-
-#endif /* SPI_ADIS16201_H_ */
similarity index 64%
rename from drivers/staging/iio/accel/adis16203_core.c
rename to drivers/staging/iio/accel/adis16203.c
index bd8119a..68189ad 100644 (file)
  */
 
 #include <linux/delay.h>
-#include <linux/mutex.h>
 #include <linux/device.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/imu/adis.h>
+#include <linux/iio/sysfs.h>
+
 #include <linux/kernel.h>
-#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/spi/spi.h>
 #include <linux/sysfs.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>
+#define ADIS16203_STARTUP_DELAY 220 /* ms */
+
+/* Flash memory write count */
+#define ADIS16203_FLASH_CNT      0x00
+
+/* Output, power supply */
+#define ADIS16203_SUPPLY_OUT     0x02
+
+/* Output, auxiliary ADC input */
+#define ADIS16203_AUX_ADC        0x08
+
+/* Output, temperature */
+#define ADIS16203_TEMP_OUT       0x0A
+
+/* Output, x-axis inclination */
+#define ADIS16203_XINCL_OUT      0x0C
+
+/* Output, y-axis inclination */
+#define ADIS16203_YINCL_OUT      0x0E
+
+/* Incline null calibration */
+#define ADIS16203_INCL_NULL      0x18
+
+/* Alarm 1 amplitude threshold */
+#define ADIS16203_ALM_MAG1       0x20
+
+/* Alarm 2 amplitude threshold */
+#define ADIS16203_ALM_MAG2       0x22
+
+/* Alarm 1, sample period */
+#define ADIS16203_ALM_SMPL1      0x24
+
+/* Alarm 2, sample period */
+#define ADIS16203_ALM_SMPL2      0x26
+
+/* Alarm control */
+#define ADIS16203_ALM_CTRL       0x28
 
-#include "adis16203.h"
+/* Auxiliary DAC data */
+#define ADIS16203_AUX_DAC        0x30
+
+/* General-purpose digital input/output control */
+#define ADIS16203_GPIO_CTRL      0x32
+
+/* Miscellaneous control */
+#define ADIS16203_MSC_CTRL       0x34
+
+/* Internal sample period (rate) control */
+#define ADIS16203_SMPL_PRD       0x36
+
+/* Operation, filter configuration */
+#define ADIS16203_AVG_CNT        0x38
+
+/* Operation, sleep mode control */
+#define ADIS16203_SLP_CNT        0x3A
+
+/* Diagnostics, system status register */
+#define ADIS16203_DIAG_STAT      0x3C
+
+/* Operation, system command register */
+#define ADIS16203_GLOB_CMD       0x3E
+
+/* MSC_CTRL */
+
+/* Self-test at power-on: 1 = disabled, 0 = enabled */
+#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST      BIT(10)
+
+/* Reverses rotation of both inclination outputs */
+#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN       BIT(9)
+
+/* Self-test enable */
+#define ADIS16203_MSC_CTRL_SELF_TEST_EN         BIT(8)
+
+/* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16203_MSC_CTRL_DATA_RDY_EN          BIT(2)
+
+/* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16203_MSC_CTRL_ACTIVE_HIGH          BIT(1)
+
+/* Data-ready line selection: 1 = DIO1, 0 = DIO0 */
+#define ADIS16203_MSC_CTRL_DATA_RDY_DIO1        BIT(0)
+
+/* DIAG_STAT */
+
+/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16203_DIAG_STAT_ALARM2        BIT(9)
+
+/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16203_DIAG_STAT_ALARM1        BIT(8)
+
+/* Self-test diagnostic error flag */
+#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5
+
+/* SPI communications failure */
+#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT      3
+
+/* Flash update failure */
+#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT     2
+
+/* Power supply above 3.625 V */
+#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT    1
+
+/* Power supply below 3.15 V */
+#define ADIS16203_DIAG_STAT_POWER_LOW_BIT     0
+
+/* GLOB_CMD */
+
+#define ADIS16203_GLOB_CMD_SW_RESET     BIT(7)
+#define ADIS16203_GLOB_CMD_CLEAR_STAT   BIT(4)
+#define ADIS16203_GLOB_CMD_FACTORY_CAL  BIT(1)
+
+#define ADIS16203_ERROR_ACTIVE          BIT(14)
+
+enum adis16203_scan {
+        ADIS16203_SCAN_INCLI_X,
+        ADIS16203_SCAN_INCLI_Y,
+        ADIS16203_SCAN_SUPPLY,
+        ADIS16203_SCAN_AUX_ADC,
+        ADIS16203_SCAN_TEMP,
+};
 
 #define DRIVER_NAME            "adis16203"
 
diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h
deleted file mode 100644 (file)
index b483e4e..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef SPI_ADIS16203_H_
-#define SPI_ADIS16203_H_
-
-#define ADIS16203_STARTUP_DELAY        220 /* ms */
-
-/* Flash memory write count */
-#define ADIS16203_FLASH_CNT      0x00
-
-/* Output, power supply */
-#define ADIS16203_SUPPLY_OUT     0x02
-
-/* Output, auxiliary ADC input */
-#define ADIS16203_AUX_ADC        0x08
-
-/* Output, temperature */
-#define ADIS16203_TEMP_OUT       0x0A
-
-/* Output, x-axis inclination */
-#define ADIS16203_XINCL_OUT      0x0C
-
-/* Output, y-axis inclination */
-#define ADIS16203_YINCL_OUT      0x0E
-
-/* Incline null calibration */
-#define ADIS16203_INCL_NULL      0x18
-
-/* Alarm 1 amplitude threshold */
-#define ADIS16203_ALM_MAG1       0x20
-
-/* Alarm 2 amplitude threshold */
-#define ADIS16203_ALM_MAG2       0x22
-
-/* Alarm 1, sample period */
-#define ADIS16203_ALM_SMPL1      0x24
-
-/* Alarm 2, sample period */
-#define ADIS16203_ALM_SMPL2      0x26
-
-/* Alarm control */
-#define ADIS16203_ALM_CTRL       0x28
-
-/* Auxiliary DAC data */
-#define ADIS16203_AUX_DAC        0x30
-
-/* General-purpose digital input/output control */
-#define ADIS16203_GPIO_CTRL      0x32
-
-/* Miscellaneous control */
-#define ADIS16203_MSC_CTRL       0x34
-
-/* Internal sample period (rate) control */
-#define ADIS16203_SMPL_PRD       0x36
-
-/* Operation, filter configuration */
-#define ADIS16203_AVG_CNT        0x38
-
-/* Operation, sleep mode control */
-#define ADIS16203_SLP_CNT        0x3A
-
-/* Diagnostics, system status register */
-#define ADIS16203_DIAG_STAT      0x3C
-
-/* Operation, system command register */
-#define ADIS16203_GLOB_CMD       0x3E
-
-/* MSC_CTRL */
-
-/* Self-test at power-on: 1 = disabled, 0 = enabled */
-#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST     BIT(10)
-
-/* Reverses rotation of both inclination outputs */
-#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN      BIT(9)
-
-/* Self-test enable */
-#define ADIS16203_MSC_CTRL_SELF_TEST_EN                BIT(8)
-
-/* Data-ready enable: 1 = enabled, 0 = disabled */
-#define ADIS16203_MSC_CTRL_DATA_RDY_EN         BIT(2)
-
-/* Data-ready polarity: 1 = active high, 0 = active low */
-#define ADIS16203_MSC_CTRL_ACTIVE_HIGH         BIT(1)
-
-/* Data-ready line selection: 1 = DIO1, 0 = DIO0 */
-#define ADIS16203_MSC_CTRL_DATA_RDY_DIO1       BIT(0)
-
-/* DIAG_STAT */
-
-/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16203_DIAG_STAT_ALARM2        BIT(9)
-
-/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16203_DIAG_STAT_ALARM1        BIT(8)
-
-/* Self-test diagnostic error flag */
-#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5
-
-/* SPI communications failure */
-#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT      3
-
-/* Flash update failure */
-#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT     2
-
-/* Power supply above 3.625 V */
-#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT    1
-
-/* Power supply below 3.15 V */
-#define ADIS16203_DIAG_STAT_POWER_LOW_BIT     0
-
-/* GLOB_CMD */
-
-#define ADIS16203_GLOB_CMD_SW_RESET    BIT(7)
-#define ADIS16203_GLOB_CMD_CLEAR_STAT  BIT(4)
-#define ADIS16203_GLOB_CMD_FACTORY_CAL BIT(1)
-
-#define ADIS16203_ERROR_ACTIVE          BIT(14)
-
-enum adis16203_scan {
-       ADIS16203_SCAN_INCLI_X,
-       ADIS16203_SCAN_INCLI_Y,
-       ADIS16203_SCAN_SUPPLY,
-       ADIS16203_SCAN_AUX_ADC,
-       ADIS16203_SCAN_TEMP,
-};
-
-#endif /* SPI_ADIS16203_H_ */
similarity index 63%
rename from drivers/staging/iio/accel/adis16209_core.c
rename to drivers/staging/iio/accel/adis16209.c
index a599e19..8ff537f 100644 (file)
 #include <linux/iio/buffer.h>
 #include <linux/iio/imu/adis.h>
 
-#include "adis16209.h"
+#define ADIS16209_STARTUP_DELAY        220 /* ms */
+
+/* Flash memory write count */
+#define ADIS16209_FLASH_CNT      0x00
+
+/* Output, power supply */
+#define ADIS16209_SUPPLY_OUT     0x02
+
+/* Output, x-axis accelerometer */
+#define ADIS16209_XACCL_OUT      0x04
+
+/* Output, y-axis accelerometer */
+#define ADIS16209_YACCL_OUT      0x06
+
+/* Output, auxiliary ADC input */
+#define ADIS16209_AUX_ADC        0x08
+
+/* Output, temperature */
+#define ADIS16209_TEMP_OUT       0x0A
+
+/* Output, x-axis inclination */
+#define ADIS16209_XINCL_OUT      0x0C
+
+/* Output, y-axis inclination */
+#define ADIS16209_YINCL_OUT      0x0E
+
+/* Output, +/-180 vertical rotational position */
+#define ADIS16209_ROT_OUT        0x10
+
+/* Calibration, x-axis acceleration offset null */
+#define ADIS16209_XACCL_NULL     0x12
+
+/* Calibration, y-axis acceleration offset null */
+#define ADIS16209_YACCL_NULL     0x14
+
+/* Calibration, x-axis inclination offset null */
+#define ADIS16209_XINCL_NULL     0x16
+
+/* Calibration, y-axis inclination offset null */
+#define ADIS16209_YINCL_NULL     0x18
+
+/* Calibration, vertical rotation offset null */
+#define ADIS16209_ROT_NULL       0x1A
+
+/* Alarm 1 amplitude threshold */
+#define ADIS16209_ALM_MAG1       0x20
+
+/* Alarm 2 amplitude threshold */
+#define ADIS16209_ALM_MAG2       0x22
+
+/* Alarm 1, sample period */
+#define ADIS16209_ALM_SMPL1      0x24
+
+/* Alarm 2, sample period */
+#define ADIS16209_ALM_SMPL2      0x26
+
+/* Alarm control */
+#define ADIS16209_ALM_CTRL       0x28
+
+/* Auxiliary DAC data */
+#define ADIS16209_AUX_DAC        0x30
+
+/* General-purpose digital input/output control */
+#define ADIS16209_GPIO_CTRL      0x32
+
+/* Miscellaneous control */
+#define ADIS16209_MSC_CTRL       0x34
+
+/* Internal sample period (rate) control */
+#define ADIS16209_SMPL_PRD       0x36
+
+/* Operation, filter configuration */
+#define ADIS16209_AVG_CNT        0x38
+
+/* Operation, sleep mode control */
+#define ADIS16209_SLP_CNT        0x3A
+
+/* Diagnostics, system status register */
+#define ADIS16209_DIAG_STAT      0x3C
+
+/* Operation, system command register */
+#define ADIS16209_GLOB_CMD       0x3E
+
+/* MSC_CTRL */
+
+/* Self-test at power-on: 1 = disabled, 0 = enabled */
+#define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST     BIT(10)
+
+/* Self-test enable */
+#define ADIS16209_MSC_CTRL_SELF_TEST_EN                BIT(8)
+
+/* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16209_MSC_CTRL_DATA_RDY_EN         BIT(2)
+
+/* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16209_MSC_CTRL_ACTIVE_HIGH         BIT(1)
+
+/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */
+#define ADIS16209_MSC_CTRL_DATA_RDY_DIO2       BIT(0)
+
+/* DIAG_STAT */
+
+/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16209_DIAG_STAT_ALARM2        BIT(9)
+
+/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16209_DIAG_STAT_ALARM1        BIT(8)
+
+/* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */
+#define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT  5
+
+/* SPI communications failure */
+#define ADIS16209_DIAG_STAT_SPI_FAIL_BIT       3
+
+/* Flash update failure */
+#define ADIS16209_DIAG_STAT_FLASH_UPT_BIT      2
+
+/* Power supply above 3.625 V */
+#define ADIS16209_DIAG_STAT_POWER_HIGH_BIT     1
+
+/* Power supply below 3.15 V */
+#define ADIS16209_DIAG_STAT_POWER_LOW_BIT      0
+
+/* GLOB_CMD */
+
+#define ADIS16209_GLOB_CMD_SW_RESET    BIT(7)
+#define ADIS16209_GLOB_CMD_CLEAR_STAT  BIT(4)
+#define ADIS16209_GLOB_CMD_FACTORY_CAL BIT(1)
+
+#define ADIS16209_ERROR_ACTIVE          BIT(14)
+
+#define ADIS16209_SCAN_SUPPLY  0
+#define ADIS16209_SCAN_ACC_X   1
+#define ADIS16209_SCAN_ACC_Y   2
+#define ADIS16209_SCAN_AUX_ADC 3
+#define ADIS16209_SCAN_TEMP    4
+#define ADIS16209_SCAN_INCLI_X 5
+#define ADIS16209_SCAN_INCLI_Y 6
+#define ADIS16209_SCAN_ROT     7
 
 static const u8 adis16209_addresses[8][1] = {
        [ADIS16209_SCAN_SUPPLY] = { },
diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
deleted file mode 100644 (file)
index 315f1c0..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-#ifndef SPI_ADIS16209_H_
-#define SPI_ADIS16209_H_
-
-#define ADIS16209_STARTUP_DELAY        220 /* ms */
-
-/* Flash memory write count */
-#define ADIS16209_FLASH_CNT      0x00
-
-/* Output, power supply */
-#define ADIS16209_SUPPLY_OUT     0x02
-
-/* Output, x-axis accelerometer */
-#define ADIS16209_XACCL_OUT      0x04
-
-/* Output, y-axis accelerometer */
-#define ADIS16209_YACCL_OUT      0x06
-
-/* Output, auxiliary ADC input */
-#define ADIS16209_AUX_ADC        0x08
-
-/* Output, temperature */
-#define ADIS16209_TEMP_OUT       0x0A
-
-/* Output, x-axis inclination */
-#define ADIS16209_XINCL_OUT      0x0C
-
-/* Output, y-axis inclination */
-#define ADIS16209_YINCL_OUT      0x0E
-
-/* Output, +/-180 vertical rotational position */
-#define ADIS16209_ROT_OUT        0x10
-
-/* Calibration, x-axis acceleration offset null */
-#define ADIS16209_XACCL_NULL     0x12
-
-/* Calibration, y-axis acceleration offset null */
-#define ADIS16209_YACCL_NULL     0x14
-
-/* Calibration, x-axis inclination offset null */
-#define ADIS16209_XINCL_NULL     0x16
-
-/* Calibration, y-axis inclination offset null */
-#define ADIS16209_YINCL_NULL     0x18
-
-/* Calibration, vertical rotation offset null */
-#define ADIS16209_ROT_NULL       0x1A
-
-/* Alarm 1 amplitude threshold */
-#define ADIS16209_ALM_MAG1       0x20
-
-/* Alarm 2 amplitude threshold */
-#define ADIS16209_ALM_MAG2       0x22
-
-/* Alarm 1, sample period */
-#define ADIS16209_ALM_SMPL1      0x24
-
-/* Alarm 2, sample period */
-#define ADIS16209_ALM_SMPL2      0x26
-
-/* Alarm control */
-#define ADIS16209_ALM_CTRL       0x28
-
-/* Auxiliary DAC data */
-#define ADIS16209_AUX_DAC        0x30
-
-/* General-purpose digital input/output control */
-#define ADIS16209_GPIO_CTRL      0x32
-
-/* Miscellaneous control */
-#define ADIS16209_MSC_CTRL       0x34
-
-/* Internal sample period (rate) control */
-#define ADIS16209_SMPL_PRD       0x36
-
-/* Operation, filter configuration */
-#define ADIS16209_AVG_CNT        0x38
-
-/* Operation, sleep mode control */
-#define ADIS16209_SLP_CNT        0x3A
-
-/* Diagnostics, system status register */
-#define ADIS16209_DIAG_STAT      0x3C
-
-/* Operation, system command register */
-#define ADIS16209_GLOB_CMD       0x3E
-
-/* MSC_CTRL */
-
-/* Self-test at power-on: 1 = disabled, 0 = enabled */
-#define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST     BIT(10)
-
-/* Self-test enable */
-#define ADIS16209_MSC_CTRL_SELF_TEST_EN                BIT(8)
-
-/* Data-ready enable: 1 = enabled, 0 = disabled */
-#define ADIS16209_MSC_CTRL_DATA_RDY_EN         BIT(2)
-
-/* Data-ready polarity: 1 = active high, 0 = active low */
-#define ADIS16209_MSC_CTRL_ACTIVE_HIGH         BIT(1)
-
-/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */
-#define ADIS16209_MSC_CTRL_DATA_RDY_DIO2       BIT(0)
-
-/* DIAG_STAT */
-
-/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16209_DIAG_STAT_ALARM2        BIT(9)
-
-/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16209_DIAG_STAT_ALARM1        BIT(8)
-
-/* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */
-#define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT  5
-
-/* SPI communications failure */
-#define ADIS16209_DIAG_STAT_SPI_FAIL_BIT       3
-
-/* Flash update failure */
-#define ADIS16209_DIAG_STAT_FLASH_UPT_BIT      2
-
-/* Power supply above 3.625 V */
-#define ADIS16209_DIAG_STAT_POWER_HIGH_BIT     1
-
-/* Power supply below 3.15 V */
-#define ADIS16209_DIAG_STAT_POWER_LOW_BIT      0
-
-/* GLOB_CMD */
-
-#define ADIS16209_GLOB_CMD_SW_RESET    BIT(7)
-#define ADIS16209_GLOB_CMD_CLEAR_STAT  BIT(4)
-#define ADIS16209_GLOB_CMD_FACTORY_CAL BIT(1)
-
-#define ADIS16209_ERROR_ACTIVE          BIT(14)
-
-#define ADIS16209_SCAN_SUPPLY  0
-#define ADIS16209_SCAN_ACC_X   1
-#define ADIS16209_SCAN_ACC_Y   2
-#define ADIS16209_SCAN_AUX_ADC 3
-#define ADIS16209_SCAN_TEMP    4
-#define ADIS16209_SCAN_INCLI_X 5
-#define ADIS16209_SCAN_INCLI_Y 6
-#define ADIS16209_SCAN_ROT     7
-
-#endif /* SPI_ADIS16209_H_ */
similarity index 62%
rename from drivers/staging/iio/accel/adis16240_core.c
rename to drivers/staging/iio/accel/adis16240.c
index d5b99e6..27d7f6a 100644 (file)
 #include <linux/iio/buffer.h>
 #include <linux/iio/imu/adis.h>
 
-#include "adis16240.h"
+#define ADIS16240_STARTUP_DELAY        220 /* ms */
+
+/* Flash memory write count */
+#define ADIS16240_FLASH_CNT      0x00
+
+/* Output, power supply */
+#define ADIS16240_SUPPLY_OUT     0x02
+
+/* Output, x-axis accelerometer */
+#define ADIS16240_XACCL_OUT      0x04
+
+/* Output, y-axis accelerometer */
+#define ADIS16240_YACCL_OUT      0x06
+
+/* Output, z-axis accelerometer */
+#define ADIS16240_ZACCL_OUT      0x08
+
+/* Output, auxiliary ADC input */
+#define ADIS16240_AUX_ADC        0x0A
+
+/* Output, temperature */
+#define ADIS16240_TEMP_OUT       0x0C
+
+/* Output, x-axis acceleration peak */
+#define ADIS16240_XPEAK_OUT      0x0E
+
+/* Output, y-axis acceleration peak */
+#define ADIS16240_YPEAK_OUT      0x10
+
+/* Output, z-axis acceleration peak */
+#define ADIS16240_ZPEAK_OUT      0x12
+
+/* Output, sum-of-squares acceleration peak */
+#define ADIS16240_XYZPEAK_OUT    0x14
+
+/* Output, Capture Buffer 1, X and Y acceleration */
+#define ADIS16240_CAPT_BUF1      0x16
+
+/* Output, Capture Buffer 2, Z acceleration */
+#define ADIS16240_CAPT_BUF2      0x18
+
+/* Diagnostic, error flags */
+#define ADIS16240_DIAG_STAT      0x1A
+
+/* Diagnostic, event counter */
+#define ADIS16240_EVNT_CNTR      0x1C
+
+/* Diagnostic, check sum value from firmware test */
+#define ADIS16240_CHK_SUM        0x1E
+
+/* Calibration, x-axis acceleration offset adjustment */
+#define ADIS16240_XACCL_OFF      0x20
+
+/* Calibration, y-axis acceleration offset adjustment */
+#define ADIS16240_YACCL_OFF      0x22
+
+/* Calibration, z-axis acceleration offset adjustment */
+#define ADIS16240_ZACCL_OFF      0x24
+
+/* Clock, hour and minute */
+#define ADIS16240_CLK_TIME       0x2E
+
+/* Clock, month and day */
+#define ADIS16240_CLK_DATE       0x30
+
+/* Clock, year */
+#define ADIS16240_CLK_YEAR       0x32
+
+/* Wake-up setting, hour and minute */
+#define ADIS16240_WAKE_TIME      0x34
+
+/* Wake-up setting, month and day */
+#define ADIS16240_WAKE_DATE      0x36
+
+/* Alarm 1 amplitude threshold */
+#define ADIS16240_ALM_MAG1       0x38
+
+/* Alarm 2 amplitude threshold */
+#define ADIS16240_ALM_MAG2       0x3A
+
+/* Alarm control */
+#define ADIS16240_ALM_CTRL       0x3C
+
+/* Capture, external trigger control */
+#define ADIS16240_XTRIG_CTRL     0x3E
+
+/* Capture, address pointer */
+#define ADIS16240_CAPT_PNTR      0x40
+
+/* Capture, configuration and control */
+#define ADIS16240_CAPT_CTRL      0x42
+
+/* General-purpose digital input/output control */
+#define ADIS16240_GPIO_CTRL      0x44
+
+/* Miscellaneous control */
+#define ADIS16240_MSC_CTRL       0x46
+
+/* Internal sample period (rate) control */
+#define ADIS16240_SMPL_PRD       0x48
+
+/* System command */
+#define ADIS16240_GLOB_CMD       0x4A
+
+/* MSC_CTRL */
+
+/* Enables sum-of-squares output (XYZPEAK_OUT) */
+#define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN      BIT(15)
+
+/* Enables peak tracking output (XPEAK_OUT, YPEAK_OUT, and ZPEAK_OUT) */
+#define ADIS16240_MSC_CTRL_X_Y_ZPEAK_OUT_EN    BIT(14)
+
+/* Self-test enable: 1 = apply electrostatic force, 0 = disabled */
+#define ADIS16240_MSC_CTRL_SELF_TEST_EN                BIT(8)
+
+/* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16240_MSC_CTRL_DATA_RDY_EN         BIT(2)
+
+/* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16240_MSC_CTRL_ACTIVE_HIGH         BIT(1)
+
+/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */
+#define ADIS16240_MSC_CTRL_DATA_RDY_DIO2       BIT(0)
+
+/* DIAG_STAT */
+
+/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16240_DIAG_STAT_ALARM2      BIT(9)
+
+/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16240_DIAG_STAT_ALARM1      BIT(8)
+
+/* Capture buffer full: 1 = capture buffer is full */
+#define ADIS16240_DIAG_STAT_CPT_BUF_FUL BIT(7)
+
+/* Flash test, checksum flag: 1 = mismatch, 0 = match */
+#define ADIS16240_DIAG_STAT_CHKSUM      BIT(6)
+
+/* Power-on, self-test flag: 1 = failure, 0 = pass */
+#define ADIS16240_DIAG_STAT_PWRON_FAIL_BIT  5
+
+/* Power-on self-test: 1 = in-progress, 0 = complete */
+#define ADIS16240_DIAG_STAT_PWRON_BUSY  BIT(4)
+
+/* SPI communications failure */
+#define ADIS16240_DIAG_STAT_SPI_FAIL_BIT       3
+
+/* Flash update failure */
+#define ADIS16240_DIAG_STAT_FLASH_UPT_BIT      2
+
+/* Power supply above 3.625 V */
+#define ADIS16240_DIAG_STAT_POWER_HIGH_BIT     1
+
+ /* Power supply below 3.15 V */
+#define ADIS16240_DIAG_STAT_POWER_LOW_BIT      0
+
+/* GLOB_CMD */
+
+#define ADIS16240_GLOB_CMD_RESUME      BIT(8)
+#define ADIS16240_GLOB_CMD_SW_RESET    BIT(7)
+#define ADIS16240_GLOB_CMD_STANDBY     BIT(2)
+
+#define ADIS16240_ERROR_ACTIVE          BIT(14)
+
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+#define ADIS16240_SCAN_ACC_X   0
+#define ADIS16240_SCAN_ACC_Y   1
+#define ADIS16240_SCAN_ACC_Z   2
+#define ADIS16240_SCAN_SUPPLY  3
+#define ADIS16240_SCAN_AUX_ADC 4
+#define ADIS16240_SCAN_TEMP    5
 
 static ssize_t adis16240_spi_read_signed(struct device *dev,
                                         struct device_attribute *attr,
@@ -65,7 +238,7 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev,
        return ret;
 }
 
-static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, S_IRUGO,
+static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, 0444,
                       adis16240_read_12bit_signed, NULL,
                       ADIS16240_XYZPEAK_OUT);
 
diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h
deleted file mode 100644 (file)
index b2cb37b..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-#ifndef SPI_ADIS16240_H_
-#define SPI_ADIS16240_H_
-
-#define ADIS16240_STARTUP_DELAY        220 /* ms */
-
-/* Flash memory write count */
-#define ADIS16240_FLASH_CNT      0x00
-
-/* Output, power supply */
-#define ADIS16240_SUPPLY_OUT     0x02
-
-/* Output, x-axis accelerometer */
-#define ADIS16240_XACCL_OUT      0x04
-
-/* Output, y-axis accelerometer */
-#define ADIS16240_YACCL_OUT      0x06
-
-/* Output, z-axis accelerometer */
-#define ADIS16240_ZACCL_OUT      0x08
-
-/* Output, auxiliary ADC input */
-#define ADIS16240_AUX_ADC        0x0A
-
-/* Output, temperature */
-#define ADIS16240_TEMP_OUT       0x0C
-
-/* Output, x-axis acceleration peak */
-#define ADIS16240_XPEAK_OUT      0x0E
-
-/* Output, y-axis acceleration peak */
-#define ADIS16240_YPEAK_OUT      0x10
-
-/* Output, z-axis acceleration peak */
-#define ADIS16240_ZPEAK_OUT      0x12
-
-/* Output, sum-of-squares acceleration peak */
-#define ADIS16240_XYZPEAK_OUT    0x14
-
-/* Output, Capture Buffer 1, X and Y acceleration */
-#define ADIS16240_CAPT_BUF1      0x16
-
-/* Output, Capture Buffer 2, Z acceleration */
-#define ADIS16240_CAPT_BUF2      0x18
-
-/* Diagnostic, error flags */
-#define ADIS16240_DIAG_STAT      0x1A
-
-/* Diagnostic, event counter */
-#define ADIS16240_EVNT_CNTR      0x1C
-
-/* Diagnostic, check sum value from firmware test */
-#define ADIS16240_CHK_SUM        0x1E
-
-/* Calibration, x-axis acceleration offset adjustment */
-#define ADIS16240_XACCL_OFF      0x20
-
-/* Calibration, y-axis acceleration offset adjustment */
-#define ADIS16240_YACCL_OFF      0x22
-
-/* Calibration, z-axis acceleration offset adjustment */
-#define ADIS16240_ZACCL_OFF      0x24
-
-/* Clock, hour and minute */
-#define ADIS16240_CLK_TIME       0x2E
-
-/* Clock, month and day */
-#define ADIS16240_CLK_DATE       0x30
-
-/* Clock, year */
-#define ADIS16240_CLK_YEAR       0x32
-
-/* Wake-up setting, hour and minute */
-#define ADIS16240_WAKE_TIME      0x34
-
-/* Wake-up setting, month and day */
-#define ADIS16240_WAKE_DATE      0x36
-
-/* Alarm 1 amplitude threshold */
-#define ADIS16240_ALM_MAG1       0x38
-
-/* Alarm 2 amplitude threshold */
-#define ADIS16240_ALM_MAG2       0x3A
-
-/* Alarm control */
-#define ADIS16240_ALM_CTRL       0x3C
-
-/* Capture, external trigger control */
-#define ADIS16240_XTRIG_CTRL     0x3E
-
-/* Capture, address pointer */
-#define ADIS16240_CAPT_PNTR      0x40
-
-/* Capture, configuration and control */
-#define ADIS16240_CAPT_CTRL      0x42
-
-/* General-purpose digital input/output control */
-#define ADIS16240_GPIO_CTRL      0x44
-
-/* Miscellaneous control */
-#define ADIS16240_MSC_CTRL       0x46
-
-/* Internal sample period (rate) control */
-#define ADIS16240_SMPL_PRD       0x48
-
-/* System command */
-#define ADIS16240_GLOB_CMD       0x4A
-
-/* MSC_CTRL */
-
-/* Enables sum-of-squares output (XYZPEAK_OUT) */
-#define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN      BIT(15)
-
-/* Enables peak tracking output (XPEAK_OUT, YPEAK_OUT, and ZPEAK_OUT) */
-#define ADIS16240_MSC_CTRL_X_Y_ZPEAK_OUT_EN    BIT(14)
-
-/* Self-test enable: 1 = apply electrostatic force, 0 = disabled */
-#define ADIS16240_MSC_CTRL_SELF_TEST_EN                BIT(8)
-
-/* Data-ready enable: 1 = enabled, 0 = disabled */
-#define ADIS16240_MSC_CTRL_DATA_RDY_EN         BIT(2)
-
-/* Data-ready polarity: 1 = active high, 0 = active low */
-#define ADIS16240_MSC_CTRL_ACTIVE_HIGH         BIT(1)
-
-/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */
-#define ADIS16240_MSC_CTRL_DATA_RDY_DIO2       BIT(0)
-
-/* DIAG_STAT */
-
-/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16240_DIAG_STAT_ALARM2      BIT(9)
-
-/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
-#define ADIS16240_DIAG_STAT_ALARM1      BIT(8)
-
-/* Capture buffer full: 1 = capture buffer is full */
-#define ADIS16240_DIAG_STAT_CPT_BUF_FUL BIT(7)
-
-/* Flash test, checksum flag: 1 = mismatch, 0 = match */
-#define ADIS16240_DIAG_STAT_CHKSUM      BIT(6)
-
-/* Power-on, self-test flag: 1 = failure, 0 = pass */
-#define ADIS16240_DIAG_STAT_PWRON_FAIL_BIT  5
-
-/* Power-on self-test: 1 = in-progress, 0 = complete */
-#define ADIS16240_DIAG_STAT_PWRON_BUSY  BIT(4)
-
-/* SPI communications failure */
-#define ADIS16240_DIAG_STAT_SPI_FAIL_BIT       3
-
-/* Flash update failure */
-#define ADIS16240_DIAG_STAT_FLASH_UPT_BIT      2
-
-/* Power supply above 3.625 V */
-#define ADIS16240_DIAG_STAT_POWER_HIGH_BIT     1
-
- /* Power supply below 3.15 V */
-#define ADIS16240_DIAG_STAT_POWER_LOW_BIT      0
-
-/* GLOB_CMD */
-
-#define ADIS16240_GLOB_CMD_RESUME      BIT(8)
-#define ADIS16240_GLOB_CMD_SW_RESET    BIT(7)
-#define ADIS16240_GLOB_CMD_STANDBY     BIT(2)
-
-#define ADIS16240_ERROR_ACTIVE          BIT(14)
-
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-#define ADIS16240_SCAN_ACC_X   0
-#define ADIS16240_SCAN_ACC_Y   1
-#define ADIS16240_SCAN_ACC_Z   2
-#define ADIS16240_SCAN_SUPPLY  3
-#define ADIS16240_SCAN_AUX_ADC 4
-#define ADIS16240_SCAN_TEMP    5
-
-#endif /* SPI_ADIS16240_H_ */
index deff899..e17efb0 100644 (file)
@@ -80,26 +80,4 @@ config AD7280
          To compile this driver as a module, choose M here: the
          module will be called ad7280a
 
-config LPC32XX_ADC
-       tristate "NXP LPC32XX ADC"
-       depends on ARCH_LPC32XX || COMPILE_TEST
-       depends on HAS_IOMEM
-       help
-         Say yes here to build support for the integrated ADC inside the
-         LPC32XX SoC. Note that this feature uses the same hardware as the
-         touchscreen driver, so you should either select only one of the two
-         drivers (lpc32xx_adc or lpc32xx_ts) or, in the OpenFirmware case,
-         activate only one via device tree selection.  Provides direct access
-         via sysfs.
-
-config SPEAR_ADC
-       tristate "ST SPEAr ADC"
-       depends on PLAT_SPEAR || COMPILE_TEST
-       depends on HAS_IOMEM
-       help
-         Say yes here to build support for the integrated ADC inside the
-         ST SPEAr SoC. Provides direct access via sysfs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called spear_adc.
 endmenu
index ac09485..bf18bdd 100644 (file)
@@ -10,5 +10,3 @@ obj-$(CONFIG_AD7780) += ad7780.o
 obj-$(CONFIG_AD7816) += ad7816.o
 obj-$(CONFIG_AD7192) += ad7192.o
 obj-$(CONFIG_AD7280) += ad7280a.o
-obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
-obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
index 1fb68c0..4fc8588 100644 (file)
@@ -342,9 +342,9 @@ ad7192_show_scale_available(struct device *dev,
 
 static IIO_DEVICE_ATTR_NAMED(in_v_m_v_scale_available,
                             in_voltage-voltage_scale_available,
-                            S_IRUGO, ad7192_show_scale_available, NULL, 0);
+                            0444, ad7192_show_scale_available, NULL, 0);
 
-static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
+static IIO_DEVICE_ATTR(in_voltage_scale_available, 0444,
                       ad7192_show_scale_available, NULL, 0);
 
 static ssize_t ad7192_show_ac_excitation(struct device *dev,
@@ -412,11 +412,11 @@ static ssize_t ad7192_set(struct device *dev,
        return ret ? ret : len;
 }
 
-static IIO_DEVICE_ATTR(bridge_switch_en, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(bridge_switch_en, 0644,
                       ad7192_show_bridge_switch, ad7192_set,
                       AD7192_REG_GPOCON);
 
-static IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(ac_excitation_en, 0644,
                       ad7192_show_ac_excitation, ad7192_set,
                       AD7192_REG_MODE);
 
index 6054c72..aa251c2 100644 (file)
@@ -267,7 +267,7 @@ static ssize_t adt7316_store_enabled(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(enabled, 0644,
                adt7316_show_enabled,
                adt7316_store_enabled,
                0);
@@ -311,7 +311,7 @@ static ssize_t adt7316_store_select_ex_temp(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(select_ex_temp, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(select_ex_temp, 0644,
                adt7316_show_select_ex_temp,
                adt7316_store_select_ex_temp,
                0);
@@ -352,7 +352,7 @@ static ssize_t adt7316_store_mode(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(mode, 0644,
                adt7316_show_mode,
                adt7316_store_mode,
                0);
@@ -364,7 +364,7 @@ static ssize_t adt7316_show_all_modes(struct device *dev,
        return sprintf(buf, "single_channel\nround_robin\n");
 }
 
-static IIO_DEVICE_ATTR(all_modes, S_IRUGO, adt7316_show_all_modes, NULL, 0);
+static IIO_DEVICE_ATTR(all_modes, 0444, adt7316_show_all_modes, NULL, 0);
 
 static ssize_t adt7316_show_ad_channel(struct device *dev,
                struct device_attribute *attr,
@@ -446,7 +446,7 @@ static ssize_t adt7316_store_ad_channel(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(ad_channel, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(ad_channel, 0644,
                adt7316_show_ad_channel,
                adt7316_store_ad_channel,
                0);
@@ -469,7 +469,7 @@ static ssize_t adt7316_show_all_ad_channels(struct device *dev,
                        "2 - External Temperature\n");
 }
 
-static IIO_DEVICE_ATTR(all_ad_channels, S_IRUGO,
+static IIO_DEVICE_ATTR(all_ad_channels, 0444,
                adt7316_show_all_ad_channels, NULL, 0);
 
 static ssize_t adt7316_show_disable_averaging(struct device *dev,
@@ -506,7 +506,7 @@ static ssize_t adt7316_store_disable_averaging(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(disable_averaging, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(disable_averaging, 0644,
                adt7316_show_disable_averaging,
                adt7316_store_disable_averaging,
                0);
@@ -545,7 +545,7 @@ static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(enable_smbus_timeout, 0644,
                adt7316_show_enable_smbus_timeout,
                adt7316_store_enable_smbus_timeout,
                0);
@@ -583,7 +583,7 @@ static ssize_t adt7316_store_powerdown(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(powerdown, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(powerdown, 0644,
                adt7316_show_powerdown,
                adt7316_store_powerdown,
                0);
@@ -621,7 +621,7 @@ static ssize_t adt7316_store_fast_ad_clock(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(fast_ad_clock, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(fast_ad_clock, 0644,
                adt7316_show_fast_ad_clock,
                adt7316_store_fast_ad_clock,
                0);
@@ -674,7 +674,7 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(da_high_resolution, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(da_high_resolution, 0644,
                adt7316_show_da_high_resolution,
                adt7316_store_da_high_resolution,
                0);
@@ -720,7 +720,7 @@ static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(AIN_internal_Vref, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(AIN_internal_Vref, 0644,
                adt7316_show_AIN_internal_Vref,
                adt7316_store_AIN_internal_Vref,
                0);
@@ -760,7 +760,7 @@ static ssize_t adt7316_store_enable_prop_DACA(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(enable_proportion_DACA, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(enable_proportion_DACA, 0644,
                adt7316_show_enable_prop_DACA,
                adt7316_store_enable_prop_DACA,
                0);
@@ -799,7 +799,7 @@ static ssize_t adt7316_store_enable_prop_DACB(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(enable_proportion_DACB, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(enable_proportion_DACB, 0644,
                adt7316_show_enable_prop_DACB,
                adt7316_store_enable_prop_DACB,
                0);
@@ -842,7 +842,7 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, 0644,
                adt7316_show_DAC_2Vref_ch_mask,
                adt7316_store_DAC_2Vref_ch_mask,
                0);
@@ -902,7 +902,7 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(DAC_update_mode, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(DAC_update_mode, 0644,
                adt7316_show_DAC_update_mode,
                adt7316_store_DAC_update_mode,
                0);
@@ -922,7 +922,7 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev,
        return sprintf(buf, "manual\n");
 }
 
-static IIO_DEVICE_ATTR(all_DAC_update_modes, S_IRUGO,
+static IIO_DEVICE_ATTR(all_DAC_update_modes, 0444,
                adt7316_show_all_DAC_update_modes, NULL, 0);
 
 
@@ -961,7 +961,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(update_DAC, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(update_DAC, 0644,
                NULL,
                adt7316_store_update_DAC,
                0);
@@ -1006,7 +1006,7 @@ static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(DA_AB_Vref_bypass, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(DA_AB_Vref_bypass, 0644,
                adt7316_show_DA_AB_Vref_bypass,
                adt7316_store_DA_AB_Vref_bypass,
                0);
@@ -1051,7 +1051,7 @@ static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(DA_CD_Vref_bypass, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(DA_CD_Vref_bypass, 0644,
                adt7316_show_DA_CD_Vref_bypass,
                adt7316_store_DA_CD_Vref_bypass,
                0);
@@ -1112,7 +1112,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
        return len;
 }
 
-static IIO_DEVICE_ATTR(DAC_internal_Vref, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(DAC_internal_Vref, 0644,
                adt7316_show_DAC_internal_Vref,
                adt7316_store_DAC_internal_Vref,
                0);
@@ -1201,7 +1201,7 @@ static ssize_t adt7316_show_VDD(struct device *dev,
 
        return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf);
 }
-static IIO_DEVICE_ATTR(VDD, S_IRUGO, adt7316_show_VDD, NULL, 0);
+static IIO_DEVICE_ATTR(VDD, 0444, adt7316_show_VDD, NULL, 0);
 
 static ssize_t adt7316_show_in_temp(struct device *dev,
                struct device_attribute *attr,
@@ -1213,7 +1213,7 @@ static ssize_t adt7316_show_in_temp(struct device *dev,
        return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf);
 }
 
-static IIO_DEVICE_ATTR(in_temp, S_IRUGO, adt7316_show_in_temp, NULL, 0);
+static IIO_DEVICE_ATTR(in_temp, 0444, adt7316_show_in_temp, NULL, 0);
 
 static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
                struct device_attribute *attr,
@@ -1225,9 +1225,9 @@ static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
        return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf);
 }
 
-static IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1,
+static IIO_DEVICE_ATTR(ex_temp_AIN1, 0444, adt7316_show_ex_temp_AIN1,
                NULL, 0);
-static IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
+static IIO_DEVICE_ATTR(ex_temp, 0444, adt7316_show_ex_temp_AIN1, NULL, 0);
 
 static ssize_t adt7316_show_AIN2(struct device *dev,
                struct device_attribute *attr,
@@ -1238,7 +1238,7 @@ static ssize_t adt7316_show_AIN2(struct device *dev,
 
        return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf);
 }
-static IIO_DEVICE_ATTR(AIN2, S_IRUGO, adt7316_show_AIN2, NULL, 0);
+static IIO_DEVICE_ATTR(AIN2, 0444, adt7316_show_AIN2, NULL, 0);
 
 static ssize_t adt7316_show_AIN3(struct device *dev,
                struct device_attribute *attr,
@@ -1249,7 +1249,7 @@ static ssize_t adt7316_show_AIN3(struct device *dev,
 
        return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf);
 }
-static IIO_DEVICE_ATTR(AIN3, S_IRUGO, adt7316_show_AIN3, NULL, 0);
+static IIO_DEVICE_ATTR(AIN3, 0444, adt7316_show_AIN3, NULL, 0);
 
 static ssize_t adt7316_show_AIN4(struct device *dev,
                struct device_attribute *attr,
@@ -1260,7 +1260,7 @@ static ssize_t adt7316_show_AIN4(struct device *dev,
 
        return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf);
 }
-static IIO_DEVICE_ATTR(AIN4, S_IRUGO, adt7316_show_AIN4, NULL, 0);
+static IIO_DEVICE_ATTR(AIN4, 0444, adt7316_show_AIN4, NULL, 0);
 
 static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
                int offset_addr, char *buf)
@@ -1325,7 +1325,7 @@ static ssize_t adt7316_store_in_temp_offset(struct device *dev,
                        len);
 }
 
-static IIO_DEVICE_ATTR(in_temp_offset, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(in_temp_offset, 0644,
                adt7316_show_in_temp_offset,
                adt7316_store_in_temp_offset, 0);
 
@@ -1351,7 +1351,7 @@ static ssize_t adt7316_store_ex_temp_offset(struct device *dev,
                        len);
 }
 
-static IIO_DEVICE_ATTR(ex_temp_offset, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(ex_temp_offset, 0644,
                adt7316_show_ex_temp_offset,
                adt7316_store_ex_temp_offset, 0);
 
@@ -1378,7 +1378,7 @@ static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev,
                        ADT7316_IN_ANALOG_TEMP_OFFSET, buf, len);
 }
 
-static IIO_DEVICE_ATTR(in_analog_temp_offset, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(in_analog_temp_offset, 0644,
                adt7316_show_in_analog_temp_offset,
                adt7316_store_in_analog_temp_offset, 0);
 
@@ -1405,7 +1405,7 @@ static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev,
                        ADT7316_EX_ANALOG_TEMP_OFFSET, buf, len);
 }
 
-static IIO_DEVICE_ATTR(ex_analog_temp_offset, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(ex_analog_temp_offset, 0644,
                adt7316_show_ex_analog_temp_offset,
                adt7316_store_ex_analog_temp_offset, 0);
 
@@ -1500,7 +1500,7 @@ static ssize_t adt7316_store_DAC_A(struct device *dev,
        return adt7316_store_DAC(chip, 0, buf, len);
 }
 
-static IIO_DEVICE_ATTR(DAC_A, S_IRUGO | S_IWUSR, adt7316_show_DAC_A,
+static IIO_DEVICE_ATTR(DAC_A, 0644, adt7316_show_DAC_A,
                adt7316_store_DAC_A, 0);
 
 static ssize_t adt7316_show_DAC_B(struct device *dev,
@@ -1524,7 +1524,7 @@ static ssize_t adt7316_store_DAC_B(struct device *dev,
        return adt7316_store_DAC(chip, 1, buf, len);
 }
 
-static IIO_DEVICE_ATTR(DAC_B, S_IRUGO | S_IWUSR, adt7316_show_DAC_B,
+static IIO_DEVICE_ATTR(DAC_B, 0644, adt7316_show_DAC_B,
                adt7316_store_DAC_B, 0);
 
 static ssize_t adt7316_show_DAC_C(struct device *dev,
@@ -1548,7 +1548,7 @@ static ssize_t adt7316_store_DAC_C(struct device *dev,
        return adt7316_store_DAC(chip, 2, buf, len);
 }
 
-static IIO_DEVICE_ATTR(DAC_C, S_IRUGO | S_IWUSR, adt7316_show_DAC_C,
+static IIO_DEVICE_ATTR(DAC_C, 0644, adt7316_show_DAC_C,
                adt7316_store_DAC_C, 0);
 
 static ssize_t adt7316_show_DAC_D(struct device *dev,
@@ -1572,7 +1572,7 @@ static ssize_t adt7316_store_DAC_D(struct device *dev,
        return adt7316_store_DAC(chip, 3, buf, len);
 }
 
-static IIO_DEVICE_ATTR(DAC_D, S_IRUGO | S_IWUSR, adt7316_show_DAC_D,
+static IIO_DEVICE_ATTR(DAC_D, 0644, adt7316_show_DAC_D,
                adt7316_store_DAC_D, 0);
 
 static ssize_t adt7316_show_device_id(struct device *dev,
@@ -1591,7 +1591,7 @@ static ssize_t adt7316_show_device_id(struct device *dev,
        return sprintf(buf, "%d\n", id);
 }
 
-static IIO_DEVICE_ATTR(device_id, S_IRUGO, adt7316_show_device_id, NULL, 0);
+static IIO_DEVICE_ATTR(device_id, 0444, adt7316_show_device_id, NULL, 0);
 
 static ssize_t adt7316_show_manufactorer_id(struct device *dev,
                struct device_attribute *attr,
@@ -1609,7 +1609,7 @@ static ssize_t adt7316_show_manufactorer_id(struct device *dev,
        return sprintf(buf, "%d\n", id);
 }
 
-static IIO_DEVICE_ATTR(manufactorer_id, S_IRUGO,
+static IIO_DEVICE_ATTR(manufactorer_id, 0444,
                adt7316_show_manufactorer_id, NULL, 0);
 
 static ssize_t adt7316_show_device_rev(struct device *dev,
@@ -1628,7 +1628,7 @@ static ssize_t adt7316_show_device_rev(struct device *dev,
        return sprintf(buf, "%d\n", rev);
 }
 
-static IIO_DEVICE_ATTR(device_rev, S_IRUGO, adt7316_show_device_rev, NULL, 0);
+static IIO_DEVICE_ATTR(device_rev, 0444, adt7316_show_device_rev, NULL, 0);
 
 static ssize_t adt7316_show_bus_type(struct device *dev,
                struct device_attribute *attr,
@@ -1649,7 +1649,7 @@ static ssize_t adt7316_show_bus_type(struct device *dev,
        return sprintf(buf, "i2c\n");
 }
 
-static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
+static IIO_DEVICE_ATTR(bus_type, 0444, adt7316_show_bus_type, NULL, 0);
 
 static struct attribute *adt7316_attributes[] = {
        &iio_dev_attr_all_modes.dev_attr.attr,
@@ -1972,61 +1972,61 @@ static ssize_t adt7316_set_int_enabled(struct device *dev,
 }
 
 static IIO_DEVICE_ATTR(int_mask,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_int_mask, adt7316_set_int_mask,
                       0);
 static IIO_DEVICE_ATTR(in_temp_high_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7316_IN_TEMP_HIGH);
 static IIO_DEVICE_ATTR(in_temp_low_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7316_IN_TEMP_LOW);
 static IIO_DEVICE_ATTR(ex_temp_high_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7316_EX_TEMP_HIGH);
 static IIO_DEVICE_ATTR(ex_temp_low_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7316_EX_TEMP_LOW);
 
 /* NASTY duplication to be fixed */
 static IIO_DEVICE_ATTR(ex_temp_ain1_high_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7316_EX_TEMP_HIGH);
 static IIO_DEVICE_ATTR(ex_temp_ain1_low_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7316_EX_TEMP_LOW);
 static IIO_DEVICE_ATTR(ain2_high_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7516_AIN2_HIGH);
 static IIO_DEVICE_ATTR(ain2_low_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7516_AIN2_LOW);
 static IIO_DEVICE_ATTR(ain3_high_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7516_AIN3_HIGH);
 static IIO_DEVICE_ATTR(ain3_low_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7516_AIN3_LOW);
 static IIO_DEVICE_ATTR(ain4_high_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7516_AIN4_HIGH);
 static IIO_DEVICE_ATTR(ain4_low_value,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_ad_bound, adt7316_set_ad_bound,
                       ADT7516_AIN4_LOW);
 static IIO_DEVICE_ATTR(int_enabled,
-                      S_IRUGO | S_IWUSR,
+                      0644,
                       adt7316_show_int_enabled,
                       adt7316_set_int_enabled, 0);
 
index b91b50f..e8609b8 100644 (file)
 #define AD7152_REG_CFG2                        26
 
 /* Status Register Bit Designations (AD7152_REG_STATUS) */
-#define AD7152_STATUS_RDY1             (1 << 0)
-#define AD7152_STATUS_RDY2             (1 << 1)
-#define AD7152_STATUS_C1C2             (1 << 2)
-#define AD7152_STATUS_PWDN             (1 << 7)
+#define AD7152_STATUS_RDY1             BIT(0)
+#define AD7152_STATUS_RDY2             BIT(1)
+#define AD7152_STATUS_C1C2             BIT(2)
+#define AD7152_STATUS_PWDN             BIT(7)
 
 /* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */
 #define AD7152_SETUP_CAPDIFF           (1 << 5)
index a5b2f06..8d40c8e 100644 (file)
 
 #include "ad9832.h"
 
+/* Registers */
+
+#define AD9832_FREQ0LL         0x0
+#define AD9832_FREQ0HL         0x1
+#define AD9832_FREQ0LM         0x2
+#define AD9832_FREQ0HM         0x3
+#define AD9832_FREQ1LL         0x4
+#define AD9832_FREQ1HL         0x5
+#define AD9832_FREQ1LM         0x6
+#define AD9832_FREQ1HM         0x7
+#define AD9832_PHASE0L         0x8
+#define AD9832_PHASE0H         0x9
+#define AD9832_PHASE1L         0xA
+#define AD9832_PHASE1H         0xB
+#define AD9832_PHASE2L         0xC
+#define AD9832_PHASE2H         0xD
+#define AD9832_PHASE3L         0xE
+#define AD9832_PHASE3H         0xF
+
+#define AD9832_PHASE_SYM       0x10
+#define AD9832_FREQ_SYM                0x11
+#define AD9832_PINCTRL_EN      0x12
+#define AD9832_OUTPUT_EN       0x13
+
+/* Command Control Bits */
+
+#define AD9832_CMD_PHA8BITSW   0x1
+#define AD9832_CMD_PHA16BITSW  0x0
+#define AD9832_CMD_FRE8BITSW   0x3
+#define AD9832_CMD_FRE16BITSW  0x2
+#define AD9832_CMD_FPSELECT    0x6
+#define AD9832_CMD_SYNCSELSRC  0x8
+#define AD9832_CMD_SLEEPRESCLR 0xC
+
+#define AD9832_FREQ            BIT(11)
+#define AD9832_PHASE(x)                (((x) & 3) << 9)
+#define AD9832_SYNC            BIT(13)
+#define AD9832_SELSRC          BIT(12)
+#define AD9832_SLEEP           BIT(13)
+#define AD9832_RESET           BIT(12)
+#define AD9832_CLR             BIT(11)
+#define CMD_SHIFT              12
+#define ADD_SHIFT              8
+#define AD9832_FREQ_BITS       32
+#define AD9832_PHASE_BITS      12
+#define RES_MASK(bits)         ((1 << (bits)) - 1)
+
+/**
+ * struct ad9832_state - driver instance specific data
+ * @spi:               spi_device
+ * @avdd:              supply regulator for the analog section
+ * @dvdd:              supply regulator for the digital section
+ * @mclk:              external master clock
+ * @ctrl_fp:           cached frequency/phase control word
+ * @ctrl_ss:           cached sync/selsrc control word
+ * @ctrl_src:          cached sleep/reset/clr word
+ * @xfer:              default spi transfer
+ * @msg:               default spi message
+ * @freq_xfer:         tuning word spi transfer
+ * @freq_msg:          tuning word spi message
+ * @phase_xfer:                tuning word spi transfer
+ * @phase_msg:         tuning word spi message
+ * @data:              spi transmit buffer
+ * @phase_data:                tuning word spi transmit buffer
+ * @freq_data:         tuning word spi transmit buffer
+ */
+
+struct ad9832_state {
+       struct spi_device               *spi;
+       struct regulator                *avdd;
+       struct regulator                *dvdd;
+       unsigned long                   mclk;
+       unsigned short                  ctrl_fp;
+       unsigned short                  ctrl_ss;
+       unsigned short                  ctrl_src;
+       struct spi_transfer             xfer;
+       struct spi_message              msg;
+       struct spi_transfer             freq_xfer[4];
+       struct spi_message              freq_msg;
+       struct spi_transfer             phase_xfer[2];
+       struct spi_message              phase_msg;
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       union {
+               __be16                  freq_data[4]____cacheline_aligned;
+               __be16                  phase_data[2];
+               __be16                  data;
+       };
+};
+
 static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout)
 {
        unsigned long long freqreg = (u64)fout *
index 1b08b04..39d326c 100644 (file)
@@ -8,98 +8,6 @@
 #ifndef IIO_DDS_AD9832_H_
 #define IIO_DDS_AD9832_H_
 
-/* Registers */
-
-#define AD9832_FREQ0LL         0x0
-#define AD9832_FREQ0HL         0x1
-#define AD9832_FREQ0LM         0x2
-#define AD9832_FREQ0HM         0x3
-#define AD9832_FREQ1LL         0x4
-#define AD9832_FREQ1HL         0x5
-#define AD9832_FREQ1LM         0x6
-#define AD9832_FREQ1HM         0x7
-#define AD9832_PHASE0L         0x8
-#define AD9832_PHASE0H         0x9
-#define AD9832_PHASE1L         0xA
-#define AD9832_PHASE1H         0xB
-#define AD9832_PHASE2L         0xC
-#define AD9832_PHASE2H         0xD
-#define AD9832_PHASE3L         0xE
-#define AD9832_PHASE3H         0xF
-
-#define AD9832_PHASE_SYM       0x10
-#define AD9832_FREQ_SYM                0x11
-#define AD9832_PINCTRL_EN      0x12
-#define AD9832_OUTPUT_EN       0x13
-
-/* Command Control Bits */
-
-#define AD9832_CMD_PHA8BITSW   0x1
-#define AD9832_CMD_PHA16BITSW  0x0
-#define AD9832_CMD_FRE8BITSW   0x3
-#define AD9832_CMD_FRE16BITSW  0x2
-#define AD9832_CMD_FPSELECT    0x6
-#define AD9832_CMD_SYNCSELSRC  0x8
-#define AD9832_CMD_SLEEPRESCLR 0xC
-
-#define AD9832_FREQ            BIT(11)
-#define AD9832_PHASE(x)                (((x) & 3) << 9)
-#define AD9832_SYNC            BIT(13)
-#define AD9832_SELSRC          BIT(12)
-#define AD9832_SLEEP           BIT(13)
-#define AD9832_RESET           BIT(12)
-#define AD9832_CLR             BIT(11)
-#define CMD_SHIFT              12
-#define ADD_SHIFT              8
-#define AD9832_FREQ_BITS       32
-#define AD9832_PHASE_BITS      12
-#define RES_MASK(bits)         ((1 << (bits)) - 1)
-
-/**
- * struct ad9832_state - driver instance specific data
- * @spi:               spi_device
- * @avdd:              supply regulator for the analog section
- * @dvdd:              supply regulator for the digital section
- * @mclk:              external master clock
- * @ctrl_fp:           cached frequency/phase control word
- * @ctrl_ss:           cached sync/selsrc control word
- * @ctrl_src:          cached sleep/reset/clr word
- * @xfer:              default spi transfer
- * @msg:               default spi message
- * @freq_xfer:         tuning word spi transfer
- * @freq_msg:          tuning word spi message
- * @phase_xfer:                tuning word spi transfer
- * @phase_msg:         tuning word spi message
- * @data:              spi transmit buffer
- * @phase_data:                tuning word spi transmit buffer
- * @freq_data:         tuning word spi transmit buffer
- */
-
-struct ad9832_state {
-       struct spi_device               *spi;
-       struct regulator                *avdd;
-       struct regulator                *dvdd;
-       unsigned long                   mclk;
-       unsigned short                  ctrl_fp;
-       unsigned short                  ctrl_ss;
-       unsigned short                  ctrl_src;
-       struct spi_transfer             xfer;
-       struct spi_message              msg;
-       struct spi_transfer             freq_xfer[4];
-       struct spi_message              freq_msg;
-       struct spi_transfer             phase_xfer[2];
-       struct spi_message              phase_msg;
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-       union {
-               __be16                  freq_data[4]____cacheline_aligned;
-               __be16                  phase_data[2];
-               __be16                  data;
-       };
-};
-
 /*
  * TODO: struct ad9832_platform_data needs to go into include/linux/iio
  */
index 19216af..f92ff7f 100644 (file)
 
 #include "ad9834.h"
 
+/* Registers */
+
+#define AD9834_REG_CMD         0
+#define AD9834_REG_FREQ0       BIT(14)
+#define AD9834_REG_FREQ1       BIT(15)
+#define AD9834_REG_PHASE0      (BIT(15) | BIT(14))
+#define AD9834_REG_PHASE1      (BIT(15) | BIT(14) | BIT(13))
+
+/* Command Control Bits */
+
+#define AD9834_B28             BIT(13)
+#define AD9834_HLB             BIT(12)
+#define AD9834_FSEL            BIT(11)
+#define AD9834_PSEL            BIT(10)
+#define AD9834_PIN_SW          BIT(9)
+#define AD9834_RESET           BIT(8)
+#define AD9834_SLEEP1          BIT(7)
+#define AD9834_SLEEP12         BIT(6)
+#define AD9834_OPBITEN         BIT(5)
+#define AD9834_SIGN_PIB                BIT(4)
+#define AD9834_DIV2            BIT(3)
+#define AD9834_MODE            BIT(1)
+
+#define AD9834_FREQ_BITS       28
+#define AD9834_PHASE_BITS      12
+
+#define RES_MASK(bits) (BIT(bits) - 1)
+
+/**
+ * struct ad9834_state - driver instance specific data
+ * @spi:               spi_device
+ * @reg:               supply regulator
+ * @mclk:              external master clock
+ * @control:           cached control word
+ * @xfer:              default spi transfer
+ * @msg:               default spi message
+ * @freq_xfer:         tuning word spi transfer
+ * @freq_msg:          tuning word spi message
+ * @data:              spi transmit buffer
+ * @freq_data:         tuning word spi transmit buffer
+ */
+
+struct ad9834_state {
+       struct spi_device               *spi;
+       struct regulator                *reg;
+       unsigned int                    mclk;
+       unsigned short                  control;
+       unsigned short                  devid;
+       struct spi_transfer             xfer;
+       struct spi_message              msg;
+       struct spi_transfer             freq_xfer[2];
+       struct spi_message              freq_msg;
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       __be16                          data ____cacheline_aligned;
+       __be16                          freq_data[2];
+};
+
+/**
+ * ad9834_supported_device_ids:
+ */
+
+enum ad9834_supported_device_ids {
+       ID_AD9833,
+       ID_AD9834,
+       ID_AD9837,
+       ID_AD9838,
+};
+
 static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout)
 {
        unsigned long long freqreg = (u64)fout * (u64)BIT(AD9834_FREQ_BITS);
index 40fdd5d..ae620f3 100644 (file)
@@ -8,67 +8,6 @@
 #ifndef IIO_DDS_AD9834_H_
 #define IIO_DDS_AD9834_H_
 
-/* Registers */
-
-#define AD9834_REG_CMD         0
-#define AD9834_REG_FREQ0       BIT(14)
-#define AD9834_REG_FREQ1       BIT(15)
-#define AD9834_REG_PHASE0      (BIT(15) | BIT(14))
-#define AD9834_REG_PHASE1      (BIT(15) | BIT(14) | BIT(13))
-
-/* Command Control Bits */
-
-#define AD9834_B28             BIT(13)
-#define AD9834_HLB             BIT(12)
-#define AD9834_FSEL            BIT(11)
-#define AD9834_PSEL            BIT(10)
-#define AD9834_PIN_SW          BIT(9)
-#define AD9834_RESET           BIT(8)
-#define AD9834_SLEEP1          BIT(7)
-#define AD9834_SLEEP12         BIT(6)
-#define AD9834_OPBITEN         BIT(5)
-#define AD9834_SIGN_PIB                BIT(4)
-#define AD9834_DIV2            BIT(3)
-#define AD9834_MODE            BIT(1)
-
-#define AD9834_FREQ_BITS       28
-#define AD9834_PHASE_BITS      12
-
-#define RES_MASK(bits) (BIT(bits) - 1)
-
-/**
- * struct ad9834_state - driver instance specific data
- * @spi:               spi_device
- * @reg:               supply regulator
- * @mclk:              external master clock
- * @control:           cached control word
- * @xfer:              default spi transfer
- * @msg:               default spi message
- * @freq_xfer:         tuning word spi transfer
- * @freq_msg:          tuning word spi message
- * @data:              spi transmit buffer
- * @freq_data:         tuning word spi transmit buffer
- */
-
-struct ad9834_state {
-       struct spi_device               *spi;
-       struct regulator                *reg;
-       unsigned int                    mclk;
-       unsigned short                  control;
-       unsigned short                  devid;
-       struct spi_transfer             xfer;
-       struct spi_message              msg;
-       struct spi_transfer             freq_xfer[2];
-       struct spi_message              freq_msg;
-
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-       __be16                          data ____cacheline_aligned;
-       __be16                          freq_data[2];
-};
-
 /*
  * TODO: struct ad7887_platform_data needs to go into include/linux/iio
  */
@@ -97,15 +36,4 @@ struct ad9834_platform_data {
        bool                    en_signbit_msb_out;
 };
 
-/**
- * ad9834_supported_device_ids:
- */
-
-enum ad9834_supported_device_ids {
-       ID_AD9833,
-       ID_AD9834,
-       ID_AD9837,
-       ID_AD9838,
-};
-
 #endif /* IIO_DDS_AD9834_H_ */
index 5e96352..297665d 100644 (file)
@@ -345,12 +345,12 @@ static ssize_t ad5933_store_frequency(struct device *dev,
        return ret ? ret : len;
 }
 
-static IIO_DEVICE_ATTR(out_voltage0_freq_start, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(out_voltage0_freq_start, 0644,
                        ad5933_show_frequency,
                        ad5933_store_frequency,
                        AD5933_REG_FREQ_START);
 
-static IIO_DEVICE_ATTR(out_voltage0_freq_increment, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(out_voltage0_freq_increment, 0644,
                        ad5933_show_frequency,
                        ad5933_store_frequency,
                        AD5933_REG_FREQ_INC);
@@ -469,32 +469,32 @@ static ssize_t ad5933_store(struct device *dev,
        return ret ? ret : len;
 }
 
-static IIO_DEVICE_ATTR(out_voltage0_scale, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(out_voltage0_scale, 0644,
                        ad5933_show,
                        ad5933_store,
                        AD5933_OUT_RANGE);
 
-static IIO_DEVICE_ATTR(out_voltage0_scale_available, S_IRUGO,
+static IIO_DEVICE_ATTR(out_voltage0_scale_available, 0444,
                        ad5933_show,
                        NULL,
                        AD5933_OUT_RANGE_AVAIL);
 
-static IIO_DEVICE_ATTR(in_voltage0_scale, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(in_voltage0_scale, 0644,
                        ad5933_show,
                        ad5933_store,
                        AD5933_IN_PGA_GAIN);
 
-static IIO_DEVICE_ATTR(in_voltage0_scale_available, S_IRUGO,
+static IIO_DEVICE_ATTR(in_voltage0_scale_available, 0444,
                        ad5933_show,
                        NULL,
                        AD5933_IN_PGA_GAIN_AVAIL);
 
-static IIO_DEVICE_ATTR(out_voltage0_freq_points, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(out_voltage0_freq_points, 0644,
                        ad5933_show,
                        ad5933_store,
                        AD5933_FREQ_POINTS);
 
-static IIO_DEVICE_ATTR(out_voltage0_settling_cycles, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(out_voltage0_settling_cycles, 0644,
                        ad5933_show,
                        ad5933_store,
                        AD5933_OUT_SETTLING_CYCLES);
index 6bb6d37..5375e7a 100644 (file)
@@ -3,6 +3,7 @@
  * ISL29028 is Concurrent Ambient Light and Proximity Sensor
  *
  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -63,6 +64,9 @@
 
 #define ISL29028_POWER_OFF_DELAY_MS            2000
 
+static const unsigned int isl29028_prox_sleep_time[] = {800, 400, 200, 100, 75,
+                                                       50, 12, 0};
+
 enum isl29028_als_ir_mode {
        ISL29028_MODE_NONE = 0,
        ISL29028_MODE_ALS,
@@ -78,22 +82,29 @@ struct isl29028_chip {
        enum isl29028_als_ir_mode       als_ir_mode;
 };
 
-static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
-                                       unsigned int sampling)
+static int isl29028_find_prox_sleep_time_index(int sampling)
 {
-       struct device *dev = regmap_get_device(chip->regmap);
-       static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0};
        unsigned int period = DIV_ROUND_UP(1000, sampling);
-       int sel, ret;
+       int i;
 
-       for (sel = 0; sel < ARRAY_SIZE(prox_period); ++sel) {
-               if (period >= prox_period[sel])
+       for (i = 0; i < ARRAY_SIZE(isl29028_prox_sleep_time); ++i) {
+               if (period >= isl29028_prox_sleep_time[i])
                        break;
        }
 
+       return i;
+}
+
+static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
+                                       unsigned int sampling)
+{
+       struct device *dev = regmap_get_device(chip->regmap);
+       int sleep_index, ret;
+
+       sleep_index = isl29028_find_prox_sleep_time_index(sampling);
        ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
                                 ISL29028_CONF_PROX_SLP_MASK,
-                                sel << ISL29028_CONF_PROX_SLP_SH);
+                                sleep_index << ISL29028_CONF_PROX_SLP_SH);
 
        if (ret < 0) {
                dev_err(dev, "%s(): Error %d setting the proximity sampling\n",
@@ -108,7 +119,7 @@ static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
 
 static int isl29028_enable_proximity(struct isl29028_chip *chip)
 {
-       int ret;
+       int sleep_index, ret;
 
        ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling);
        if (ret < 0)
@@ -121,7 +132,8 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip)
                return ret;
 
        /* Wait for conversion to be complete for first sample */
-       mdelay(DIV_ROUND_UP(1000, chip->prox_sampling));
+       sleep_index = isl29028_find_prox_sleep_time_index(chip->prox_sampling);
+       msleep(isl29028_prox_sleep_time[sleep_index]);
 
        return 0;
 }
@@ -192,7 +204,7 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
                return ret;
 
        /* Need to wait for conversion time if ALS/IR mode enabled */
-       mdelay(ISL29028_CONV_TIME_MS);
+       msleep(ISL29028_CONV_TIME_MS);
 
        chip->als_ir_mode = mode;
 
@@ -645,7 +657,8 @@ static int __maybe_unused isl29028_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops isl29028_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(isl29028_suspend, isl29028_resume)
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                               pm_runtime_force_resume)
        SET_RUNTIME_PM_OPS(isl29028_suspend, isl29028_resume, NULL)
 };
 
index 671dc99..dfd8b71 100644 (file)
@@ -6,22 +6,88 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/delay.h>
-#include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.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/mutex.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/spi/spi.h>
 #include "meter.h"
-#include "ade7753.h"
+
+#define ADE7753_WAVEFORM   0x01
+#define ADE7753_AENERGY    0x02
+#define ADE7753_RAENERGY   0x03
+#define ADE7753_LAENERGY   0x04
+#define ADE7753_VAENERGY   0x05
+#define ADE7753_RVAENERGY  0x06
+#define ADE7753_LVAENERGY  0x07
+#define ADE7753_LVARENERGY 0x08
+#define ADE7753_MODE       0x09
+#define ADE7753_IRQEN      0x0A
+#define ADE7753_STATUS     0x0B
+#define ADE7753_RSTSTATUS  0x0C
+#define ADE7753_CH1OS      0x0D
+#define ADE7753_CH2OS      0x0E
+#define ADE7753_GAIN       0x0F
+#define ADE7753_PHCAL      0x10
+#define ADE7753_APOS       0x11
+#define ADE7753_WGAIN      0x12
+#define ADE7753_WDIV       0x13
+#define ADE7753_CFNUM      0x14
+#define ADE7753_CFDEN      0x15
+#define ADE7753_IRMS       0x16
+#define ADE7753_VRMS       0x17
+#define ADE7753_IRMSOS     0x18
+#define ADE7753_VRMSOS     0x19
+#define ADE7753_VAGAIN     0x1A
+#define ADE7753_VADIV      0x1B
+#define ADE7753_LINECYC    0x1C
+#define ADE7753_ZXTOUT     0x1D
+#define ADE7753_SAGCYC     0x1E
+#define ADE7753_SAGLVL     0x1F
+#define ADE7753_IPKLVL     0x20
+#define ADE7753_VPKLVL     0x21
+#define ADE7753_IPEAK      0x22
+#define ADE7753_RSTIPEAK   0x23
+#define ADE7753_VPEAK      0x24
+#define ADE7753_RSTVPEAK   0x25
+#define ADE7753_TEMP       0x26
+#define ADE7753_PERIOD     0x27
+#define ADE7753_TMODE      0x3D
+#define ADE7753_CHKSUM     0x3E
+#define ADE7753_DIEREV     0x3F
+
+#define ADE7753_READ_REG(a)    a
+#define ADE7753_WRITE_REG(a) ((a) | 0x80)
+
+#define ADE7753_MAX_TX    4
+#define ADE7753_MAX_RX    4
+#define ADE7753_STARTUP_DELAY 1000
+
+#define ADE7753_SPI_SLOW    (u32)(300 * 1000)
+#define ADE7753_SPI_BURST   (u32)(1000 * 1000)
+#define ADE7753_SPI_FAST    (u32)(2000 * 1000)
+
+/**
+ * struct ade7753_state - device instance specific data
+ * @us:         actual spi_device
+ * @tx:         transmit buffer
+ * @rx:         receive buffer
+ * @buf_lock:       mutex to protect tx and rx
+ **/
+struct ade7753_state {
+           struct spi_device   *us;
+                   struct mutex        buf_lock;
+                           u8          tx[ADE7753_MAX_TX] ____cacheline_aligned;
+                                   u8          rx[ADE7753_MAX_RX];
+};
 
 static int ade7753_spi_write_reg_8(struct device *dev,
                                   u8 reg_address,
diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h
deleted file mode 100644 (file)
index bfe7491..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _ADE7753_H
-#define _ADE7753_H
-
-#define ADE7753_WAVEFORM   0x01
-#define ADE7753_AENERGY    0x02
-#define ADE7753_RAENERGY   0x03
-#define ADE7753_LAENERGY   0x04
-#define ADE7753_VAENERGY   0x05
-#define ADE7753_RVAENERGY  0x06
-#define ADE7753_LVAENERGY  0x07
-#define ADE7753_LVARENERGY 0x08
-#define ADE7753_MODE       0x09
-#define ADE7753_IRQEN      0x0A
-#define ADE7753_STATUS     0x0B
-#define ADE7753_RSTSTATUS  0x0C
-#define ADE7753_CH1OS      0x0D
-#define ADE7753_CH2OS      0x0E
-#define ADE7753_GAIN       0x0F
-#define ADE7753_PHCAL      0x10
-#define ADE7753_APOS       0x11
-#define ADE7753_WGAIN      0x12
-#define ADE7753_WDIV       0x13
-#define ADE7753_CFNUM      0x14
-#define ADE7753_CFDEN      0x15
-#define ADE7753_IRMS       0x16
-#define ADE7753_VRMS       0x17
-#define ADE7753_IRMSOS     0x18
-#define ADE7753_VRMSOS     0x19
-#define ADE7753_VAGAIN     0x1A
-#define ADE7753_VADIV      0x1B
-#define ADE7753_LINECYC    0x1C
-#define ADE7753_ZXTOUT     0x1D
-#define ADE7753_SAGCYC     0x1E
-#define ADE7753_SAGLVL     0x1F
-#define ADE7753_IPKLVL     0x20
-#define ADE7753_VPKLVL     0x21
-#define ADE7753_IPEAK      0x22
-#define ADE7753_RSTIPEAK   0x23
-#define ADE7753_VPEAK      0x24
-#define ADE7753_RSTVPEAK   0x25
-#define ADE7753_TEMP       0x26
-#define ADE7753_PERIOD     0x27
-#define ADE7753_TMODE      0x3D
-#define ADE7753_CHKSUM     0x3E
-#define ADE7753_DIEREV     0x3F
-
-#define ADE7753_READ_REG(a)    a
-#define ADE7753_WRITE_REG(a) ((a) | 0x80)
-
-#define ADE7753_MAX_TX    4
-#define ADE7753_MAX_RX    4
-#define ADE7753_STARTUP_DELAY 1000
-
-#define ADE7753_SPI_SLOW       (u32)(300 * 1000)
-#define ADE7753_SPI_BURST      (u32)(1000 * 1000)
-#define ADE7753_SPI_FAST       (u32)(2000 * 1000)
-
-/**
- * struct ade7753_state - device instance specific data
- * @us:                        actual spi_device
- * @tx:                        transmit buffer
- * @rx:                        receive buffer
- * @buf_lock:          mutex to protect tx and rx
- **/
-struct ade7753_state {
-       struct spi_device       *us;
-       struct mutex            buf_lock;
-       u8                      tx[ADE7753_MAX_TX] ____cacheline_aligned;
-       u8                      rx[ADE7753_MAX_RX];
-};
-
-#endif
index e8007f0..c6cffc1 100644 (file)
@@ -426,9 +426,7 @@ static int ade7854_set_irq(struct device *dev, bool enable)
        else
                irqen &= ~BIT(17);
 
-       ret = st->write_reg_32(dev, ADE7854_MASK0, irqen);
-
-       return ret;
+       return st->write_reg_32(dev, ADE7854_MASK0, irqen);
 }
 
 static int ade7854_initial_setup(struct iio_dev *indio_dev)
index dfba510..0e37f23 100644 (file)
        IIO_DEVICE_ATTR(reactive_power_c_gain, _mode, _show, _store, _addr)
 
 #define IIO_DEV_ATTR_CURRENT_A(_show, _addr)                   \
-       IIO_DEVICE_ATTR(current_a, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(current_a, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CURRENT_B(_show, _addr)                   \
-       IIO_DEVICE_ATTR(current_b, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(current_b, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CURRENT_C(_show, _addr)                   \
-       IIO_DEVICE_ATTR(current_c, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(current_c, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_VOLT_A(_show, _addr)                      \
-       IIO_DEVICE_ATTR(volt_a, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(volt_a, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_VOLT_B(_show, _addr)                      \
-       IIO_DEVICE_ATTR(volt_b, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(volt_b, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_VOLT_C(_show, _addr)                      \
-       IIO_DEVICE_ATTR(volt_c, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(volt_c, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_AENERGY(_show, _addr)                     \
-       IIO_DEVICE_ATTR(aenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(aenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_LENERGY(_show, _addr)                     \
-       IIO_DEVICE_ATTR(lenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(lenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_RAENERGY(_show, _addr)                    \
-       IIO_DEVICE_ATTR(raenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(raenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_LAENERGY(_show, _addr)                    \
-       IIO_DEVICE_ATTR(laenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(laenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_VAENERGY(_show, _addr)                    \
-       IIO_DEVICE_ATTR(vaenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(vaenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_LVAENERGY(_show, _addr)                   \
-       IIO_DEVICE_ATTR(lvaenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(lvaenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_RVAENERGY(_show, _addr)                   \
-       IIO_DEVICE_ATTR(rvaenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(rvaenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_LVARENERGY(_show, _addr)                  \
-       IIO_DEVICE_ATTR(lvarenergy, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(lvarenergy, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CHKSUM(_show, _addr)                       \
-       IIO_DEVICE_ATTR(chksum, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(chksum, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_ANGLE0(_show, _addr)                       \
-       IIO_DEVICE_ATTR(angle0, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(angle0, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_ANGLE1(_show, _addr)                       \
-       IIO_DEVICE_ATTR(angle1, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(angle1, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_ANGLE2(_show, _addr)                       \
-       IIO_DEVICE_ATTR(angle2, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(angle2, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_AWATTHR(_show, _addr)                     \
-       IIO_DEVICE_ATTR(awatthr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(awatthr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_BWATTHR(_show, _addr)                     \
-       IIO_DEVICE_ATTR(bwatthr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(bwatthr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CWATTHR(_show, _addr)                     \
-       IIO_DEVICE_ATTR(cwatthr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(cwatthr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_AFWATTHR(_show, _addr)                    \
-       IIO_DEVICE_ATTR(afwatthr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(afwatthr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_BFWATTHR(_show, _addr)                    \
-       IIO_DEVICE_ATTR(bfwatthr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(bfwatthr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CFWATTHR(_show, _addr)                    \
-       IIO_DEVICE_ATTR(cfwatthr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(cfwatthr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_AVARHR(_show, _addr)                      \
-       IIO_DEVICE_ATTR(avarhr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(avarhr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_BVARHR(_show, _addr)                      \
-       IIO_DEVICE_ATTR(bvarhr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(bvarhr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CVARHR(_show, _addr)                      \
-       IIO_DEVICE_ATTR(cvarhr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(cvarhr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_AVAHR(_show, _addr)                       \
-       IIO_DEVICE_ATTR(avahr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(avahr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_BVAHR(_show, _addr)                       \
-       IIO_DEVICE_ATTR(bvahr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(bvahr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_CVAHR(_show, _addr)                       \
-       IIO_DEVICE_ATTR(cvahr, S_IRUGO, _show, NULL, _addr)
+       IIO_DEVICE_ATTR(cvahr, 0444, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_IOS(_mode, _show, _store, _addr)                \
        IIO_DEVICE_ATTR(ios, _mode, _show, _store, _addr)
index 6b99263..90b57c0 100644 (file)
@@ -531,36 +531,36 @@ error_ret:
        return ret;
 }
 
-static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(fclkin, 0644,
                       ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
-static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(fexcit, 0644,
                       ad2s1210_show_fexcit,    ad2s1210_store_fexcit, 0);
-static IIO_DEVICE_ATTR(control, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(control, 0644,
                       ad2s1210_show_control, ad2s1210_store_control, 0);
-static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(bits, 0644,
                       ad2s1210_show_resolution, ad2s1210_store_resolution, 0);
-static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(fault, 0644,
                       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
 
-static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(los_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_LOS_THRD);
-static IIO_DEVICE_ATTR(dos_ovr_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(dos_ovr_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_DOS_OVR_THRD);
-static IIO_DEVICE_ATTR(dos_mis_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(dos_mis_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_DOS_MIS_THRD);
-static IIO_DEVICE_ATTR(dos_rst_max_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(dos_rst_max_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_DOS_RST_MAX_THRD);
-static IIO_DEVICE_ATTR(dos_rst_min_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(dos_rst_min_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_DOS_RST_MIN_THRD);
-static IIO_DEVICE_ATTR(lot_high_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(lot_high_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_LOT_HIGH_THRD);
-static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(lot_low_thrd, 0644,
                       ad2s1210_show_reg, ad2s1210_store_reg,
                       AD2S1210_REG_LOT_LOW_THRD);
 
index 30c7dc4..46dd1f2 100644 (file)
 #define HID_USAGE_SENSOR_DATA_ATMOSPHERIC_PRESSURE              0x200430
 #define HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE                   0x200431
 
+/* Tempreture (200033) */
+#define        HID_USAGE_SENSOR_TEMPERATURE                            0x200033
+#define        HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE         0x200434
+
 /* Gyro 3D: (200076) */
 #define HID_USAGE_SENSOR_GYRO_3D                               0x200076
 #define HID_USAGE_SENSOR_DATA_ANGL_VELOCITY                    0x200456