Commit ca9280d1 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-4.13a' of...

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

Jonathan writes:

First set of new device support, features and cleanups for IIO in the 4.13 cycle

Two entirely new drivers in here plus the usual range of cleanups and features.

New device support
* ad5064
  - add ltc2631, ltc2633 and ltc2635 support.
* bma180
  - trivial support for bma250e (new id)
* hid-sensor-rotation
  - add relative orientation and geometric orientation support.
* isl29028
  - add isl29030 support (its effectively the same part from a driver point of
  view)
* maxim_thermocouple
  - add max31856 id.
* meson-saradc
  - add meson8b SoC adc support.
* ti-adc084s021
  - new driver and bindings.
* ti-adc108s102
  - new driver and bindings.

Staging graduations
* isl29028

Features
* bma180
  - ACPI enumeration for BMA250E which is used in various x86 tablets.
* hi8453
  - add raw access rather than only events.
* hid-sensor-hub
  - Implement batch mode in which we can set a threshold on the amount of time
  between data coming from the fifos.  This is the first device to do this
  rather than use a watershed on the number of samples.
* hts221
  - power management support
* lsm6dsx
  - add system power management support.
* rpr0521
  - sampling frequency read / write
* stm32-trigger
  - add support for TRG02 triggers.
* tsl2583
  - runtime power management support.

Cleanups
* core
  - inkern: fix a double unlock in iio_read_available_channel_raw when raw
  value doesn't appear to be raw (error path).
  - fixup accidental sizeof pointer in iio_device_add_mask_type.
* docs
  - fix an accidental duplicated line in sysfs-bus-iio-meas-spec.
* tools
  - use local include/uapi headers to ensure always up to date.
  - increase length of allowed trigger names.
* ad9834
  - symbolic to octal permissions.
* ade7753
  - symbolic to octal permissions.
  - fix indentation
* ade7754
  - symbolic to octal permissions.
* ade7758
  - symbolic to octal permissions.
- ade7854
  - symbolic to octal permissions.
* as3935
  - move out of storm check to given consistent results for raw and processed
  values.
* bmp280
  - fix bme280 naming in Kconfig help.
* hi8435
  - avoid garbage on event after enable.
  - add missing in_voltage_sensing_mode_available to list possible enum options.
  - handle the reset gpio with the obvious polarity rather than relying on
  DT to provide it correctly.
* hid-sensors
  - fix a wrong error path scrubbing of return values.
* hid-sensors-accel
  - drop static on a local variable
* hid-sensors-rotation
  - Add missing scale and offset property parsing support.
* ina2xx
  - Fix a bad use of GENMASK and some typos and whitespace issues.
* isl29018
  - only declare the ACPI table when ACPI is enabled.
* isl29028
  - fix proximity sleep times.
* lsm6dsx
  - replace ifdef CONFIG_PM with __maybe_unused to avoid the complexity of
  dealing with the various PM config variables.
* meson-saradc
  - mark meson_sar_adc_data static and const.
* rcar-gyroadc
  - derive the interface clock speed from the fck clock on the basis they are
  the same actual clock.
  - drop the now unused if clock from the bindings.
* rpr0521
  - disable sensor when marked as such rather than always enabling it.
  - poweroff if probe fails and we can talk to device.
  - make sure device powered off when it doesn't need to be on.
  - use sizeof rather than hardcoded size on value read.
  - whitespace fixup.
  - reorder channel numbers ready for buffered support which didn't quite
  make this pull request.
* st-accel
  - fix platform data initialization to allow remove and reprobe.
* st-pressure
  - fix platform data initialization to allow remove and reprobe.
* tsl2x7x
  - S_IRUGO, S_IWUSR to octal values
  - rename driver for consistency with more recent drivers
  - drop FSF mailing address
  - replace DEVICE_ATTR macros with the shorter DEVICE_ATTR_RW form and
  relevant function renames.
* zpa2326
  - report an error for consistency with other error paths.
parents 13253d80 7e87d11c
...@@ -1425,6 +1425,17 @@ Description: ...@@ -1425,6 +1425,17 @@ Description:
guarantees that the hardware fifo is flushed to the device guarantees that the hardware fifo is flushed to the device
buffer. buffer.
What: /sys/bus/iio/devices/iio:device*/buffer/hwfifo_timeout
KernelVersion: 4.12
Contact: linux-iio@vger.kernel.org
Description:
A read/write property to provide capability to delay reporting of
samples till a timeout is reached. This allows host processors to
sleep, while the sensor is storing samples in its internal fifo.
The maximum timeout in seconds can be specified by setting
hwfifo_timeout.The current delay can be read by reading
hwfifo_timeout. A value of 0 means that there is no timeout.
What: /sys/bus/iio/devices/iio:deviceX/buffer/hwfifo_watermark What: /sys/bus/iio/devices/iio:deviceX/buffer/hwfifo_watermark
KernelVersion: 4.2 KernelVersion: 4.2
Contact: linux-iio@vger.kernel.org Contact: linux-iio@vger.kernel.org
......
...@@ -5,4 +5,3 @@ Description: ...@@ -5,4 +5,3 @@ Description:
Reading returns either '1' or '0'. '1' means that the Reading returns either '1' or '0'. '1' means that the
battery level supplied to sensor is below 2.25V. battery level supplied to sensor is below 2.25V.
This ABI is available for tsys02d, htu21, ms8607 This ABI is available for tsys02d, htu21, ms8607
This ABI is available for htu21, ms8607
...@@ -16,6 +16,54 @@ Description: ...@@ -16,6 +16,54 @@ Description:
- "OC2REF" : OC2REF signal is used as trigger output. - "OC2REF" : OC2REF signal is used as trigger output.
- "OC3REF" : OC3REF signal is used as trigger output. - "OC3REF" : OC3REF signal is used as trigger output.
- "OC4REF" : OC4REF signal is used as trigger output. - "OC4REF" : OC4REF signal is used as trigger output.
Additional modes (on TRGO2 only):
- "OC5REF" : OC5REF signal is used as trigger output.
- "OC6REF" : OC6REF signal is used as trigger output.
- "compare_pulse_OC4REF":
OC4REF rising or falling edges generate pulses.
- "compare_pulse_OC6REF":
OC6REF rising or falling edges generate pulses.
- "compare_pulse_OC4REF_r_or_OC6REF_r":
OC4REF or OC6REF rising edges generate pulses.
- "compare_pulse_OC4REF_r_or_OC6REF_f":
OC4REF rising or OC6REF falling edges generate pulses.
- "compare_pulse_OC5REF_r_or_OC6REF_r":
OC5REF or OC6REF rising edges generate pulses.
- "compare_pulse_OC5REF_r_or_OC6REF_f":
OC5REF rising or OC6REF falling edges generate pulses.
+-----------+ +-------------+ +---------+
| Prescaler +-> | Counter | +-> | Master | TRGO(2)
+-----------+ +--+--------+-+ |-> | Control +-->
| | || +---------+
+--v--------+-+ OCxREF || +---------+
| Chx compare +----------> | Output | ChX
+-----------+-+ | | Control +-->
. | | +---------+
. | | .
+-----------v-+ OC6REF | .
| Ch6 compare +---------+>
+-------------+
Example with: "compare_pulse_OC4REF_r_or_OC6REF_r":
X
X X
X . . X
X . . X
X . . X
count X . . . . X
. . . .
. . . .
+---------------+
OC4REF | . . |
+-+ . . +-+
. +---+ .
OC6REF . | | .
+-------+ +-------+
+-+ +-+
TRGO2 | | | |
+-+ +---+ +---------+
What: /sys/bus/iio/devices/triggerX/master_mode What: /sys/bus/iio/devices/triggerX/master_mode
KernelVersion: 4.11 KernelVersion: 4.11
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
Required properties: Required properties:
- compatible: depending on the SoC this should be one of: - compatible: depending on the SoC this should be one of:
- "amlogic,meson8-saradc" for Meson8
- "amlogic,meson8b-saradc" for Meson8b
- "amlogic,meson-gxbb-saradc" for GXBB - "amlogic,meson-gxbb-saradc" for GXBB
- "amlogic,meson-gxl-saradc" for GXL - "amlogic,meson-gxl-saradc" for GXL
- "amlogic,meson-gxm-saradc" for GXM - "amlogic,meson-gxm-saradc" for GXM
......
...@@ -16,8 +16,7 @@ Required properties: ...@@ -16,8 +16,7 @@ Required properties:
- clocks: References to all the clocks specified in the clock-names - clocks: References to all the clocks specified in the clock-names
property as specified in property as specified in
Documentation/devicetree/bindings/clock/clock-bindings.txt. Documentation/devicetree/bindings/clock/clock-bindings.txt.
- clock-names: Shall contain "fck" and "if". The "fck" is the GyroADC block - clock-names: Shall contain "fck". The "fck" is the GyroADC block clock.
clock, the "if" is the interface clock.
- power-domains: Must contain a reference to the PM domain, if available. - power-domains: Must contain a reference to the PM domain, if available.
- #address-cells: Should be <1> (setting for the subnodes) for all ADCs - #address-cells: Should be <1> (setting for the subnodes) for all ADCs
except for "fujitsu,mb88101a". Should be <0> (setting for except for "fujitsu,mb88101a". Should be <0> (setting for
...@@ -75,8 +74,8 @@ Example: ...@@ -75,8 +74,8 @@ Example:
adc@e6e54000 { adc@e6e54000 {
compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc"; compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc";
reg = <0 0xe6e54000 0 64>; reg = <0 0xe6e54000 0 64>;
clocks = <&mstp9_clks R8A7791_CLK_GYROADC>, <&clk_65m>; clocks = <&mstp9_clks R8A7791_CLK_GYROADC>;
clock-names = "fck", "if"; clock-names = "fck";
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
pinctrl-0 = <&adc_pins>; pinctrl-0 = <&adc_pins>;
......
* Texas Instruments' ADC084S021
Required properties:
- compatible : Must be "ti,adc084s021"
- reg : SPI chip select number for the device
- vref-supply : The regulator supply for ADC reference voltage
- spi-cpol : Per spi-bus bindings
- spi-cpha : Per spi-bus bindings
- spi-max-frequency : Per spi-bus bindings
Example:
adc@0 {
compatible = "ti,adc084s021";
reg = <0>;
vref-supply = <&adc_vref>;
spi-cpol;
spi-cpha;
spi-max-frequency = <16000000>;
};
* Texas Instruments' ADC108S102 and ADC128S102 ADC chip
Required properties:
- compatible: Should be "ti,adc108s102"
- reg: spi chip select number for the device
- vref-supply: The regulator supply for ADC reference voltage
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
adc@0 {
compatible = "ti,adc108s102";
reg = <0>;
vref-supply = <&vdd_supply>;
spi-max-frequency = <1000000>;
};
...@@ -55,6 +55,7 @@ gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire In ...@@ -55,6 +55,7 @@ gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire In
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* BMA250: 7-bit I2C slave address 0x18 or 0x19 * BMA250: 7-bit I2C slave address 0x18 or 0x19
*/ */
#include <linux/acpi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
enum chip_ids { enum chip_ids {
BMA180, BMA180,
BMA250, BMA250,
BMA250E,
}; };
struct bma180_data; struct bma180_data;
...@@ -55,6 +57,7 @@ struct bma180_part_info { ...@@ -55,6 +57,7 @@ struct bma180_part_info {
u8 power_reg, power_mask, lowpower_val; u8 power_reg, power_mask, lowpower_val;
u8 int_enable_reg, int_enable_mask; u8 int_enable_reg, int_enable_mask;
u8 softreset_reg; u8 softreset_reg;
u8 chip_id;
int (*chip_config)(struct bma180_data *data); int (*chip_config)(struct bma180_data *data);
void (*chip_disable)(struct bma180_data *data); void (*chip_disable)(struct bma180_data *data);
...@@ -112,6 +115,8 @@ struct bma180_part_info { ...@@ -112,6 +115,8 @@ struct bma180_part_info {
#define BMA250_INT1_DATA_MASK BIT(0) #define BMA250_INT1_DATA_MASK BIT(0)
#define BMA250_INT_RESET_MASK BIT(7) /* Reset pending interrupts */ #define BMA250_INT_RESET_MASK BIT(7) /* Reset pending interrupts */
#define BMA250E_CHIP_ID 0xf9
struct bma180_data { struct bma180_data {
struct i2c_client *client; struct i2c_client *client;
struct iio_trigger *trig; struct iio_trigger *trig;
...@@ -309,7 +314,7 @@ static int bma180_chip_init(struct bma180_data *data) ...@@ -309,7 +314,7 @@ static int bma180_chip_init(struct bma180_data *data)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret != BMA180_ID_REG_VAL) if (ret != data->part_info->chip_id)
return -ENODEV; return -ENODEV;
ret = bma180_soft_reset(data); ret = bma180_soft_reset(data);
...@@ -632,6 +637,7 @@ static const struct bma180_part_info bma180_part_info[] = { ...@@ -632,6 +637,7 @@ static const struct bma180_part_info bma180_part_info[] = {
BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER, BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER,
BMA180_CTRL_REG3, BMA180_NEW_DATA_INT, BMA180_CTRL_REG3, BMA180_NEW_DATA_INT,
BMA180_RESET, BMA180_RESET,
BMA180_CHIP_ID,
bma180_chip_config, bma180_chip_config,
bma180_chip_disable, bma180_chip_disable,
}, },
...@@ -646,6 +652,22 @@ static const struct bma180_part_info bma180_part_info[] = { ...@@ -646,6 +652,22 @@ static const struct bma180_part_info bma180_part_info[] = {
BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1, BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK, BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
BMA250_RESET_REG, BMA250_RESET_REG,
BMA180_CHIP_ID,
bma250_chip_config,
bma250_chip_disable,
},
[BMA250E] = {
bma250_channels, ARRAY_SIZE(bma250_channels),
bma250_scale_table, ARRAY_SIZE(bma250_scale_table),
bma250_bw_table, ARRAY_SIZE(bma250_bw_table),
BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK,
BMA250_POWER_REG, BMA250_SUSPEND_MASK,
BMA250_BW_REG, BMA250_BW_MASK,
BMA250_RANGE_REG, BMA250_RANGE_MASK,
BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
BMA250_RESET_REG,
BMA250E_CHIP_ID,
bma250_chip_config, bma250_chip_config,
bma250_chip_disable, bma250_chip_disable,
}, },
...@@ -706,6 +728,8 @@ static const struct iio_trigger_ops bma180_trigger_ops = { ...@@ -706,6 +728,8 @@ static const struct iio_trigger_ops bma180_trigger_ops = {
static int bma180_probe(struct i2c_client *client, static int bma180_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev;
const struct acpi_device_id *acpi_id;
struct bma180_data *data; struct bma180_data *data;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
enum chip_ids chip; enum chip_ids chip;
...@@ -718,10 +742,17 @@ static int bma180_probe(struct i2c_client *client, ...@@ -718,10 +742,17 @@ static int bma180_probe(struct i2c_client *client,
data = iio_priv(indio_dev); data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev); i2c_set_clientdata(client, indio_dev);
data->client = client; data->client = client;
if (client->dev.of_node) if (dev->of_node) {
chip = (enum chip_ids)of_device_get_match_data(&client->dev); chip = (enum chip_ids)of_device_get_match_data(&client->dev);
else } else if (id) {
chip = id->driver_data; chip = id->driver_data;
} else {
acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!acpi_id)
return -ENODEV;
chip = acpi_id->driver_data;
}
data->part_info = &bma180_part_info[chip]; data->part_info = &bma180_part_info[chip];
ret = data->part_info->chip_config(data); ret = data->part_info->chip_config(data);
...@@ -842,9 +873,16 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume); ...@@ -842,9 +873,16 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
#define BMA180_PM_OPS NULL #define BMA180_PM_OPS NULL
#endif #endif
static const struct acpi_device_id bma180_acpi_match[] = {
{ "BMA250E", BMA250E },
{ }
};
MODULE_DEVICE_TABLE(acpi, bma180_acpi_match);
static struct i2c_device_id bma180_ids[] = { static struct i2c_device_id bma180_ids[] = {
{ "bma180", BMA180 }, { "bma180", BMA180 },
{ "bma250", BMA250 }, { "bma250", BMA250 },
{ "bma250e", BMA250E },
{ } { }
}; };
...@@ -866,6 +904,7 @@ MODULE_DEVICE_TABLE(of, bma180_of_match); ...@@ -866,6 +904,7 @@ MODULE_DEVICE_TABLE(of, bma180_of_match);
static struct i2c_driver bma180_driver = { static struct i2c_driver bma180_driver = {
.driver = { .driver = {
.name = "bma180", .name = "bma180",
.acpi_match_table = ACPI_PTR(bma180_acpi_match),
.pm = BMA180_PM_OPS, .pm = BMA180_PM_OPS,
.of_match_table = bma180_of_match, .of_match_table = bma180_of_match,
}, },
......
...@@ -347,7 +347,7 @@ static int accel_3d_parse_report(struct platform_device *pdev, ...@@ -347,7 +347,7 @@ static int accel_3d_parse_report(struct platform_device *pdev,
static int hid_accel_3d_probe(struct platform_device *pdev) static int hid_accel_3d_probe(struct platform_device *pdev)
{ {
int ret = 0; int ret = 0;
static const char *name; const char *name;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
struct accel_3d_state *accel_state; struct accel_3d_state *accel_state;
const struct iio_chan_spec *channel_spec; const struct iio_chan_spec *channel_spec;
......
...@@ -710,6 +710,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { ...@@ -710,6 +710,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
int st_accel_common_probe(struct iio_dev *indio_dev) int st_accel_common_probe(struct iio_dev *indio_dev)
{ {
struct st_sensor_data *adata = iio_priv(indio_dev); struct st_sensor_data *adata = iio_priv(indio_dev);
struct st_sensors_platform_data *pdata =
(struct st_sensors_platform_data *)adata->dev->platform_data;
int irq = adata->get_irq_data_ready(indio_dev); int irq = adata->get_irq_data_ready(indio_dev);
int err; int err;
...@@ -736,9 +738,8 @@ int st_accel_common_probe(struct iio_dev *indio_dev) ...@@ -736,9 +738,8 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
&adata->sensor_settings->fs.fs_avl[0]; &adata->sensor_settings->fs.fs_avl[0];
adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
if (!adata->dev->platform_data) if (!pdata)
adata->dev->platform_data = pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
(struct st_sensors_platform_data *)&default_accel_pdata;
err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
if (err < 0) if (err < 0)
......
...@@ -679,6 +679,18 @@ config TI_ADC0832 ...@@ -679,6 +679,18 @@ config TI_ADC0832
This driver can also be built as a module. If so, the module will be This driver can also be built as a module. If so, the module will be
called ti-adc0832. called ti-adc0832.
config TI_ADC084S021
tristate "Texas Instruments ADC084S021"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
If you say yes here you get support for Texas Instruments ADC084S021
chips.
This driver can also be built as a module. If so, the module will be
called ti-adc084s021.
config TI_ADC12138 config TI_ADC12138
tristate "Texas Instruments ADC12130/ADC12132/ADC12138" tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
depends on SPI depends on SPI
...@@ -691,6 +703,18 @@ config TI_ADC12138 ...@@ -691,6 +703,18 @@ config TI_ADC12138
This driver can also be built as a module. If so, the module will be This driver can also be built as a module. If so, the module will be
called ti-adc12138. called ti-adc12138.
config TI_ADC108S102
tristate "Texas Instruments ADC108S102 and ADC128S102 driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Texas Instruments ADC108S102 and
ADC128S102 ADC.
To compile this driver as a module, choose M here: the module will
be called ti-adc108s102.
config TI_ADC128S052 config TI_ADC128S052
tristate "Texas Instruments ADC128S052/ADC122S021/ADC124S021" tristate "Texas Instruments ADC128S052/ADC122S021/ADC124S021"
depends on SPI depends on SPI
......
...@@ -62,7 +62,9 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o ...@@ -62,7 +62,9 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
obj-$(CONFIG_STM32_ADC) += stm32-adc.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
obj-$(CONFIG_TI_ADC108S102) += ti-adc108s102.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
......
...@@ -105,6 +105,26 @@ static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val) ...@@ -105,6 +105,26 @@ static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val)
return spi_write(priv->spi, priv->reg_buffer, 3); return spi_write(priv->spi, priv->reg_buffer, 3);
} }
static int hi8435_read_raw(struct iio_dev *idev,
const struct iio_chan_spec *chan,
int *val, int *val2, long mask)
{
struct hi8435_priv *priv = iio_priv(idev);
u32 tmp;
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
if (ret < 0)
return ret;
*val = !!(tmp & BIT(chan->channel));
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
static int hi8435_read_event_config(struct iio_dev *idev, static int hi8435_read_event_config(struct iio_dev *idev,
const struct iio_chan_spec *chan, const struct iio_chan_spec *chan,
enum iio_event_type type, enum iio_event_type type,
...@@ -121,10 +141,21 @@ static int hi8435_write_event_config(struct iio_dev *idev, ...@@ -121,10 +141,21 @@ static int hi8435_write_event_config(struct iio_dev *idev,
enum iio_event_direction dir, int state) enum iio_event_direction dir, int state)
{ {
struct hi8435_priv *priv = iio_priv(idev); struct hi8435_priv *priv = iio_priv(idev);
int ret;
u32 tmp;
if (state) {
ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
if (ret < 0)
return ret;
if (tmp & BIT(chan->channel))
priv->event_prev_val |= BIT(chan->channel);
else
priv->event_prev_val &= ~BIT(chan->channel);
priv->event_scan_mask &= ~BIT(chan->channel);
if (state)
priv->event_scan_mask |= BIT(chan->channel); priv->event_scan_mask |= BIT(chan->channel);
} else
priv->event_scan_mask &= ~BIT(chan->channel);
return 0; return 0;
} }
...@@ -325,6 +356,7 @@ static const struct iio_enum hi8435_sensing_mode = { ...@@ -325,6 +356,7 @@ static const struct iio_enum hi8435_sensing_mode = {
static const struct iio_chan_spec_ext_info hi8435_ext_info[] = { static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode), IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode),
IIO_ENUM_AVAILABLE("sensing_mode", &hi8435_sensing_mode),
{}, {},
}; };
...@@ -333,6 +365,7 @@ static const struct iio_chan_spec_ext_info hi8435_ext_info[] = { ...@@ -333,6 +365,7 @@ static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
.type = IIO_VOLTAGE, \ .type = IIO_VOLTAGE, \
.indexed = 1, \ .indexed = 1, \
.channel = num, \ .channel = num, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.event_spec = hi8435_events, \ .event_spec = hi8435_events, \
.num_event_specs = ARRAY_SIZE(hi8435_events), \ .num_event_specs = ARRAY_SIZE(hi8435_events), \
.ext_info = hi8435_ext_info, \ .ext_info = hi8435_ext_info, \
...@@ -376,6 +409,7 @@ static const struct iio_chan_spec hi8435_channels[] = { ...@@ -376,6 +409,7 @@ static const struct iio_chan_spec hi8435_channels[] = {
static const struct iio_info hi8435_info = { static const struct iio_info hi8435_info = {
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
.read_raw = hi8435_read_raw,
.read_event_config = &hi8435_read_event_config, .read_event_config = &hi8435_read_event_config,
.write_event_config = hi8435_write_event_config, .write_event_config = hi8435_write_event_config,
.read_event_value = &hi8435_read_event_value, .read_event_value = &hi8435_read_event_value,
...@@ -442,13 +476,15 @@ static int hi8435_probe(struct spi_device *spi) ...@@ -442,13 +476,15 @@ static int hi8435_probe(struct spi_device *spi)
priv->spi = spi; priv->spi = spi;
reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW); reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW);
if (IS_ERR(reset_gpio)) { if (!IS_ERR(reset_gpio)) {
/* chip s/w reset if h/w reset failed */ /* need >=100ns low pulse to reset chip */
gpiod_set_raw_value_cansleep(reset_gpio, 0);
udelay(1);
gpiod_set_raw_value_cansleep(reset_gpio, 1);
} else {
/* s/w reset chip if h/w reset is not available */
hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST); hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
hi8435_writeb(priv, HI8435_CTRL_REG, 0); hi8435_writeb(priv, HI8435_CTRL_REG, 0);
} else {
udelay(5);
gpiod_set_value(reset_gpio, 1);
} }
spi_set_drvdata(spi, idev); spi_set_drvdata(spi, idev);
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
#define INA2XX_CURRENT 0x04 /* readonly */ #define INA2XX_CURRENT 0x04 /* readonly */
#define INA2XX_CALIBRATION 0x05 #define INA2XX_CALIBRATION 0x05
#define INA226_ALERT_MASK GENMASK(2, 1) #define INA226_MASK_ENABLE 0x06
#define INA266_CVRF BIT(3) #define INA226_CVRF BIT(3)
#define INA2XX_MAX_REGISTERS 8 #define INA2XX_MAX_REGISTERS 8
...@@ -417,8 +417,8 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, ...@@ -417,8 +417,8 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
.address = (_address), \ .address = (_address), \
.indexed = 1, \ .indexed = 1, \
.channel = (_index), \ .channel = (_index), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
| BIT(IIO_CHAN_INFO_SCALE), \ BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.scan_index = (_index), \ .scan_index = (_index), \
...@@ -481,12 +481,12 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) ...@@ -481,12 +481,12 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
*/ */
if (!chip->allow_async_readout) if (!chip->allow_async_readout)
do { do {
ret = regmap_read(chip->regmap, INA226_ALERT_MASK, ret = regmap_read(chip->regmap, INA226_MASK_ENABLE,
&alert); &alert);
if (ret < 0) if (ret < 0)
return ret; return ret;
alert &= INA266_CVRF; alert &= INA226_CVRF;
} while (!alert); } while (!alert);
/* /*
......
...@@ -220,6 +220,7 @@ enum meson_sar_adc_chan7_mux_sel { ...@@ -220,6 +220,7 @@ enum meson_sar_adc_chan7_mux_sel {
}; };
struct meson_sar_adc_data { struct meson_sar_adc_data {
bool has_bl30_integration;
unsigned int resolution; unsigned int resolution;
const char *name; const char *name;
}; };
...@@ -437,12 +438,16 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) ...@@ -437,12 +438,16 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
mutex_lock(&indio_dev->mlock); mutex_lock(&indio_dev->mlock);
if (priv->data->has_bl30_integration) {
/* prevent BL30 from using the SAR ADC while we are using it */ /* prevent BL30 from using the SAR ADC while we are using it */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY, MESON_SAR_ADC_DELAY_KERNEL_BUSY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY); MESON_SAR_ADC_DELAY_KERNEL_BUSY);
/* wait until BL30 releases it's lock (so we can use the SAR ADC) */ /*
* wait until BL30 releases it's lock (so we can use the SAR
* ADC)
*/
do { do {
udelay(1); udelay(1);
regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val); regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
...@@ -450,6 +455,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev) ...@@ -450,6 +455,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
if (timeout < 0) if (timeout < 0)
return -ETIMEDOUT; return -ETIMEDOUT;
}
return 0; return 0;
} }
...@@ -458,6 +464,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev) ...@@ -458,6 +464,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
{ {
struct meson_sar_adc_priv *priv = iio_priv(indio_dev); struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
if (priv->data->has_bl30_integration)
/* allow BL30 to use the SAR ADC again */ /* allow BL30 to use the SAR ADC again */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0); MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
...@@ -614,14 +621,16 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev) ...@@ -614,14 +621,16 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
*/ */
meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT); meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT);
if (priv->data->has_bl30_integration) {
/* /*
* leave sampling delay and the input clocks as configured by BL30 to * leave sampling delay and the input clocks as configured by
* make sure BL30 gets the values it expects when reading the * BL30 to make sure BL30 gets the values it expects when
* temperature sensor. * reading the temperature sensor.
*/ */
regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval); regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
return 0; return 0;
}
meson_sar_adc_stop_sample_engine(indio_dev); meson_sar_adc_stop_sample_engine(indio_dev);
...@@ -834,22 +843,45 @@ static const struct iio_info meson_sar_adc_iio_info = { ...@@ -834,22 +843,45 @@ static const struct iio_info meson_sar_adc_iio_info = {
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
}; };
struct meson_sar_adc_data meson_sar_adc_gxbb_data = { static const struct meson_sar_adc_data meson_sar_adc_meson8_data = {
.has_bl30_integration = false,
.resolution = 10,
.name = "meson-meson8-saradc",
};
static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = {
.has_bl30_integration = false,
.resolution = 10,
.name = "meson-meson8b-saradc",
};
static const struct meson_sar_adc_data meson_sar_adc_gxbb_data = {
.has_bl30_integration = true,
.resolution = 10, .resolution = 10,
.name = "meson-gxbb-saradc", .name = "meson-gxbb-saradc",
}; };
struct meson_sar_adc_data meson_sar_adc_gxl_data = { static const struct meson_sar_adc_data meson_sar_adc_gxl_data = {
.has_bl30_integration = true,
.resolution = 12, .resolution = 12,
.name = "meson-gxl-saradc", .name = "meson-gxl-saradc",
}; };
struct meson_sar_adc_data meson_sar_adc_gxm_data = { static const struct meson_sar_adc_data meson_sar_adc_gxm_data = {
.has_bl30_integration = true,
.resolution = 12, .resolution = 12,
.name = "meson-gxm-saradc", .name = "meson-gxm-saradc",
}; };
static const struct of_device_id meson_sar_adc_of_match[] = { static const struct of_device_id meson_sar_adc_of_match[] = {
{
.compatible = "amlogic,meson8-saradc",
.data = &meson_sar_adc_meson8_data,
},
{
.compatible = "amlogic,meson8b-saradc",
.data = &meson_sar_adc_meson8b_data,
},
{ {
.compatible = "amlogic,meson-gxbb-saradc", .compatible = "amlogic,meson-gxbb-saradc",
.data = &meson_sar_adc_gxbb_data, .data = &meson_sar_adc_gxbb_data,
......
...@@ -73,7 +73,7 @@ enum rcar_gyroadc_model { ...@@ -73,7 +73,7 @@ enum rcar_gyroadc_model {
struct rcar_gyroadc { struct rcar_gyroadc {
struct device *dev; struct device *dev;
void __iomem *regs; void __iomem *regs;
struct clk *iclk; struct clk *clk;
struct regulator *vref[8]; struct regulator *vref[8];
unsigned int num_channels; unsigned int num_channels;
enum rcar_gyroadc_model model; enum rcar_gyroadc_model model;
...@@ -83,7 +83,7 @@ struct rcar_gyroadc { ...@@ -83,7 +83,7 @@ struct rcar_gyroadc {
static void rcar_gyroadc_hw_init(struct rcar_gyroadc *priv) static void rcar_gyroadc_hw_init(struct rcar_gyroadc *priv)
{ {
const unsigned long clk_mhz = clk_get_rate(priv->iclk) / 1000000; const unsigned long clk_mhz = clk_get_rate(priv->clk) / 1000000;
const unsigned long clk_mul = const unsigned long clk_mul =
(priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) ? 10 : 5; (priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) ? 10 : 5;
unsigned long clk_len = clk_mhz * clk_mul; unsigned long clk_len = clk_mhz * clk_mul;
...@@ -510,9 +510,9 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) ...@@ -510,9 +510,9 @@ static int rcar_gyroadc_probe(struct platform_device *pdev)
if (IS_ERR(priv->regs)) if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs); return PTR_ERR(priv->regs);
priv->iclk = devm_clk_get(dev, "if"); priv->clk = devm_clk_get(dev, "fck");
if (IS_ERR(priv->iclk)) { if (IS_ERR(priv->clk)) {
ret = PTR_ERR(priv->iclk); ret = PTR_ERR(priv->clk);
if (ret != -EPROBE_DEFER) if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret); dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret);
return ret; return ret;
...@@ -536,7 +536,7 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) ...@@ -536,7 +536,7 @@ static int rcar_gyroadc_probe(struct platform_device *pdev)
indio_dev->info = &rcar_gyroadc_iio_info; indio_dev->info = &rcar_gyroadc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
ret = clk_prepare_enable(priv->iclk); ret = clk_prepare_enable(priv->clk);
if (ret) { if (ret) {
dev_err(dev, "Could not prepare or enable the IF clock.\n"); dev_err(dev, "Could not prepare or enable the IF clock.\n");
goto err_clk_if_enable; goto err_clk_if_enable;
...@@ -565,7 +565,7 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) ...@@ -565,7 +565,7 @@ static int rcar_gyroadc_probe(struct platform_device *pdev)
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
pm_runtime_disable(dev); pm_runtime_disable(dev);
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
clk_disable_unprepare(priv->iclk); clk_disable_unprepare(priv->clk);
err_clk_if_enable: err_clk_if_enable:
rcar_gyroadc_deinit_supplies(indio_dev); rcar_gyroadc_deinit_supplies(indio_dev);
...@@ -584,7 +584,7 @@ static int rcar_gyroadc_remove(struct platform_device *pdev) ...@@ -584,7 +584,7 @@ static int rcar_gyroadc_remove(struct platform_device *pdev)
pm_runtime_put_sync(dev); pm_runtime_put_sync(dev);
pm_runtime_disable(dev); pm_runtime_disable(dev);
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
clk_disable_unprepare(priv->iclk); clk_disable_unprepare(priv->clk);
rcar_gyroadc_deinit_supplies(indio_dev); rcar_gyroadc_deinit_supplies(indio_dev);
return 0; return 0;
......
/**
* Copyright (C) 2017 Axis Communications AB
*
* Driver for Texas Instruments' ADC084S021 ADC chip.
* Datasheets can be found here:
* http://www.ti.com/lit/ds/symlink/adc084s021.pdf
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/regulator/consumer.h>
#define ADC084S021_DRIVER_NAME "adc084s021"
struct adc084s021 {
struct spi_device *spi;
struct spi_message message;
struct spi_transfer spi_trans;
struct regulator *reg;
struct mutex lock;
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache line.
*/
u16 tx_buf[4] ____cacheline_aligned;
__be16 rx_buf[5]; /* First 16-bits are trash */
};
#define ADC084S021_VOLTAGE_CHANNEL(num) \
{ \
.type = IIO_VOLTAGE, \
.channel = (num), \
.indexed = 1, \
.scan_index = (num), \
.scan_type = { \
.sign = 'u', \
.realbits = 8, \
.storagebits = 16, \
.shift = 4, \
.endianness = IIO_BE, \
}, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
}
static const struct iio_chan_spec adc084s021_channels[] = {
ADC084S021_VOLTAGE_CHANNEL(0),
ADC084S021_VOLTAGE_CHANNEL(1),
ADC084S021_VOLTAGE_CHANNEL(2),
ADC084S021_VOLTAGE_CHANNEL(3),
IIO_CHAN_SOFT_TIMESTAMP(4),
};
/**
* Read an ADC channel and return its value.
*
* @adc: The ADC SPI data.
* @data: Buffer for converted data.
*/
static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data)
{
int n_words = (adc->spi_trans.len >> 1) - 1; /* Discard first word */
int ret, i = 0;
u16 *p = data;
/* Do the transfer */
ret = spi_sync(adc->spi, &adc->message);
if (ret < 0)
return ret;
for (; i < n_words; i++)
*(p + i) = adc->rx_buf[i + 1];
return ret;
}
static int adc084s021_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *channel, int *val,
int *val2, long mask)
{
struct adc084s021 *adc = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret < 0)
return ret;
ret = regulator_enable(adc->reg);
if (ret) {
iio_device_release_direct_mode(indio_dev);
return ret;
}
adc->tx_buf[0] = channel->channel << 3;
ret = adc084s021_adc_conversion(adc, val);
iio_device_release_direct_mode(indio_dev);
regulator_disable(adc->reg);
if (ret < 0)
return ret;
*val = be16_to_cpu(*val);
*val = (*val >> channel->scan_type.shift) & 0xff;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
ret = regulator_enable(adc->reg);
if (ret)
return ret;
ret = regulator_get_voltage(adc->reg);
regulator_disable(adc->reg);
if (ret < 0)
return ret;
*val = ret / 1000;
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
/**
* Read enabled ADC channels and push data to the buffer.
*
* @irq: The interrupt number (not used).
* @pollfunc: Pointer to the poll func.
*/
static irqreturn_t adc084s021_buffer_trigger_handler(int irq, void *pollfunc)
{
struct iio_poll_func *pf = pollfunc;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc084s021 *adc = iio_priv(indio_dev);
__be16 data[8] = {0}; /* 4 * 16-bit words of data + 8 bytes timestamp */
mutex_lock(&adc->lock);
if (adc084s021_adc_conversion(adc, &data) < 0)
dev_err(&adc->spi->dev, "Failed to read data\n");
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_get_time_ns(indio_dev));
mutex_unlock(&adc->lock);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int adc084s021_buffer_preenable(struct iio_dev *indio_dev)
{
struct adc084s021 *adc = iio_priv(indio_dev);
int scan_index;
int i = 0;
for_each_set_bit(scan_index, indio_dev->active_scan_mask,
indio_dev->masklength) {
const struct iio_chan_spec *channel =
&indio_dev->channels[scan_index];
adc->tx_buf[i++] = channel->channel << 3;
}
adc->spi_trans.len = 2 + (i * sizeof(__be16)); /* Trash + channels */
return regulator_enable(adc->reg);
}
static int adc084s021_buffer_postdisable(struct iio_dev *indio_dev)
{
struct adc084s021 *adc = iio_priv(indio_dev);
adc->spi_trans.len = 4; /* Trash + single channel */
return regulator_disable(adc->reg);
}
static const struct iio_info adc084s021_info = {
.read_raw = adc084s021_read_raw,
.driver_module = THIS_MODULE,
};
static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = {
.preenable = adc084s021_buffer_preenable,
.postenable = iio_triggered_buffer_postenable,
.predisable = iio_triggered_buffer_predisable,
.postdisable = adc084s021_buffer_postdisable,
};
static int adc084s021_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct adc084s021 *adc;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
if (!indio_dev) {
dev_err(&spi->dev, "Failed to allocate IIO device\n");
return -ENOMEM;
}
adc = iio_priv(indio_dev);
adc->spi = spi;
/* Connect the SPI device and the iio dev */
spi_set_drvdata(spi, indio_dev);
/* Initiate the Industrial I/O device */
indio_dev->dev.parent = &spi->dev;
indio_dev->dev.of_node = spi->dev.of_node;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &adc084s021_info;
indio_dev->channels = adc084s021_channels;
indio_dev->num_channels = ARRAY_SIZE(adc084s021_channels);
/* Create SPI transfer for channel reads */
adc->spi_trans.tx_buf = adc->tx_buf;
adc->spi_trans.rx_buf = adc->rx_buf;
adc->spi_trans.len = 4; /* Trash + single channel */
spi_message_init_with_transfers(&adc->message, &adc->spi_trans, 1);
adc->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(adc->reg))
return PTR_ERR(adc->reg);
mutex_init(&adc->lock);
/* Setup triggered buffer with pollfunction */
ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
adc084s021_buffer_trigger_handler,
&adc084s021_buffer_setup_ops);
if (ret) {
dev_err(&spi->dev, "Failed to setup triggered buffer\n");
return ret;
}
return devm_iio_device_register(&spi->dev, indio_dev);
}
static const struct of_device_id adc084s021_of_match[] = {
{ .compatible = "ti,adc084s021", },
{},
};
MODULE_DEVICE_TABLE(of, adc084s021_of_match);
static const struct spi_device_id adc084s021_id[] = {
{ ADC084S021_DRIVER_NAME, 0},
{}
};
MODULE_DEVICE_TABLE(spi, adc084s021_id);
static struct spi_driver adc084s021_driver = {
.driver = {
.name = ADC084S021_DRIVER_NAME,
.of_match_table = of_match_ptr(adc084s021_of_match),
},
.probe = adc084s021_probe,
.id_table = adc084s021_id,
};
module_spi_driver(adc084s021_driver);
MODULE_AUTHOR("Mårten Lindahl <martenli@axis.com>");
MODULE_DESCRIPTION("Texas Instruments ADC084S021");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("1.0");
/*
* TI ADC108S102 SPI ADC driver
*
* Copyright (c) 2013-2015 Intel Corporation.
* Copyright (c) 2017 Siemens AG
*
* 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.
*
* This IIO device driver is designed to work with the following
* analog to digital converters from Texas Instruments:
* ADC108S102
* ADC128S102
* The communication with ADC chip is via the SPI bus (mode 3).
*/
#include <linux/acpi.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/types.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
/*
* In case of ACPI, we use the hard-wired 5000 mV of the Galileo and IOT2000
* boards as default for the reference pin VA. Device tree users encode that
* via the vref-supply regulator.
*/
#define ADC108S102_VA_MV_ACPI_DEFAULT 5000
/*
* Defining the ADC resolution being 12 bits, we can use the same driver for
* both ADC108S102 (10 bits resolution) and ADC128S102 (12 bits resolution)
* chips. The ADC108S102 effectively returns a 12-bit result with the 2
* least-significant bits unset.
*/
#define ADC108S102_BITS 12
#define ADC108S102_MAX_CHANNELS 8
/*
* 16-bit SPI command format:
* [15:14] Ignored
* [13:11] 3-bit channel address
* [10:0] Ignored
*/
#define ADC108S102_CMD(ch) ((u16)(ch) << 11)
/*
* 16-bit SPI response format:
* [15:12] Zeros
* [11:0] 12-bit ADC sample (for ADC108S102, [1:0] will always be 0).
*/
#define ADC108S102_RES_DATA(res) ((u16)res & GENMASK(11, 0))
struct adc108s102_state {
struct spi_device *spi;
struct regulator *reg;
u32 va_millivolt;
/* SPI transfer used by triggered buffer handler*/
struct spi_transfer ring_xfer;
/* SPI transfer used by direct scan */
struct spi_transfer scan_single_xfer;
/* SPI message used by ring_xfer SPI transfer */
struct spi_message ring_msg;
/* SPI message used by scan_single_xfer SPI transfer */
struct spi_message scan_single_msg;
/*
* SPI message buffers:
* tx_buf: |C0|C1|C2|C3|C4|C5|C6|C7|XX|
* rx_buf: |XX|R0|R1|R2|R3|R4|R5|R6|R7|tt|tt|tt|tt|
*
* tx_buf: 8 channel read commands, plus 1 dummy command
* rx_buf: 1 dummy response, 8 channel responses, plus 64-bit timestamp
*/
__be16 rx_buf[13] ____cacheline_aligned;
__be16 tx_buf[9] ____cacheline_aligned;
};
#define ADC108S102_V_CHAN(index) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = index, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.address = index, \
.scan_index = index, \
.scan_type = { \
.sign = 'u', \
.realbits = ADC108S102_BITS, \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
}
static const struct iio_chan_spec adc108s102_channels[] = {
ADC108S102_V_CHAN(0),
ADC108S102_V_CHAN(1),
ADC108S102_V_CHAN(2),
ADC108S102_V_CHAN(3),
ADC108S102_V_CHAN(4),
ADC108S102_V_CHAN(5),
ADC108S102_V_CHAN(6),
ADC108S102_V_CHAN(7),
IIO_CHAN_SOFT_TIMESTAMP(8),
};
static int adc108s102_update_scan_mode(struct iio_dev *indio_dev,
unsigned long const *active_scan_mask)
{
struct adc108s102_state *st = iio_priv(indio_dev);
unsigned int bit, cmds;
/*
* Fill in the first x shorts of tx_buf with the number of channels
* enabled for sampling by the triggered buffer.
*/
cmds = 0;
for_each_set_bit(bit, active_scan_mask, ADC108S102_MAX_CHANNELS)
st->tx_buf[cmds++] = cpu_to_be16(ADC108S102_CMD(bit));
/* One dummy command added, to clock in the last response */
st->tx_buf[cmds++] = 0x00;
/* build SPI ring message */
st->ring_xfer.tx_buf = &st->tx_buf[0];
st->ring_xfer.rx_buf = &st->rx_buf[0];
st->ring_xfer.len = cmds * sizeof(st->tx_buf[0]);
spi_message_init_with_transfers(&st->ring_msg, &st->ring_xfer, 1);
return 0;
}
static irqreturn_t adc108s102_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc108s102_state *st = iio_priv(indio_dev);
int ret;
ret = spi_sync(st->spi, &st->ring_msg);
if (ret < 0)
goto out_notify;
/* Skip the dummy response in the first slot */
iio_push_to_buffers_with_timestamp(indio_dev,
(u8 *)&st->rx_buf[1],
iio_get_time_ns(indio_dev));
out_notify:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int adc108s102_scan_direct(struct adc108s102_state *st, unsigned int ch)
{
int ret;
st->tx_buf[0] = cpu_to_be16(ADC108S102_CMD(ch));
ret = spi_sync(st->spi, &st->scan_single_msg);
if (ret)
return ret;
/* Skip the dummy response in the first slot */
return be16_to_cpu(st->rx_buf[1]);
}
static int adc108s102_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long m)
{
struct adc108s102_state *st = iio_priv(indio_dev);
int ret;
switch (m) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
ret = adc108s102_scan_direct(st, chan->address);
iio_device_release_direct_mode(indio_dev);
if (ret < 0)
return ret;
*val = ADC108S102_RES_DATA(ret);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (chan->type != IIO_VOLTAGE)
break;
*val = st->va_millivolt;
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
default:
break;
}
return -EINVAL;
}
static const struct iio_info adc108s102_info = {
.read_raw = &adc108s102_read_raw,
.update_scan_mode = &adc108s102_update_scan_mode,
.driver_module = THIS_MODULE,
};
static int adc108s102_probe(struct spi_device *spi)
{
struct adc108s102_state *st;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
if (ACPI_COMPANION(&spi->dev)) {
st->va_millivolt = ADC108S102_VA_MV_ACPI_DEFAULT;
} else {
st->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret < 0) {
dev_err(&spi->dev, "Cannot enable vref regulator\n");
return ret;
}
ret = regulator_get_voltage(st->reg);
if (ret < 0) {
dev_err(&spi->dev, "vref get voltage failed\n");
return ret;
}
st->va_millivolt = ret / 1000;
}
spi_set_drvdata(spi, indio_dev);
st->spi = spi;
indio_dev->name = spi->modalias;
indio_dev->dev.parent = &spi->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = adc108s102_channels;
indio_dev->num_channels = ARRAY_SIZE(adc108s102_channels);
indio_dev->info = &adc108s102_info;
/* Setup default message */
st->scan_single_xfer.tx_buf = st->tx_buf;
st->scan_single_xfer.rx_buf = st->rx_buf;
st->scan_single_xfer.len = 2 * sizeof(st->tx_buf[0]);
spi_message_init_with_transfers(&st->scan_single_msg,
&st->scan_single_xfer, 1);
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&adc108s102_trigger_handler, NULL);
if (ret)
goto error_disable_reg;
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&spi->dev, "Failed to register IIO device\n");
goto error_cleanup_triggered_buffer;
}
return 0;
error_cleanup_triggered_buffer:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
regulator_disable(st->reg);
return ret;
}
static int adc108s102_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adc108s102_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(st->reg);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id adc108s102_of_match[] = {
{ .compatible = "ti,adc108s102" },
{ }
};
MODULE_DEVICE_TABLE(of, adc108s102_of_match);
#endif
#ifdef CONFIG_ACPI
static const struct acpi_device_id adc108s102_acpi_ids[] = {
{ "INT3495", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, adc108s102_acpi_ids);
#endif
static const struct spi_device_id adc108s102_id[] = {
{ "adc108s102", 0 },
{ }
};
MODULE_DEVICE_TABLE(spi, adc108s102_id);
static struct spi_driver adc108s102_driver = {
.driver = {
.name = "adc108s102",
.of_match_table = of_match_ptr(adc108s102_of_match),
.acpi_match_table = ACPI_PTR(adc108s102_acpi_ids),
},
.probe = adc108s102_probe,
.remove = adc108s102_remove,
.id_table = adc108s102_id,
};
module_spi_driver(adc108s102_driver);
MODULE_AUTHOR("Bogdan Pricop <bogdan.pricop@emutex.com>");
MODULE_DESCRIPTION("Texas Instruments ADC108S102 and ADC128S102 driver");
MODULE_LICENSE("GPL v2");
...@@ -69,6 +69,12 @@ static struct { ...@@ -69,6 +69,12 @@ static struct {
{HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND, {HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND,
1000000, 0}, 1000000, 0},
{HID_USAGE_SENSOR_DEVICE_ORIENTATION, 0, 1, 0},
{HID_USAGE_SENSOR_RELATIVE_ORIENTATION, 0, 1, 0},
{HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION, 0, 1, 0},
{HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0}, {HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0},
{HID_USAGE_SENSOR_TEMPERATURE, HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0}, {HID_USAGE_SENSOR_TEMPERATURE, HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0},
...@@ -230,7 +236,7 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, ...@@ -230,7 +236,7 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id, ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id,
st->poll.index, sizeof(value), &value); st->poll.index, sizeof(value), &value);
if (ret < 0 || value < 0) if (ret < 0 || value < 0)
ret = -EINVAL; return -EINVAL;
ret = sensor_hub_get_feature(st->hsdev, ret = sensor_hub_get_feature(st->hsdev,
st->poll.report_id, st->poll.report_id,
...@@ -283,7 +289,7 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st, ...@@ -283,7 +289,7 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
st->sensitivity.index, sizeof(value), st->sensitivity.index, sizeof(value),
&value); &value);
if (ret < 0 || value < 0) if (ret < 0 || value < 0)
ret = -EINVAL; return -EINVAL;
ret = sensor_hub_get_feature(st->hsdev, ret = sensor_hub_get_feature(st->hsdev,
st->sensitivity.report_id, st->sensitivity.report_id,
...@@ -404,6 +410,48 @@ int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev, ...@@ -404,6 +410,48 @@ int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev,
} }
static void hid_sensor_get_report_latency_info(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_common *st)
{
sensor_hub_input_get_attribute_info(hsdev, HID_FEATURE_REPORT,
usage_id,
HID_USAGE_SENSOR_PROP_REPORT_LATENCY,
&st->report_latency);
hid_dbg(hsdev->hdev, "Report latency attributes: %x:%x\n",
st->report_latency.index, st->report_latency.report_id);
}
int hid_sensor_get_report_latency(struct hid_sensor_common *st)
{
int ret;
int value;
ret = sensor_hub_get_feature(st->hsdev, st->report_latency.report_id,
st->report_latency.index, sizeof(value),
&value);
if (ret < 0)
return ret;
return value;
}
EXPORT_SYMBOL(hid_sensor_get_report_latency);
int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency_ms)
{
return sensor_hub_set_feature(st->hsdev, st->report_latency.report_id,
st->report_latency.index,
sizeof(latency_ms), &latency_ms);
}
EXPORT_SYMBOL(hid_sensor_set_report_latency);
bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st)
{
return st->report_latency.index > 0 && st->report_latency.report_id > 0;
}
EXPORT_SYMBOL(hid_sensor_batch_mode_supported);
int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
u32 usage_id, u32 usage_id,
struct hid_sensor_common *st) struct hid_sensor_common *st)
...@@ -445,6 +493,8 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, ...@@ -445,6 +493,8 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
} else } else
st->timestamp_ns_scale = 1000000000; st->timestamp_ns_scale = 1000000000;
hid_sensor_get_report_latency_info(hsdev, usage_id, st);
hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n", hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n",
st->poll.index, st->poll.report_id, st->poll.index, st->poll.report_id,
st->report_state.index, st->report_state.report_id, st->report_state.index, st->report_state.report_id,
......
...@@ -26,9 +26,84 @@ ...@@ -26,9 +26,84 @@
#include <linux/hid-sensor-hub.h> #include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/trigger.h> #include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include "hid-sensor-trigger.h" #include "hid-sensor-trigger.h"
static ssize_t _hid_sensor_set_report_latency(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
int integer, fract, ret;
int latency;
ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
if (ret)
return ret;
latency = integer * 1000 + fract / 1000;
ret = hid_sensor_set_report_latency(attrb, latency);
if (ret < 0)
return len;
attrb->latency_ms = hid_sensor_get_report_latency(attrb);
return len;
}
static ssize_t _hid_sensor_get_report_latency(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
int latency;
latency = hid_sensor_get_report_latency(attrb);
if (latency < 0)
return latency;
return sprintf(buf, "%d.%06u\n", latency / 1000, (latency % 1000) * 1000);
}
static ssize_t _hid_sensor_get_fifo_state(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
int latency;
latency = hid_sensor_get_report_latency(attrb);
if (latency < 0)
return latency;
return sprintf(buf, "%d\n", !!latency);
}
static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
_hid_sensor_get_report_latency,
_hid_sensor_set_report_latency, 0);
static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
_hid_sensor_get_fifo_state, NULL, 0);
static const struct attribute *hid_sensor_fifo_attributes[] = {
&iio_dev_attr_hwfifo_timeout.dev_attr.attr,
&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
NULL,
};
static void hid_sensor_setup_batch_mode(struct iio_dev *indio_dev,
struct hid_sensor_common *st)
{
if (!hid_sensor_batch_mode_supported(st))
return;
iio_buffer_set_attrs(indio_dev->buffer, hid_sensor_fifo_attributes);
}
static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
{ {
int state_val; int state_val;
...@@ -141,6 +216,9 @@ static void hid_sensor_set_power_work(struct work_struct *work) ...@@ -141,6 +216,9 @@ static void hid_sensor_set_power_work(struct work_struct *work)
sizeof(attrb->raw_hystersis), sizeof(attrb->raw_hystersis),
&attrb->raw_hystersis); &attrb->raw_hystersis);
if (attrb->latency_ms > 0)
hid_sensor_set_report_latency(attrb, attrb->latency_ms);
_hid_sensor_power_state(attrb, true); _hid_sensor_power_state(attrb, true);
} }
...@@ -192,6 +270,8 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name, ...@@ -192,6 +270,8 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
attrb->trigger = trig; attrb->trigger = trig;
indio_dev->trig = iio_trigger_get(trig); indio_dev->trig = iio_trigger_get(trig);
hid_sensor_setup_batch_mode(indio_dev, attrb);
ret = pm_runtime_set_active(&indio_dev->dev); ret = pm_runtime_set_active(&indio_dev->dev);
if (ret) if (ret)
goto error_unreg_trigger; goto error_unreg_trigger;
......
...@@ -13,7 +13,8 @@ config AD5064 ...@@ -13,7 +13,8 @@ config AD5064
AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, AD5627, AD5627R, AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, AD5627, AD5627R,
AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, AD5666, AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, AD5666,
AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616,
LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to Analog Converter. LTC2617, LTC2619, LTC2626, LTC2627, LTC2629, LTC2631, LTC2633, LTC2635
Digital to Analog Converter.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ad5064. module will be called ad5064.
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
* AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R,
* AD5627, AD5627R, AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, * AD5627, AD5627R, AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R,
* AD5666, AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, * AD5666, AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616,
* LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to analog converters * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629, LTC2631, LTC2633, LTC2635
* driver * Digital to analog converters driver
* *
* Copyright 2011 Analog Devices Inc. * Copyright 2011 Analog Devices Inc.
* *
...@@ -168,6 +168,24 @@ enum ad5064_type { ...@@ -168,6 +168,24 @@ enum ad5064_type {
ID_LTC2626, ID_LTC2626,
ID_LTC2627, ID_LTC2627,
ID_LTC2629, ID_LTC2629,
ID_LTC2631_L12,
ID_LTC2631_H12,
ID_LTC2631_L10,
ID_LTC2631_H10,
ID_LTC2631_L8,
ID_LTC2631_H8,
ID_LTC2633_L12,
ID_LTC2633_H12,
ID_LTC2633_L10,
ID_LTC2633_H10,
ID_LTC2633_L8,
ID_LTC2633_H8,
ID_LTC2635_L12,
ID_LTC2635_H12,
ID_LTC2635_L10,
ID_LTC2635_H10,
ID_LTC2635_L8,
ID_LTC2635_H8,
}; };
static int ad5064_write(struct ad5064_state *st, unsigned int cmd, static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
...@@ -425,6 +443,19 @@ static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info); ...@@ -425,6 +443,19 @@ static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info); static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2617_channels, 14, 2, ltc2617_ext_info); static DECLARE_AD5064_CHANNELS(ltc2617_channels, 14, 2, ltc2617_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2627_channels, 12, 4, ltc2617_ext_info); static DECLARE_AD5064_CHANNELS(ltc2627_channels, 12, 4, ltc2617_ext_info);
#define ltc2631_12_channels ltc2627_channels
static DECLARE_AD5064_CHANNELS(ltc2631_10_channels, 10, 6, ltc2617_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2631_8_channels, 8, 8, ltc2617_ext_info);
#define LTC2631_INFO(vref, pchannels, nchannels) \
{ \
.shared_vref = true, \
.internal_vref = vref, \
.channels = pchannels, \
.num_channels = nchannels, \
.regmap_type = AD5064_REGMAP_LTC, \
}
static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
[ID_AD5024] = { [ID_AD5024] = {
...@@ -724,6 +755,24 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { ...@@ -724,6 +755,24 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
.num_channels = 4, .num_channels = 4,
.regmap_type = AD5064_REGMAP_LTC, .regmap_type = AD5064_REGMAP_LTC,
}, },
[ID_LTC2631_L12] = LTC2631_INFO(2500000, ltc2631_12_channels, 1),
[ID_LTC2631_H12] = LTC2631_INFO(4096000, ltc2631_12_channels, 1),
[ID_LTC2631_L10] = LTC2631_INFO(2500000, ltc2631_10_channels, 1),
[ID_LTC2631_H10] = LTC2631_INFO(4096000, ltc2631_10_channels, 1),
[ID_LTC2631_L8] = LTC2631_INFO(2500000, ltc2631_8_channels, 1),
[ID_LTC2631_H8] = LTC2631_INFO(4096000, ltc2631_8_channels, 1),
[ID_LTC2633_L12] = LTC2631_INFO(2500000, ltc2631_12_channels, 2),
[ID_LTC2633_H12] = LTC2631_INFO(4096000, ltc2631_12_channels, 2),
[ID_LTC2633_L10] = LTC2631_INFO(2500000, ltc2631_10_channels, 2),
[ID_LTC2633_H10] = LTC2631_INFO(4096000, ltc2631_10_channels, 2),
[ID_LTC2633_L8] = LTC2631_INFO(2500000, ltc2631_8_channels, 2),
[ID_LTC2633_H8] = LTC2631_INFO(4096000, ltc2631_8_channels, 2),
[ID_LTC2635_L12] = LTC2631_INFO(2500000, ltc2631_12_channels, 4),
[ID_LTC2635_H12] = LTC2631_INFO(4096000, ltc2631_12_channels, 4),
[ID_LTC2635_L10] = LTC2631_INFO(2500000, ltc2631_10_channels, 4),
[ID_LTC2635_H10] = LTC2631_INFO(4096000, ltc2631_10_channels, 4),
[ID_LTC2635_L8] = LTC2631_INFO(2500000, ltc2631_8_channels, 4),
[ID_LTC2635_H8] = LTC2631_INFO(4096000, ltc2631_8_channels, 4),
}; };
static inline unsigned int ad5064_num_vref(struct ad5064_state *st) static inline unsigned int ad5064_num_vref(struct ad5064_state *st)
...@@ -982,6 +1031,24 @@ static const struct i2c_device_id ad5064_i2c_ids[] = { ...@@ -982,6 +1031,24 @@ static const struct i2c_device_id ad5064_i2c_ids[] = {
{"ltc2626", ID_LTC2626}, {"ltc2626", ID_LTC2626},
{"ltc2627", ID_LTC2627}, {"ltc2627", ID_LTC2627},
{"ltc2629", ID_LTC2629}, {"ltc2629", ID_LTC2629},
{"ltc2631-l12", ID_LTC2631_L12},
{"ltc2631-h12", ID_LTC2631_H12},
{"ltc2631-l10", ID_LTC2631_L10},
{"ltc2631-h10", ID_LTC2631_H10},
{"ltc2631-l8", ID_LTC2631_L8},
{"ltc2631-h8", ID_LTC2631_H8},
{"ltc2633-l12", ID_LTC2633_L12},
{"ltc2633-h12", ID_LTC2633_H12},
{"ltc2633-l10", ID_LTC2633_L10},
{"ltc2633-h10", ID_LTC2633_H10},
{"ltc2633-l8", ID_LTC2633_L8},
{"ltc2633-h8", ID_LTC2633_H8},
{"ltc2635-l12", ID_LTC2635_L12},
{"ltc2635-h12", ID_LTC2635_H12},
{"ltc2635-l10", ID_LTC2635_L10},
{"ltc2635-h10", ID_LTC2635_H10},
{"ltc2635-l8", ID_LTC2635_L8},
{"ltc2635-h8", ID_LTC2635_H8},
{} {}
}; };
MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids); MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);
......
...@@ -57,12 +57,15 @@ struct hts221_hw { ...@@ -57,12 +57,15 @@ struct hts221_hw {
struct hts221_sensor sensors[HTS221_SENSOR_MAX]; struct hts221_sensor sensors[HTS221_SENSOR_MAX];
bool enabled;
u8 odr; u8 odr;
const struct hts221_transfer_function *tf; const struct hts221_transfer_function *tf;
struct hts221_transfer_buffer tb; struct hts221_transfer_buffer tb;
}; };
extern const struct dev_pm_ops hts221_pm_ops;
int hts221_config_drdy(struct hts221_hw *hw, bool enable); int hts221_config_drdy(struct hts221_hw *hw, bool enable);
int hts221_probe(struct iio_dev *iio_dev); int hts221_probe(struct iio_dev *iio_dev);
int hts221_power_on(struct hts221_hw *hw); int hts221_power_on(struct hts221_hw *hw);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pm.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "hts221.h" #include "hts221.h"
...@@ -307,15 +308,30 @@ hts221_sysfs_temp_oversampling_avail(struct device *dev, ...@@ -307,15 +308,30 @@ hts221_sysfs_temp_oversampling_avail(struct device *dev,
int hts221_power_on(struct hts221_hw *hw) int hts221_power_on(struct hts221_hw *hw)
{ {
return hts221_update_odr(hw, hw->odr); int err;
err = hts221_update_odr(hw, hw->odr);
if (err < 0)
return err;
hw->enabled = true;
return 0;
} }
int hts221_power_off(struct hts221_hw *hw) int hts221_power_off(struct hts221_hw *hw)
{ {
u8 data[] = {0x00, 0x00}; __le16 data = 0;
int err;
return hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data), err = hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
data); (u8 *)&data);
if (err < 0)
return err;
hw->enabled = false;
return 0;
} }
static int hts221_parse_temp_caldata(struct hts221_hw *hw) static int hts221_parse_temp_caldata(struct hts221_hw *hw)
...@@ -682,6 +698,36 @@ int hts221_probe(struct iio_dev *iio_dev) ...@@ -682,6 +698,36 @@ int hts221_probe(struct iio_dev *iio_dev)
} }
EXPORT_SYMBOL(hts221_probe); EXPORT_SYMBOL(hts221_probe);
static int __maybe_unused hts221_suspend(struct device *dev)
{
struct iio_dev *iio_dev = dev_get_drvdata(dev);
struct hts221_hw *hw = iio_priv(iio_dev);
__le16 data = 0;
int err;
err = hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
(u8 *)&data);
return err < 0 ? err : 0;
}
static int __maybe_unused hts221_resume(struct device *dev)
{
struct iio_dev *iio_dev = dev_get_drvdata(dev);
struct hts221_hw *hw = iio_priv(iio_dev);
int err = 0;
if (hw->enabled)
err = hts221_update_odr(hw, hw->odr);
return err;
}
const struct dev_pm_ops hts221_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(hts221_suspend, hts221_resume)
};
EXPORT_SYMBOL(hts221_pm_ops);
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver"); MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -105,6 +105,7 @@ MODULE_DEVICE_TABLE(i2c, hts221_i2c_id_table); ...@@ -105,6 +105,7 @@ MODULE_DEVICE_TABLE(i2c, hts221_i2c_id_table);
static struct i2c_driver hts221_driver = { static struct i2c_driver hts221_driver = {
.driver = { .driver = {
.name = "hts221_i2c", .name = "hts221_i2c",
.pm = &hts221_pm_ops,
.of_match_table = of_match_ptr(hts221_i2c_of_match), .of_match_table = of_match_ptr(hts221_i2c_of_match),
.acpi_match_table = ACPI_PTR(hts221_acpi_match), .acpi_match_table = ACPI_PTR(hts221_acpi_match),
}, },
......
...@@ -113,6 +113,7 @@ MODULE_DEVICE_TABLE(spi, hts221_spi_id_table); ...@@ -113,6 +113,7 @@ MODULE_DEVICE_TABLE(spi, hts221_spi_id_table);
static struct spi_driver hts221_driver = { static struct spi_driver hts221_driver = {
.driver = { .driver = {
.name = "hts221_spi", .name = "hts221_spi",
.pm = &hts221_pm_ops,
.of_match_table = of_match_ptr(hts221_spi_of_match), .of_match_table = of_match_ptr(hts221_spi_of_match),
}, },
.probe = hts221_spi_probe, .probe = hts221_spi_probe,
......
...@@ -135,6 +135,8 @@ struct st_lsm6dsx_hw { ...@@ -135,6 +135,8 @@ struct st_lsm6dsx_hw {
#endif /* CONFIG_SPI_MASTER */ #endif /* CONFIG_SPI_MASTER */
}; };
extern const struct dev_pm_ops st_lsm6dsx_pm_ops;
int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
const struct st_lsm6dsx_transfer_function *tf_ops); const struct st_lsm6dsx_transfer_function *tf_ops);
int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor); int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor);
...@@ -144,5 +146,8 @@ int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask, ...@@ -144,5 +146,8 @@ int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask,
u8 val); u8 val);
int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
u16 watermark); u16 watermark);
int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
enum st_lsm6dsx_fifo_mode fifo_mode);
#endif /* ST_LSM6DSX_H */ #endif /* ST_LSM6DSX_H */
...@@ -130,7 +130,7 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) ...@@ -130,7 +130,7 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
return 0; return 0;
} }
static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
enum st_lsm6dsx_fifo_mode fifo_mode) enum st_lsm6dsx_fifo_mode fifo_mode)
{ {
u8 data; u8 data;
...@@ -303,7 +303,7 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) ...@@ -303,7 +303,7 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
return read_len; return read_len;
} }
static int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
{ {
int err; int err;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/pm.h>
#include <linux/platform_data/st_sensors_pdata.h> #include <linux/platform_data/st_sensors_pdata.h>
...@@ -731,6 +732,57 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, ...@@ -731,6 +732,57 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
} }
EXPORT_SYMBOL(st_lsm6dsx_probe); EXPORT_SYMBOL(st_lsm6dsx_probe);
static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
{
struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
struct st_lsm6dsx_sensor *sensor;
int i, err = 0;
for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
sensor = iio_priv(hw->iio_devs[i]);
if (!(hw->enable_mask & BIT(sensor->id)))
continue;
err = st_lsm6dsx_write_with_mask(hw,
st_lsm6dsx_odr_table[sensor->id].reg.addr,
st_lsm6dsx_odr_table[sensor->id].reg.mask, 0);
if (err < 0)
return err;
}
if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
err = st_lsm6dsx_flush_fifo(hw);
return err;
}
static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
{
struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
struct st_lsm6dsx_sensor *sensor;
int i, err = 0;
for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
sensor = iio_priv(hw->iio_devs[i]);
if (!(hw->enable_mask & BIT(sensor->id)))
continue;
err = st_lsm6dsx_set_odr(sensor, sensor->odr);
if (err < 0)
return err;
}
if (hw->enable_mask)
err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
return err;
}
const struct dev_pm_ops st_lsm6dsx_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
};
EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
......
...@@ -98,6 +98,7 @@ MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); ...@@ -98,6 +98,7 @@ MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
static struct i2c_driver st_lsm6dsx_driver = { static struct i2c_driver st_lsm6dsx_driver = {
.driver = { .driver = {
.name = "st_lsm6dsx_i2c", .name = "st_lsm6dsx_i2c",
.pm = &st_lsm6dsx_pm_ops,
.of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match), .of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match),
}, },
.probe = st_lsm6dsx_i2c_probe, .probe = st_lsm6dsx_i2c_probe,
......
...@@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); ...@@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
static struct spi_driver st_lsm6dsx_driver = { static struct spi_driver st_lsm6dsx_driver = {
.driver = { .driver = {
.name = "st_lsm6dsx_spi", .name = "st_lsm6dsx_spi",
.pm = &st_lsm6dsx_pm_ops,
.of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match), .of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match),
}, },
.probe = st_lsm6dsx_spi_probe, .probe = st_lsm6dsx_spi_probe,
......
...@@ -1089,7 +1089,7 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev, ...@@ -1089,7 +1089,7 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
{ {
int i, ret, attrcount = 0; int i, ret, attrcount = 0;
for_each_set_bit(i, infomask, sizeof(infomask)*8) { for_each_set_bit(i, infomask, sizeof(*infomask)*8) {
if (i >= ARRAY_SIZE(iio_chan_info_postfix)) if (i >= ARRAY_SIZE(iio_chan_info_postfix))
return -EINVAL; return -EINVAL;
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i], ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
...@@ -1118,7 +1118,7 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev, ...@@ -1118,7 +1118,7 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev,
int i, ret, attrcount = 0; int i, ret, attrcount = 0;
char *avail_postfix; char *avail_postfix;
for_each_set_bit(i, infomask, sizeof(infomask) * 8) { for_each_set_bit(i, infomask, sizeof(*infomask) * 8) {
avail_postfix = kasprintf(GFP_KERNEL, avail_postfix = kasprintf(GFP_KERNEL,
"%s_available", "%s_available",
iio_chan_info_postfix[i]); iio_chan_info_postfix[i]);
......
...@@ -750,11 +750,9 @@ int iio_read_avail_channel_raw(struct iio_channel *chan, ...@@ -750,11 +750,9 @@ int iio_read_avail_channel_raw(struct iio_channel *chan,
err_unlock: err_unlock:
mutex_unlock(&chan->indio_dev->info_exist_lock); mutex_unlock(&chan->indio_dev->info_exist_lock);
if (ret >= 0 && type != IIO_VAL_INT) { if (ret >= 0 && type != IIO_VAL_INT)
/* raw values are assumed to be IIO_VAL_INT */ /* raw values are assumed to be IIO_VAL_INT */
ret = -EINVAL; ret = -EINVAL;
goto err_unlock;
}
return ret; return ret;
} }
......
...@@ -172,6 +172,16 @@ config SENSORS_ISL29018 ...@@ -172,6 +172,16 @@ config SENSORS_ISL29018
in lux, proximity infrared sensing and normal infrared sensing. in lux, proximity infrared sensing and normal infrared sensing.
Data from sensor is accessible via sysfs. Data from sensor is accessible via sysfs.
config SENSORS_ISL29028
tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor"
depends on I2C
select REGMAP_I2C
help
Provides driver for the Intersil's ISL29028 device.
This driver supports the sysfs interface to get the ALS, IR intensity,
Proximity value via iio. The ISL29028 provides the concurrent sensing
of ambient light and proximity.
config ISL29125 config ISL29125
tristate "Intersil ISL29125 digital color light sensor" tristate "Intersil ISL29125 digital color light sensor"
depends on I2C depends on I2C
......
...@@ -20,6 +20,7 @@ obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o ...@@ -20,6 +20,7 @@ obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o
obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o
obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
obj-$(CONFIG_ISL29125) += isl29125.o obj-$(CONFIG_ISL29125) += isl29125.o
obj-$(CONFIG_JSA1212) += jsa1212.o obj-$(CONFIG_JSA1212) += jsa1212.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
......
...@@ -807,6 +807,7 @@ static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume); ...@@ -807,6 +807,7 @@ static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume);
#define ISL29018_PM_OPS NULL #define ISL29018_PM_OPS NULL
#endif #endif
#ifdef CONFIG_ACPI
static const struct acpi_device_id isl29018_acpi_match[] = { static const struct acpi_device_id isl29018_acpi_match[] = {
{"ISL29018", isl29018}, {"ISL29018", isl29018},
{"ISL29023", isl29023}, {"ISL29023", isl29023},
...@@ -814,6 +815,7 @@ static const struct acpi_device_id isl29018_acpi_match[] = { ...@@ -814,6 +815,7 @@ static const struct acpi_device_id isl29018_acpi_match[] = {
{}, {},
}; };
MODULE_DEVICE_TABLE(acpi, isl29018_acpi_match); MODULE_DEVICE_TABLE(acpi, isl29018_acpi_match);
#endif
static const struct i2c_device_id isl29018_id[] = { static const struct i2c_device_id isl29018_id[] = {
{"isl29018", isl29018}, {"isl29018", isl29018},
......
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Datasheets:
* - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf
* - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -64,8 +68,25 @@ ...@@ -64,8 +68,25 @@
#define ISL29028_POWER_OFF_DELAY_MS 2000 #define ISL29028_POWER_OFF_DELAY_MS 2000
static const unsigned int isl29028_prox_sleep_time[] = {800, 400, 200, 100, 75, struct isl29028_prox_data {
50, 12, 0}; int sampling_int;
int sampling_fract;
int sleep_time;
};
static const struct isl29028_prox_data isl29028_prox_data[] = {
{ 1, 250000, 800 },
{ 2, 500000, 400 },
{ 5, 0, 200 },
{ 10, 0, 100 },
{ 13, 300000, 75 },
{ 20, 0, 50 },
{ 80, 0, 13 }, /*
* Note: Data sheet lists 12.5 ms sleep time.
* Round up a half millisecond for msleep().
*/
{ 100, 0, 0 }
};
enum isl29028_als_ir_mode { enum isl29028_als_ir_mode {
ISL29028_MODE_NONE = 0, ISL29028_MODE_NONE = 0,
...@@ -76,32 +97,37 @@ enum isl29028_als_ir_mode { ...@@ -76,32 +97,37 @@ enum isl29028_als_ir_mode {
struct isl29028_chip { struct isl29028_chip {
struct mutex lock; struct mutex lock;
struct regmap *regmap; struct regmap *regmap;
unsigned int prox_sampling; int prox_sampling_int;
int prox_sampling_frac;
bool enable_prox; bool enable_prox;
int lux_scale; int lux_scale;
enum isl29028_als_ir_mode als_ir_mode; enum isl29028_als_ir_mode als_ir_mode;
}; };
static int isl29028_find_prox_sleep_time_index(int sampling) static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract)
{ {
unsigned int period = DIV_ROUND_UP(1000, sampling);
int i; int i;
for (i = 0; i < ARRAY_SIZE(isl29028_prox_sleep_time); ++i) { for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) {
if (period >= isl29028_prox_sleep_time[i]) if (isl29028_prox_data[i].sampling_int == sampling_int &&
break; isl29028_prox_data[i].sampling_fract == sampling_fract)
return i;
} }
return i; return -EINVAL;
} }
static int isl29028_set_proxim_sampling(struct isl29028_chip *chip, static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
unsigned int sampling) int sampling_int, int sampling_fract)
{ {
struct device *dev = regmap_get_device(chip->regmap); struct device *dev = regmap_get_device(chip->regmap);
int sleep_index, ret; int sleep_index, ret;
sleep_index = isl29028_find_prox_sleep_time_index(sampling); sleep_index = isl29028_find_prox_sleep_index(sampling_int,
sampling_fract);
if (sleep_index < 0)
return sleep_index;
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
ISL29028_CONF_PROX_SLP_MASK, ISL29028_CONF_PROX_SLP_MASK,
sleep_index << ISL29028_CONF_PROX_SLP_SH); sleep_index << ISL29028_CONF_PROX_SLP_SH);
...@@ -112,16 +138,18 @@ static int isl29028_set_proxim_sampling(struct isl29028_chip *chip, ...@@ -112,16 +138,18 @@ static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
return ret; return ret;
} }
chip->prox_sampling = sampling; chip->prox_sampling_int = sampling_int;
chip->prox_sampling_frac = sampling_fract;
return ret; return ret;
} }
static int isl29028_enable_proximity(struct isl29028_chip *chip) static int isl29028_enable_proximity(struct isl29028_chip *chip)
{ {
int sleep_index, ret; int prox_index, ret;
ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int,
chip->prox_sampling_frac);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -132,8 +160,12 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip) ...@@ -132,8 +160,12 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip)
return ret; return ret;
/* Wait for conversion to be complete for first sample */ /* Wait for conversion to be complete for first sample */
sleep_index = isl29028_find_prox_sleep_time_index(chip->prox_sampling); prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int,
msleep(isl29028_prox_sleep_time[sleep_index]); chip->prox_sampling_frac);
if (prox_index < 0)
return prox_index;
msleep(isl29028_prox_data[prox_index].sleep_time);
return 0; return 0;
} }
...@@ -361,7 +393,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, ...@@ -361,7 +393,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
break; break;
} }
ret = isl29028_set_proxim_sampling(chip, val); ret = isl29028_set_proxim_sampling(chip, val, val2);
break; break;
case IIO_LIGHT: case IIO_LIGHT:
if (mask != IIO_CHAN_INFO_SCALE) { if (mask != IIO_CHAN_INFO_SCALE) {
...@@ -439,7 +471,8 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, ...@@ -439,7 +471,8 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
if (chan->type != IIO_PROXIMITY) if (chan->type != IIO_PROXIMITY)
break; break;
*val = chip->prox_sampling; *val = chip->prox_sampling_int;
*val2 = chip->prox_sampling_frac;
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
break; break;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
...@@ -472,7 +505,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, ...@@ -472,7 +505,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
} }
static IIO_CONST_ATTR(in_proximity_sampling_frequency_available, static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
"1 3 5 10 13 20 83 100"); "1.25 2.5 5 10 13.3 20 80 100");
static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000"); static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) #define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
...@@ -571,7 +604,8 @@ static int isl29028_probe(struct i2c_client *client, ...@@ -571,7 +604,8 @@ static int isl29028_probe(struct i2c_client *client,
} }
chip->enable_prox = false; chip->enable_prox = false;
chip->prox_sampling = 20; chip->prox_sampling_int = 20;
chip->prox_sampling_frac = 0;
chip->lux_scale = 2000; chip->lux_scale = 2000;
ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
...@@ -664,6 +698,7 @@ static const struct dev_pm_ops isl29028_pm_ops = { ...@@ -664,6 +698,7 @@ static const struct dev_pm_ops isl29028_pm_ops = {
static const struct i2c_device_id isl29028_id[] = { static const struct i2c_device_id isl29028_id[] = {
{"isl29028", 0}, {"isl29028", 0},
{"isl29030", 0},
{} {}
}; };
MODULE_DEVICE_TABLE(i2c, isl29028_id); MODULE_DEVICE_TABLE(i2c, isl29028_id);
...@@ -671,6 +706,7 @@ MODULE_DEVICE_TABLE(i2c, isl29028_id); ...@@ -671,6 +706,7 @@ MODULE_DEVICE_TABLE(i2c, isl29028_id);
static const struct of_device_id isl29028_of_match[] = { static const struct of_device_id isl29028_of_match[] = {
{ .compatible = "isl,isl29028", }, /* for backward compat., don't use */ { .compatible = "isl,isl29028", }, /* for backward compat., don't use */
{ .compatible = "isil,isl29028", }, { .compatible = "isil,isl29028", },
{ .compatible = "isil,isl29030", },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, isl29028_of_match); MODULE_DEVICE_TABLE(of, isl29028_of_match);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* IIO driver for RPR-0521RS (7-bit I2C slave address 0x38). * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
* *
* TODO: illuminance channel, PM support, buffer * TODO: illuminance channel, buffer
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define RPR0521_REG_PXS_DATA 0x44 /* 16-bit, little endian */ #define RPR0521_REG_PXS_DATA 0x44 /* 16-bit, little endian */
#define RPR0521_REG_ALS_DATA0 0x46 /* 16-bit, little endian */ #define RPR0521_REG_ALS_DATA0 0x46 /* 16-bit, little endian */
#define RPR0521_REG_ALS_DATA1 0x48 /* 16-bit, little endian */ #define RPR0521_REG_ALS_DATA1 0x48 /* 16-bit, little endian */
#define RPR0521_REG_PS_OFFSET_LSB 0x53
#define RPR0521_REG_ID 0x92 #define RPR0521_REG_ID 0x92
#define RPR0521_MODE_ALS_MASK BIT(7) #define RPR0521_MODE_ALS_MASK BIT(7)
...@@ -77,9 +78,9 @@ static const struct rpr0521_gain rpr0521_pxs_gain[3] = { ...@@ -77,9 +78,9 @@ static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
}; };
enum rpr0521_channel { enum rpr0521_channel {
RPR0521_CHAN_PXS,
RPR0521_CHAN_ALS_DATA0, RPR0521_CHAN_ALS_DATA0,
RPR0521_CHAN_ALS_DATA1, RPR0521_CHAN_ALS_DATA1,
RPR0521_CHAN_PXS,
}; };
struct rpr0521_reg_desc { struct rpr0521_reg_desc {
...@@ -88,6 +89,10 @@ struct rpr0521_reg_desc { ...@@ -88,6 +89,10 @@ struct rpr0521_reg_desc {
}; };
static const struct rpr0521_reg_desc rpr0521_data_reg[] = { static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
[RPR0521_CHAN_PXS] = {
.address = RPR0521_REG_PXS_DATA,
.device_mask = RPR0521_MODE_PXS_MASK,
},
[RPR0521_CHAN_ALS_DATA0] = { [RPR0521_CHAN_ALS_DATA0] = {
.address = RPR0521_REG_ALS_DATA0, .address = RPR0521_REG_ALS_DATA0,
.device_mask = RPR0521_MODE_ALS_MASK, .device_mask = RPR0521_MODE_ALS_MASK,
...@@ -96,10 +101,6 @@ static const struct rpr0521_reg_desc rpr0521_data_reg[] = { ...@@ -96,10 +101,6 @@ static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
.address = RPR0521_REG_ALS_DATA1, .address = RPR0521_REG_ALS_DATA1,
.device_mask = RPR0521_MODE_ALS_MASK, .device_mask = RPR0521_MODE_ALS_MASK,
}, },
[RPR0521_CHAN_PXS] = {
.address = RPR0521_REG_PXS_DATA,
.device_mask = RPR0521_MODE_PXS_MASK,
},
}; };
static const struct rpr0521_gain_info { static const struct rpr0521_gain_info {
...@@ -109,6 +110,13 @@ static const struct rpr0521_gain_info { ...@@ -109,6 +110,13 @@ static const struct rpr0521_gain_info {
const struct rpr0521_gain *gain; const struct rpr0521_gain *gain;
int size; int size;
} rpr0521_gain[] = { } rpr0521_gain[] = {
[RPR0521_CHAN_PXS] = {
.reg = RPR0521_REG_PXS_CTRL,
.mask = RPR0521_PXS_GAIN_MASK,
.shift = RPR0521_PXS_GAIN_SHIFT,
.gain = rpr0521_pxs_gain,
.size = ARRAY_SIZE(rpr0521_pxs_gain),
},
[RPR0521_CHAN_ALS_DATA0] = { [RPR0521_CHAN_ALS_DATA0] = {
.reg = RPR0521_REG_ALS_CTRL, .reg = RPR0521_REG_ALS_CTRL,
.mask = RPR0521_ALS_DATA0_GAIN_MASK, .mask = RPR0521_ALS_DATA0_GAIN_MASK,
...@@ -123,13 +131,30 @@ static const struct rpr0521_gain_info { ...@@ -123,13 +131,30 @@ static const struct rpr0521_gain_info {
.gain = rpr0521_als_gain, .gain = rpr0521_als_gain,
.size = ARRAY_SIZE(rpr0521_als_gain), .size = ARRAY_SIZE(rpr0521_als_gain),
}, },
[RPR0521_CHAN_PXS] = { };
.reg = RPR0521_REG_PXS_CTRL,
.mask = RPR0521_PXS_GAIN_MASK, struct rpr0521_samp_freq {
.shift = RPR0521_PXS_GAIN_SHIFT, int als_hz;
.gain = rpr0521_pxs_gain, int als_uhz;
.size = ARRAY_SIZE(rpr0521_pxs_gain), int pxs_hz;
}, int pxs_uhz;
};
static const struct rpr0521_samp_freq rpr0521_samp_freq_i[13] = {
/* {ALS, PXS}, W==currently writable option */
{0, 0, 0, 0}, /* W0000, 0=standby */
{0, 0, 100, 0}, /* 0001 */
{0, 0, 25, 0}, /* 0010 */
{0, 0, 10, 0}, /* 0011 */
{0, 0, 2, 500000}, /* 0100 */
{10, 0, 20, 0}, /* 0101 */
{10, 0, 10, 0}, /* W0110 */
{10, 0, 2, 500000}, /* 0111 */
{2, 500000, 20, 0}, /* 1000, measurement 100ms, sleep 300ms */
{2, 500000, 10, 0}, /* 1001, measurement 100ms, sleep 300ms */
{2, 500000, 0, 0}, /* 1010, high sensitivity mode */
{2, 500000, 2, 500000}, /* W1011, high sensitivity mode */
{20, 0, 20, 0} /* 1100, ALS_data x 0.5, see specification P.18 */
}; };
struct rpr0521_data { struct rpr0521_data {
...@@ -142,9 +167,11 @@ struct rpr0521_data { ...@@ -142,9 +167,11 @@ struct rpr0521_data {
bool als_dev_en; bool als_dev_en;
bool pxs_dev_en; bool pxs_dev_en;
/* optimize runtime pm ops - enable device only if needed */ /* optimize runtime pm ops - enable/disable device only if needed */
bool als_ps_need_en; bool als_ps_need_en;
bool pxs_ps_need_en; bool pxs_ps_need_en;
bool als_need_dis;
bool pxs_need_dis;
struct regmap *regmap; struct regmap *regmap;
}; };
...@@ -152,9 +179,16 @@ struct rpr0521_data { ...@@ -152,9 +179,16 @@ struct rpr0521_data {
static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL); static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL); static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
/*
* Start with easy freq first, whole table of freq combinations is more
* complicated.
*/
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("2.5 10");
static struct attribute *rpr0521_attributes[] = { static struct attribute *rpr0521_attributes[] = {
&iio_const_attr_in_intensity_scale_available.dev_attr.attr, &iio_const_attr_in_intensity_scale_available.dev_attr.attr,
&iio_const_attr_in_proximity_scale_available.dev_attr.attr, &iio_const_attr_in_proximity_scale_available.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL, NULL,
}; };
...@@ -163,6 +197,14 @@ static const struct attribute_group rpr0521_attribute_group = { ...@@ -163,6 +197,14 @@ static const struct attribute_group rpr0521_attribute_group = {
}; };
static const struct iio_chan_spec rpr0521_channels[] = { static const struct iio_chan_spec rpr0521_channels[] = {
{
.type = IIO_PROXIMITY,
.address = RPR0521_CHAN_PXS,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{ {
.type = IIO_INTENSITY, .type = IIO_INTENSITY,
.modified = 1, .modified = 1,
...@@ -170,6 +212,7 @@ static const struct iio_chan_spec rpr0521_channels[] = { ...@@ -170,6 +212,7 @@ static const struct iio_chan_spec rpr0521_channels[] = {
.channel2 = IIO_MOD_LIGHT_BOTH, .channel2 = IIO_MOD_LIGHT_BOTH,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE), BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
}, },
{ {
.type = IIO_INTENSITY, .type = IIO_INTENSITY,
...@@ -178,13 +221,8 @@ static const struct iio_chan_spec rpr0521_channels[] = { ...@@ -178,13 +221,8 @@ static const struct iio_chan_spec rpr0521_channels[] = {
.channel2 = IIO_MOD_LIGHT_IR, .channel2 = IIO_MOD_LIGHT_IR,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE), BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
}, },
{
.type = IIO_PROXIMITY,
.address = RPR0521_CHAN_PXS,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
}
}; };
static int rpr0521_als_enable(struct rpr0521_data *data, u8 status) static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
...@@ -197,7 +235,10 @@ static int rpr0521_als_enable(struct rpr0521_data *data, u8 status) ...@@ -197,7 +235,10 @@ static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (status & RPR0521_MODE_ALS_MASK)
data->als_dev_en = true; data->als_dev_en = true;
else
data->als_dev_en = false;
return 0; return 0;
} }
...@@ -212,7 +253,10 @@ static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status) ...@@ -212,7 +253,10 @@ static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (status & RPR0521_MODE_PXS_MASK)
data->pxs_dev_en = true; data->pxs_dev_en = true;
else
data->pxs_dev_en = false;
return 0; return 0;
} }
...@@ -224,40 +268,32 @@ static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status) ...@@ -224,40 +268,32 @@ static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
* @on: state to be set for devices in @device_mask * @on: state to be set for devices in @device_mask
* @device_mask: bitmask specifying for which device we need to update @on state * @device_mask: bitmask specifying for which device we need to update @on state
* *
* We rely on rpr0521_runtime_resume to enable our @device_mask devices, but * Calls for this function must be balanced so that each ON should have matching
* if (for example) PXS was enabled (pxs_dev_en = true) by a previous call to * OFF. Otherwise pm usage_count gets out of sync.
* rpr0521_runtime_resume and we want to enable ALS we MUST set ALS enable
* bit of RPR0521_REG_MODE_CTRL here because rpr0521_runtime_resume will not
* be called twice.
*/ */
static int rpr0521_set_power_state(struct rpr0521_data *data, bool on, static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
u8 device_mask) u8 device_mask)
{ {
#ifdef CONFIG_PM #ifdef CONFIG_PM
int ret; int ret;
u8 update_mask = 0;
if (device_mask & RPR0521_MODE_ALS_MASK) { if (device_mask & RPR0521_MODE_ALS_MASK) {
if (on && !data->als_ps_need_en && data->pxs_dev_en)
update_mask |= RPR0521_MODE_ALS_MASK;
else
data->als_ps_need_en = on; data->als_ps_need_en = on;
data->als_need_dis = !on;
} }
if (device_mask & RPR0521_MODE_PXS_MASK) { if (device_mask & RPR0521_MODE_PXS_MASK) {
if (on && !data->pxs_ps_need_en && data->als_dev_en)
update_mask |= RPR0521_MODE_PXS_MASK;
else
data->pxs_ps_need_en = on; data->pxs_ps_need_en = on;
data->pxs_need_dis = !on;
} }
if (update_mask) { /*
ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL, * On: _resume() is called only when we are suspended
update_mask, update_mask); * Off: _suspend() is called after delay if _resume() is not
if (ret < 0) * called before that.
return ret; * Note: If either measurement is re-enabled before _suspend(),
} * both stay enabled until _suspend().
*/
if (on) { if (on) {
ret = pm_runtime_get_sync(&data->client->dev); ret = pm_runtime_get_sync(&data->client->dev);
} else { } else {
...@@ -273,6 +309,23 @@ static int rpr0521_set_power_state(struct rpr0521_data *data, bool on, ...@@ -273,6 +309,23 @@ static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
return ret; return ret;
} }
if (on) {
/* If _resume() was not called, enable measurement now. */
if (data->als_ps_need_en) {
ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
if (ret)
return ret;
data->als_ps_need_en = false;
}
if (data->pxs_ps_need_en) {
ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
if (ret)
return ret;
data->pxs_ps_need_en = false;
}
}
#endif #endif
return 0; return 0;
} }
...@@ -314,6 +367,106 @@ static int rpr0521_set_gain(struct rpr0521_data *data, int chan, ...@@ -314,6 +367,106 @@ static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
idx << rpr0521_gain[chan].shift); idx << rpr0521_gain[chan].shift);
} }
static int rpr0521_read_samp_freq(struct rpr0521_data *data,
enum iio_chan_type chan_type,
int *val, int *val2)
{
int reg, ret;
ret = regmap_read(data->regmap, RPR0521_REG_MODE_CTRL, &reg);
if (ret < 0)
return ret;
reg &= RPR0521_MODE_MEAS_TIME_MASK;
if (reg >= ARRAY_SIZE(rpr0521_samp_freq_i))
return -EINVAL;
switch (chan_type) {
case IIO_INTENSITY:
*val = rpr0521_samp_freq_i[reg].als_hz;
*val2 = rpr0521_samp_freq_i[reg].als_uhz;
return 0;
case IIO_PROXIMITY:
*val = rpr0521_samp_freq_i[reg].pxs_hz;
*val2 = rpr0521_samp_freq_i[reg].pxs_uhz;
return 0;
default:
return -EINVAL;
}
}
static int rpr0521_write_samp_freq_common(struct rpr0521_data *data,
enum iio_chan_type chan_type,
int val, int val2)
{
int i;
/*
* Ignore channel
* both pxs and als are setup only to same freq because of simplicity
*/
switch (val) {
case 0:
i = 0;
break;
case 2:
if (val2 != 500000)
return -EINVAL;
i = 11;
break;
case 10:
i = 6;
break;
default:
return -EINVAL;
}
return regmap_update_bits(data->regmap,
RPR0521_REG_MODE_CTRL,
RPR0521_MODE_MEAS_TIME_MASK,
i);
}
static int rpr0521_read_ps_offset(struct rpr0521_data *data, int *offset)
{
int ret;
__le16 buffer;
ret = regmap_bulk_read(data->regmap,
RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
if (ret < 0) {
dev_err(&data->client->dev, "Failed to read PS OFFSET register\n");
return ret;
}
*offset = le16_to_cpu(buffer);
return ret;
}
static int rpr0521_write_ps_offset(struct rpr0521_data *data, int offset)
{
int ret;
__le16 buffer;
buffer = cpu_to_le16(offset & 0x3ff);
ret = regmap_raw_write(data->regmap,
RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
if (ret < 0) {
dev_err(&data->client->dev, "Failed to write PS OFFSET register\n");
return ret;
}
return ret;
}
static int rpr0521_read_raw(struct iio_dev *indio_dev, static int rpr0521_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, struct iio_chan_spec const *chan, int *val,
int *val2, long mask) int *val2, long mask)
...@@ -339,7 +492,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev, ...@@ -339,7 +492,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
ret = regmap_bulk_read(data->regmap, ret = regmap_bulk_read(data->regmap,
rpr0521_data_reg[chan->address].address, rpr0521_data_reg[chan->address].address,
&raw_data, 2); &raw_data, sizeof(raw_data));
if (ret < 0) { if (ret < 0) {
rpr0521_set_power_state(data, false, device_mask); rpr0521_set_power_state(data, false, device_mask);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -354,6 +507,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev, ...@@ -354,6 +507,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
*val = le16_to_cpu(raw_data); *val = le16_to_cpu(raw_data);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
mutex_lock(&data->lock); mutex_lock(&data->lock);
ret = rpr0521_get_gain(data, chan->address, val, val2); ret = rpr0521_get_gain(data, chan->address, val, val2);
...@@ -362,6 +516,25 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev, ...@@ -362,6 +516,25 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
return ret; return ret;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ:
mutex_lock(&data->lock);
ret = rpr0521_read_samp_freq(data, chan->type, val, val2);
mutex_unlock(&data->lock);
if (ret < 0)
return ret;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OFFSET:
mutex_lock(&data->lock);
ret = rpr0521_read_ps_offset(data, val);
mutex_unlock(&data->lock);
if (ret < 0)
return ret;
return IIO_VAL_INT;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -381,6 +554,22 @@ static int rpr0521_write_raw(struct iio_dev *indio_dev, ...@@ -381,6 +554,22 @@ static int rpr0521_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return ret; return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
mutex_lock(&data->lock);
ret = rpr0521_write_samp_freq_common(data, chan->type,
val, val2);
mutex_unlock(&data->lock);
return ret;
case IIO_CHAN_INFO_OFFSET:
mutex_lock(&data->lock);
ret = rpr0521_write_ps_offset(data, val);
mutex_unlock(&data->lock);
return ret;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -419,12 +608,14 @@ static int rpr0521_init(struct rpr0521_data *data) ...@@ -419,12 +608,14 @@ static int rpr0521_init(struct rpr0521_data *data)
return ret; return ret;
} }
#ifndef CONFIG_PM
ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE); ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE); ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
if (ret < 0) if (ret < 0)
return ret; return ret;
#endif
return 0; return 0;
} }
...@@ -510,13 +701,26 @@ static int rpr0521_probe(struct i2c_client *client, ...@@ -510,13 +701,26 @@ static int rpr0521_probe(struct i2c_client *client,
ret = pm_runtime_set_active(&client->dev); ret = pm_runtime_set_active(&client->dev);
if (ret < 0) if (ret < 0)
return ret; goto err_poweroff;
pm_runtime_enable(&client->dev); pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS); pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev); pm_runtime_use_autosuspend(&client->dev);
return iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret)
goto err_pm_disable;
return 0;
err_pm_disable:
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);
err_poweroff:
rpr0521_poweroff(data);
return ret;
} }
static int rpr0521_remove(struct i2c_client *client) static int rpr0521_remove(struct i2c_client *client)
...@@ -541,9 +745,16 @@ static int rpr0521_runtime_suspend(struct device *dev) ...@@ -541,9 +745,16 @@ static int rpr0521_runtime_suspend(struct device *dev)
struct rpr0521_data *data = iio_priv(indio_dev); struct rpr0521_data *data = iio_priv(indio_dev);
int ret; int ret;
/* disable channels and sets {als,pxs}_dev_en to false */
mutex_lock(&data->lock); mutex_lock(&data->lock);
/* If measurements are enabled, enable them on resume */
if (!data->als_need_dis)
data->als_ps_need_en = data->als_dev_en;
if (!data->pxs_need_dis)
data->pxs_ps_need_en = data->pxs_dev_en;
/* disable channels and sets {als,pxs}_dev_en to false */
ret = rpr0521_poweroff(data); ret = rpr0521_poweroff(data);
regcache_mark_dirty(data->regmap);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return ret; return ret;
...@@ -555,6 +766,7 @@ static int rpr0521_runtime_resume(struct device *dev) ...@@ -555,6 +766,7 @@ static int rpr0521_runtime_resume(struct device *dev)
struct rpr0521_data *data = iio_priv(indio_dev); struct rpr0521_data *data = iio_priv(indio_dev);
int ret; int ret;
regcache_sync(data->regmap);
if (data->als_ps_need_en) { if (data->als_ps_need_en) {
ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE); ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
if (ret < 0) if (ret < 0)
...@@ -568,6 +780,7 @@ static int rpr0521_runtime_resume(struct device *dev) ...@@ -568,6 +780,7 @@ static int rpr0521_runtime_resume(struct device *dev)
return ret; return ret;
data->pxs_ps_need_en = false; data->pxs_ps_need_en = false;
} }
msleep(100); //wait for first measurement result
return 0; return 0;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* within the TAOS tsl258x family of devices (tsl2580, tsl2581, tsl2583). * within the TAOS tsl258x family of devices (tsl2580, tsl2581, tsl2583).
* *
* Copyright (c) 2011, TAOS Corporation. * Copyright (c) 2011, TAOS Corporation.
* Copyright (c) 2016 Brian Masney <masneyb@onstation.org> * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/pm_runtime.h>
/* Device Registers and Masks */ /* Device Registers and Masks */
#define TSL2583_CNTRL 0x00 #define TSL2583_CNTRL 0x00
...@@ -64,6 +65,8 @@ ...@@ -64,6 +65,8 @@
#define TSL2583_CHIP_ID 0x90 #define TSL2583_CHIP_ID 0x90
#define TSL2583_CHIP_ID_MASK 0xf0 #define TSL2583_CHIP_ID_MASK 0xf0
#define TSL2583_POWER_OFF_DELAY_MS 2000
/* Per-device data */ /* Per-device data */
struct tsl2583_als_info { struct tsl2583_als_info {
u16 als_ch0; u16 als_ch0;
...@@ -108,7 +111,6 @@ struct tsl2583_chip { ...@@ -108,7 +111,6 @@ struct tsl2583_chip {
struct tsl2583_settings als_settings; struct tsl2583_settings als_settings;
int als_time_scale; int als_time_scale;
int als_saturation; int als_saturation;
bool suspended;
}; };
struct gainadj { struct gainadj {
...@@ -460,8 +462,6 @@ static int tsl2583_chip_init_and_power_on(struct iio_dev *indio_dev) ...@@ -460,8 +462,6 @@ static int tsl2583_chip_init_and_power_on(struct iio_dev *indio_dev)
if (ret < 0) if (ret < 0)
return ret; return ret;
chip->suspended = false;
return ret; return ret;
} }
...@@ -513,11 +513,6 @@ static ssize_t in_illuminance_calibrate_store(struct device *dev, ...@@ -513,11 +513,6 @@ static ssize_t in_illuminance_calibrate_store(struct device *dev,
mutex_lock(&chip->als_mutex); mutex_lock(&chip->als_mutex);
if (chip->suspended) {
ret = -EBUSY;
goto done;
}
ret = tsl2583_als_calibrate(indio_dev); ret = tsl2583_als_calibrate(indio_dev);
if (ret < 0) if (ret < 0)
goto done; goto done;
...@@ -645,20 +640,36 @@ static const struct iio_chan_spec tsl2583_channels[] = { ...@@ -645,20 +640,36 @@ static const struct iio_chan_spec tsl2583_channels[] = {
}, },
}; };
static int tsl2583_set_pm_runtime_busy(struct tsl2583_chip *chip, bool on)
{
int ret;
if (on) {
ret = pm_runtime_get_sync(&chip->client->dev);
if (ret < 0)
pm_runtime_put_noidle(&chip->client->dev);
} else {
pm_runtime_mark_last_busy(&chip->client->dev);
ret = pm_runtime_put_autosuspend(&chip->client->dev);
}
return ret;
}
static int tsl2583_read_raw(struct iio_dev *indio_dev, static int tsl2583_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
int *val, int *val2, long mask) int *val, int *val2, long mask)
{ {
struct tsl2583_chip *chip = iio_priv(indio_dev); struct tsl2583_chip *chip = iio_priv(indio_dev);
int ret = -EINVAL; int ret, pm_ret;
mutex_lock(&chip->als_mutex); ret = tsl2583_set_pm_runtime_busy(chip, true);
if (ret < 0)
return ret;
if (chip->suspended) { mutex_lock(&chip->als_mutex);
ret = -EBUSY;
goto read_done;
}
ret = -EINVAL;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
if (chan->type == IIO_LIGHT) { if (chan->type == IIO_LIGHT) {
...@@ -719,6 +730,18 @@ static int tsl2583_read_raw(struct iio_dev *indio_dev, ...@@ -719,6 +730,18 @@ static int tsl2583_read_raw(struct iio_dev *indio_dev,
read_done: read_done:
mutex_unlock(&chip->als_mutex); mutex_unlock(&chip->als_mutex);
if (ret < 0)
return ret;
/*
* Preserve the ret variable if the call to
* tsl2583_set_pm_runtime_busy() is successful so the reading
* (if applicable) is returned to user space.
*/
pm_ret = tsl2583_set_pm_runtime_busy(chip, false);
if (pm_ret < 0)
return pm_ret;
return ret; return ret;
} }
...@@ -727,15 +750,15 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev, ...@@ -727,15 +750,15 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask) int val, int val2, long mask)
{ {
struct tsl2583_chip *chip = iio_priv(indio_dev); struct tsl2583_chip *chip = iio_priv(indio_dev);
int ret = -EINVAL; int ret;
mutex_lock(&chip->als_mutex); ret = tsl2583_set_pm_runtime_busy(chip, true);
if (ret < 0)
return ret;
if (chip->suspended) { mutex_lock(&chip->als_mutex);
ret = -EBUSY;
goto write_done;
}
ret = -EINVAL;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
if (chan->type == IIO_LIGHT) { if (chan->type == IIO_LIGHT) {
...@@ -767,9 +790,15 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev, ...@@ -767,9 +790,15 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev,
break; break;
} }
write_done:
mutex_unlock(&chip->als_mutex); mutex_unlock(&chip->als_mutex);
if (ret < 0)
return ret;
ret = tsl2583_set_pm_runtime_busy(chip, false);
if (ret < 0)
return ret;
return ret; return ret;
} }
...@@ -803,7 +832,6 @@ static int tsl2583_probe(struct i2c_client *clientp, ...@@ -803,7 +832,6 @@ static int tsl2583_probe(struct i2c_client *clientp,
i2c_set_clientdata(clientp, indio_dev); i2c_set_clientdata(clientp, indio_dev);
mutex_init(&chip->als_mutex); mutex_init(&chip->als_mutex);
chip->suspended = true;
ret = i2c_smbus_read_byte_data(clientp, ret = i2c_smbus_read_byte_data(clientp,
TSL2583_CMD_REG | TSL2583_CHIPID); TSL2583_CMD_REG | TSL2583_CHIPID);
...@@ -826,6 +854,11 @@ static int tsl2583_probe(struct i2c_client *clientp, ...@@ -826,6 +854,11 @@ static int tsl2583_probe(struct i2c_client *clientp,
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = chip->client->name; indio_dev->name = chip->client->name;
pm_runtime_enable(&clientp->dev);
pm_runtime_set_autosuspend_delay(&clientp->dev,
TSL2583_POWER_OFF_DELAY_MS);
pm_runtime_use_autosuspend(&clientp->dev);
ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
if (ret) { if (ret) {
dev_err(&clientp->dev, "%s: iio registration failed\n", dev_err(&clientp->dev, "%s: iio registration failed\n",
...@@ -836,16 +869,25 @@ static int tsl2583_probe(struct i2c_client *clientp, ...@@ -836,16 +869,25 @@ static int tsl2583_probe(struct i2c_client *clientp,
/* Load up the V2 defaults (these are hard coded defaults for now) */ /* Load up the V2 defaults (these are hard coded defaults for now) */
tsl2583_defaults(chip); tsl2583_defaults(chip);
/* Make sure the chip is on */
ret = tsl2583_chip_init_and_power_on(indio_dev);
if (ret < 0)
return ret;
dev_info(&clientp->dev, "Light sensor found.\n"); dev_info(&clientp->dev, "Light sensor found.\n");
return 0; return 0;
} }
static int tsl2583_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct tsl2583_chip *chip = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);
return tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF);
}
static int __maybe_unused tsl2583_suspend(struct device *dev) static int __maybe_unused tsl2583_suspend(struct device *dev)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
...@@ -855,7 +897,6 @@ static int __maybe_unused tsl2583_suspend(struct device *dev) ...@@ -855,7 +897,6 @@ static int __maybe_unused tsl2583_suspend(struct device *dev)
mutex_lock(&chip->als_mutex); mutex_lock(&chip->als_mutex);
ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF); ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF);
chip->suspended = true;
mutex_unlock(&chip->als_mutex); mutex_unlock(&chip->als_mutex);
...@@ -877,7 +918,11 @@ static int __maybe_unused tsl2583_resume(struct device *dev) ...@@ -877,7 +918,11 @@ static int __maybe_unused tsl2583_resume(struct device *dev)
return ret; return ret;
} }
static SIMPLE_DEV_PM_OPS(tsl2583_pm_ops, tsl2583_suspend, tsl2583_resume); static const struct dev_pm_ops tsl2583_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(tsl2583_suspend, tsl2583_resume, NULL)
};
static struct i2c_device_id tsl2583_idtable[] = { static struct i2c_device_id tsl2583_idtable[] = {
{ "tsl2580", 0 }, { "tsl2580", 0 },
...@@ -904,6 +949,7 @@ static struct i2c_driver tsl2583_driver = { ...@@ -904,6 +949,7 @@ static struct i2c_driver tsl2583_driver = {
}, },
.id_table = tsl2583_idtable, .id_table = tsl2583_idtable,
.probe = tsl2583_probe, .probe = tsl2583_probe,
.remove = tsl2583_remove,
}; };
module_i2c_driver(tsl2583_driver); module_i2c_driver(tsl2583_driver);
......
...@@ -31,6 +31,10 @@ struct dev_rot_state { ...@@ -31,6 +31,10 @@ struct dev_rot_state {
struct hid_sensor_common common_attributes; struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info quaternion; struct hid_sensor_hub_attribute_info quaternion;
u32 sampled_vals[4]; u32 sampled_vals[4];
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
int value_offset;
}; };
/* Channel definitions */ /* Channel definitions */
...@@ -41,6 +45,8 @@ static const struct iio_chan_spec dev_rot_channels[] = { ...@@ -41,6 +45,8 @@ static const struct iio_chan_spec dev_rot_channels[] = {
.channel2 = IIO_MOD_QUATERNION, .channel2 = IIO_MOD_QUATERNION,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_HYSTERESIS) BIT(IIO_CHAN_INFO_HYSTERESIS)
} }
}; };
...@@ -80,6 +86,15 @@ static int dev_rot_read_raw(struct iio_dev *indio_dev, ...@@ -80,6 +86,15 @@ static int dev_rot_read_raw(struct iio_dev *indio_dev,
} else } else
ret_type = -EINVAL; ret_type = -EINVAL;
break; break;
case IIO_CHAN_INFO_SCALE:
vals[0] = rot_state->scale_pre_decml;
vals[1] = rot_state->scale_post_decml;
return rot_state->scale_precision;
case IIO_CHAN_INFO_OFFSET:
*vals = rot_state->value_offset;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
ret_type = hid_sensor_read_samp_freq_value( ret_type = hid_sensor_read_samp_freq_value(
&rot_state->common_attributes, &vals[0], &vals[1]); &rot_state->common_attributes, &vals[0], &vals[1]);
...@@ -199,6 +214,11 @@ static int dev_rot_parse_report(struct platform_device *pdev, ...@@ -199,6 +214,11 @@ static int dev_rot_parse_report(struct platform_device *pdev,
dev_dbg(&pdev->dev, "dev_rot: attrib size %d\n", dev_dbg(&pdev->dev, "dev_rot: attrib size %d\n",
st->quaternion.size); st->quaternion.size);
st->scale_precision = hid_sensor_format_scale(
hsdev->usage,
&st->quaternion,
&st->scale_pre_decml, &st->scale_post_decml);
/* Set Sensitivity field ids, when there is no individual modifier */ /* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) { if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev, sensor_hub_input_get_attribute_info(hsdev,
...@@ -218,7 +238,7 @@ static int dev_rot_parse_report(struct platform_device *pdev, ...@@ -218,7 +238,7 @@ static int dev_rot_parse_report(struct platform_device *pdev,
static int hid_dev_rot_probe(struct platform_device *pdev) static int hid_dev_rot_probe(struct platform_device *pdev)
{ {
int ret; int ret;
static char *name = "dev_rotation"; static char *name;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
struct dev_rot_state *rot_state; struct dev_rot_state *rot_state;
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
...@@ -234,8 +254,21 @@ static int hid_dev_rot_probe(struct platform_device *pdev) ...@@ -234,8 +254,21 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
rot_state->common_attributes.hsdev = hsdev; rot_state->common_attributes.hsdev = hsdev;
rot_state->common_attributes.pdev = pdev; rot_state->common_attributes.pdev = pdev;
ret = hid_sensor_parse_common_attributes(hsdev, switch (hsdev->usage) {
HID_USAGE_SENSOR_DEVICE_ORIENTATION, case HID_USAGE_SENSOR_DEVICE_ORIENTATION:
name = "dev_rotation";
break;
case HID_USAGE_SENSOR_RELATIVE_ORIENTATION:
name = "relative_orientation";
break;
case HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION:
name = "geomagnetic_orientation";
break;
default:
return -EINVAL;
}
ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage,
&rot_state->common_attributes); &rot_state->common_attributes);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n"); dev_err(&pdev->dev, "failed to setup common attributes\n");
...@@ -252,8 +285,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev) ...@@ -252,8 +285,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
ret = dev_rot_parse_report(pdev, hsdev, ret = dev_rot_parse_report(pdev, hsdev,
(struct iio_chan_spec *)indio_dev->channels, (struct iio_chan_spec *)indio_dev->channels,
HID_USAGE_SENSOR_DEVICE_ORIENTATION, hsdev->usage, rot_state);
rot_state);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to setup attributes\n"); dev_err(&pdev->dev, "failed to setup attributes\n");
return ret; return ret;
...@@ -288,8 +320,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev) ...@@ -288,8 +320,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
rot_state->callbacks.send_event = dev_rot_proc_event; rot_state->callbacks.send_event = dev_rot_proc_event;
rot_state->callbacks.capture_sample = dev_rot_capture_sample; rot_state->callbacks.capture_sample = dev_rot_capture_sample;
rot_state->callbacks.pdev = pdev; rot_state->callbacks.pdev = pdev;
ret = sensor_hub_register_callback(hsdev, ret = sensor_hub_register_callback(hsdev, hsdev->usage,
HID_USAGE_SENSOR_DEVICE_ORIENTATION,
&rot_state->callbacks); &rot_state->callbacks);
if (ret) { if (ret) {
dev_err(&pdev->dev, "callback reg failed\n"); dev_err(&pdev->dev, "callback reg failed\n");
...@@ -314,7 +345,7 @@ static int hid_dev_rot_remove(struct platform_device *pdev) ...@@ -314,7 +345,7 @@ static int hid_dev_rot_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct dev_rot_state *rot_state = iio_priv(indio_dev); struct dev_rot_state *rot_state = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_DEVICE_ORIENTATION); sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
hid_sensor_remove_trigger(&rot_state->common_attributes); hid_sensor_remove_trigger(&rot_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev); iio_triggered_buffer_cleanup(indio_dev);
...@@ -327,6 +358,14 @@ static const struct platform_device_id hid_dev_rot_ids[] = { ...@@ -327,6 +358,14 @@ static const struct platform_device_id hid_dev_rot_ids[] = {
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-20008a", .name = "HID-SENSOR-20008a",
}, },
{
/* Relative orientation(AG) sensor */
.name = "HID-SENSOR-20008e",
},
{
/* Geomagnetic orientation(AM) sensor */
.name = "HID-SENSOR-2000c1",
},
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(platform, hid_dev_rot_ids); MODULE_DEVICE_TABLE(platform, hid_dev_rot_ids);
......
...@@ -23,7 +23,7 @@ config BMP280 ...@@ -23,7 +23,7 @@ config BMP280
select BMP280_SPI if (SPI_MASTER) select BMP280_SPI if (SPI_MASTER)
help help
Say yes here to build support for Bosch Sensortec BMP180 and BMP280 Say yes here to build support for Bosch Sensortec BMP180 and BMP280
pressure and temperature sensors. Also supports the BE280 with pressure and temperature sensors. Also supports the BME280 with
an additional humidity sensor channel. an additional humidity sensor channel.
To compile this driver as a module, choose M here: the core module To compile this driver as a module, choose M here: the core module
......
...@@ -568,6 +568,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = { ...@@ -568,6 +568,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
int st_press_common_probe(struct iio_dev *indio_dev) int st_press_common_probe(struct iio_dev *indio_dev)
{ {
struct st_sensor_data *press_data = iio_priv(indio_dev); struct st_sensor_data *press_data = iio_priv(indio_dev);
struct st_sensors_platform_data *pdata =
(struct st_sensors_platform_data *)press_data->dev->platform_data;
int irq = press_data->get_irq_data_ready(indio_dev); int irq = press_data->get_irq_data_ready(indio_dev);
int err; int err;
...@@ -603,10 +605,8 @@ int st_press_common_probe(struct iio_dev *indio_dev) ...@@ -603,10 +605,8 @@ int st_press_common_probe(struct iio_dev *indio_dev)
press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz; press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
/* Some devices don't support a data ready pin. */ /* Some devices don't support a data ready pin. */
if (!press_data->dev->platform_data && if (!pdata && press_data->sensor_settings->drdy_irq.addr)
press_data->sensor_settings->drdy_irq.addr) pdata = (struct st_sensors_platform_data *)&default_press_pdata;
press_data->dev->platform_data =
(struct st_sensors_platform_data *)&default_press_pdata;
err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
if (err < 0) if (err < 0)
......
...@@ -867,12 +867,13 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, ...@@ -867,12 +867,13 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
{ {
int ret; int ret;
unsigned int val; unsigned int val;
long timeout;
zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt"); zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt");
ret = wait_for_completion_interruptible_timeout( timeout = wait_for_completion_interruptible_timeout(
&private->data_ready, ZPA2326_CONVERSION_JIFFIES); &private->data_ready, ZPA2326_CONVERSION_JIFFIES);
if (ret > 0) if (timeout > 0)
/* /*
* Interrupt handler completed before timeout: return operation * Interrupt handler completed before timeout: return operation
* status. * status.
...@@ -882,13 +883,16 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, ...@@ -882,13 +883,16 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
/* Clear all interrupts just to be sure. */ /* Clear all interrupts just to be sure. */
regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val); regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val);
if (!ret) if (!timeout) {
/* Timed out. */ /* Timed out. */
zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)",
timeout);
ret = -ETIME; ret = -ETIME;
} else if (timeout < 0) {
if (ret != -ERESTARTSYS) zpa2326_warn(indio_dev,
zpa2326_warn(indio_dev, "no one shot interrupt occurred (%d)", "wait for one shot interrupt cancelled");
ret); ret = -ERESTARTSYS;
}
return ret; return ret;
} }
......
...@@ -176,13 +176,13 @@ static int as3935_read_raw(struct iio_dev *indio_dev, ...@@ -176,13 +176,13 @@ static int as3935_read_raw(struct iio_dev *indio_dev,
if (ret) if (ret)
return ret; return ret;
if (m == IIO_CHAN_INFO_RAW)
return IIO_VAL_INT;
/* storm out of range */ /* storm out of range */
if (*val == AS3935_DATA_MASK) if (*val == AS3935_DATA_MASK)
return -EINVAL; return -EINVAL;
if (m == IIO_CHAN_INFO_RAW)
return IIO_VAL_INT;
if (m == IIO_CHAN_INFO_PROCESSED) if (m == IIO_CHAN_INFO_PROCESSED)
*val *= 1000; *val *= 1000;
break; break;
......
...@@ -267,6 +267,7 @@ static int maxim_thermocouple_remove(struct spi_device *spi) ...@@ -267,6 +267,7 @@ static int maxim_thermocouple_remove(struct spi_device *spi)
static const struct spi_device_id maxim_thermocouple_id[] = { static const struct spi_device_id maxim_thermocouple_id[] = {
{"max6675", MAX6675}, {"max6675", MAX6675},
{"max31855", MAX31855}, {"max31855", MAX31855},
{"max31856", MAX31855},
{}, {},
}; };
MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id); MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
......
...@@ -14,19 +14,19 @@ ...@@ -14,19 +14,19 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#define MAX_TRIGGERS 6 #define MAX_TRIGGERS 7
#define MAX_VALIDS 5 #define MAX_VALIDS 5
/* List the triggers created by each timer */ /* List the triggers created by each timer */
static const void *triggers_table[][MAX_TRIGGERS] = { static const void *triggers_table[][MAX_TRIGGERS] = {
{ TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,}, { TIM1_TRGO, TIM1_TRGO2, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,},
{ TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,}, { TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,},
{ TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,}, { TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,},
{ TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,}, { TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,},
{ TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,}, { TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,},
{ TIM6_TRGO,}, { TIM6_TRGO,},
{ TIM7_TRGO,}, { TIM7_TRGO,},
{ TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,}, { TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
{ TIM9_TRGO, TIM9_CH1, TIM9_CH2,}, { TIM9_TRGO, TIM9_CH1, TIM9_CH2,},
{ }, /* timer 10 */ { }, /* timer 10 */
{ }, /* timer 11 */ { }, /* timer 11 */
...@@ -56,9 +56,16 @@ struct stm32_timer_trigger { ...@@ -56,9 +56,16 @@ struct stm32_timer_trigger {
u32 max_arr; u32 max_arr;
const void *triggers; const void *triggers;
const void *valids; const void *valids;
bool has_trgo2;
}; };
static bool stm32_timer_is_trgo2_name(const char *name)
{
return !!strstr(name, "trgo2");
}
static int stm32_timer_start(struct stm32_timer_trigger *priv, static int stm32_timer_start(struct stm32_timer_trigger *priv,
struct iio_trigger *trig,
unsigned int frequency) unsigned int frequency)
{ {
unsigned long long prd, div; unsigned long long prd, div;
...@@ -102,7 +109,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, ...@@ -102,7 +109,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
/* Force master mode to update mode */ /* Force master mode to update mode */
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0x20); if (stm32_timer_is_trgo2_name(trig->name))
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2,
0x2 << TIM_CR2_MMS2_SHIFT);
else
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS,
0x2 << TIM_CR2_MMS_SHIFT);
/* Make sure that registers are updated */ /* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
...@@ -150,7 +162,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev, ...@@ -150,7 +162,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev,
if (freq == 0) { if (freq == 0) {
stm32_timer_stop(priv); stm32_timer_stop(priv);
} else { } else {
ret = stm32_timer_start(priv, freq); ret = stm32_timer_start(priv, trig, freq);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -183,6 +195,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(0660, ...@@ -183,6 +195,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(0660,
stm32_tt_read_frequency, stm32_tt_read_frequency,
stm32_tt_store_frequency); stm32_tt_store_frequency);
#define MASTER_MODE_MAX 7
#define MASTER_MODE2_MAX 15
static char *master_mode_table[] = { static char *master_mode_table[] = {
"reset", "reset",
"enable", "enable",
...@@ -191,7 +206,16 @@ static char *master_mode_table[] = { ...@@ -191,7 +206,16 @@ static char *master_mode_table[] = {
"OC1REF", "OC1REF",
"OC2REF", "OC2REF",
"OC3REF", "OC3REF",
"OC4REF" "OC4REF",
/* Master mode selection 2 only */
"OC5REF",
"OC6REF",
"compare_pulse_OC4REF",
"compare_pulse_OC6REF",
"compare_pulse_OC4REF_r_or_OC6REF_r",
"compare_pulse_OC4REF_r_or_OC6REF_f",
"compare_pulse_OC5REF_r_or_OC6REF_r",
"compare_pulse_OC5REF_r_or_OC6REF_f",
}; };
static ssize_t stm32_tt_show_master_mode(struct device *dev, static ssize_t stm32_tt_show_master_mode(struct device *dev,
...@@ -199,9 +223,14 @@ static ssize_t stm32_tt_show_master_mode(struct device *dev, ...@@ -199,9 +223,14 @@ static ssize_t stm32_tt_show_master_mode(struct device *dev,
char *buf) char *buf)
{ {
struct stm32_timer_trigger *priv = dev_get_drvdata(dev); struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
struct iio_trigger *trig = to_iio_trigger(dev);
u32 cr2; u32 cr2;
regmap_read(priv->regmap, TIM_CR2, &cr2); regmap_read(priv->regmap, TIM_CR2, &cr2);
if (stm32_timer_is_trgo2_name(trig->name))
cr2 = (cr2 & TIM_CR2_MMS2) >> TIM_CR2_MMS2_SHIFT;
else
cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT; cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT;
return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]); return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]);
...@@ -212,13 +241,25 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev, ...@@ -212,13 +241,25 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
const char *buf, size_t len) const char *buf, size_t len)
{ {
struct stm32_timer_trigger *priv = dev_get_drvdata(dev); struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
struct iio_trigger *trig = to_iio_trigger(dev);
u32 mask, shift, master_mode_max;
int i; int i;
for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) { if (stm32_timer_is_trgo2_name(trig->name)) {
mask = TIM_CR2_MMS2;
shift = TIM_CR2_MMS2_SHIFT;
master_mode_max = MASTER_MODE2_MAX;
} else {
mask = TIM_CR2_MMS;
shift = TIM_CR2_MMS_SHIFT;
master_mode_max = MASTER_MODE_MAX;
}
for (i = 0; i <= master_mode_max; i++) {
if (!strncmp(master_mode_table[i], buf, if (!strncmp(master_mode_table[i], buf,
strlen(master_mode_table[i]))) { strlen(master_mode_table[i]))) {
regmap_update_bits(priv->regmap, TIM_CR2, regmap_update_bits(priv->regmap, TIM_CR2, mask,
TIM_CR2_MMS, i << TIM_CR2_MMS_SHIFT); i << shift);
/* Make sure that registers are updated */ /* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR, regmap_update_bits(priv->regmap, TIM_EGR,
TIM_EGR_UG, TIM_EGR_UG); TIM_EGR_UG, TIM_EGR_UG);
...@@ -229,8 +270,31 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev, ...@@ -229,8 +270,31 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
return -EINVAL; return -EINVAL;
} }
static IIO_CONST_ATTR(master_mode_available, static ssize_t stm32_tt_show_master_mode_avail(struct device *dev,
"reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF"); struct device_attribute *attr,
char *buf)
{
struct iio_trigger *trig = to_iio_trigger(dev);
unsigned int i, master_mode_max;
size_t len = 0;
if (stm32_timer_is_trgo2_name(trig->name))
master_mode_max = MASTER_MODE2_MAX;
else
master_mode_max = MASTER_MODE_MAX;
for (i = 0; i <= master_mode_max; i++)
len += scnprintf(buf + len, PAGE_SIZE - len,
"%s ", master_mode_table[i]);
/* replace trailing space by newline */
buf[len - 1] = '\n';
return len;
}
static IIO_DEVICE_ATTR(master_mode_available, 0444,
stm32_tt_show_master_mode_avail, NULL, 0);
static IIO_DEVICE_ATTR(master_mode, 0660, static IIO_DEVICE_ATTR(master_mode, 0660,
stm32_tt_show_master_mode, stm32_tt_show_master_mode,
...@@ -240,7 +304,7 @@ static IIO_DEVICE_ATTR(master_mode, 0660, ...@@ -240,7 +304,7 @@ static IIO_DEVICE_ATTR(master_mode, 0660,
static struct attribute *stm32_trigger_attrs[] = { static struct attribute *stm32_trigger_attrs[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_master_mode.dev_attr.attr, &iio_dev_attr_master_mode.dev_attr.attr,
&iio_const_attr_master_mode_available.dev_attr.attr, &iio_dev_attr_master_mode_available.dev_attr.attr,
NULL, NULL,
}; };
...@@ -264,6 +328,12 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) ...@@ -264,6 +328,12 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
while (cur && *cur) { while (cur && *cur) {
struct iio_trigger *trig; struct iio_trigger *trig;
bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur);
if (cur_is_trgo2 && !priv->has_trgo2) {
cur++;
continue;
}
trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur); trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur);
if (!trig) if (!trig)
...@@ -277,7 +347,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) ...@@ -277,7 +347,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
* should only be available on trgo trigger which * should only be available on trgo trigger which
* is always the first in the list. * is always the first in the list.
*/ */
if (cur == priv->triggers) if (cur == priv->triggers || cur_is_trgo2)
trig->dev.groups = stm32_trigger_attr_groups; trig->dev.groups = stm32_trigger_attr_groups;
iio_trigger_set_drvdata(trig, priv); iio_trigger_set_drvdata(trig, priv);
...@@ -584,6 +654,20 @@ bool is_stm32_timer_trigger(struct iio_trigger *trig) ...@@ -584,6 +654,20 @@ bool is_stm32_timer_trigger(struct iio_trigger *trig)
} }
EXPORT_SYMBOL(is_stm32_timer_trigger); EXPORT_SYMBOL(is_stm32_timer_trigger);
static void stm32_timer_detect_trgo2(struct stm32_timer_trigger *priv)
{
u32 val;
/*
* Master mode selection 2 bits can only be written and read back when
* timer supports it.
*/
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, TIM_CR2_MMS2);
regmap_read(priv->regmap, TIM_CR2, &val);
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0);
priv->has_trgo2 = !!val;
}
static int stm32_timer_trigger_probe(struct platform_device *pdev) static int stm32_timer_trigger_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -614,6 +698,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) ...@@ -614,6 +698,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
priv->max_arr = ddata->max_arr; priv->max_arr = ddata->max_arr;
priv->triggers = triggers_table[index]; priv->triggers = triggers_table[index];
priv->valids = valids_table[index]; priv->valids = valids_table[index];
stm32_timer_detect_trgo2(priv);
ret = stm32_setup_iio_triggers(priv); ret = stm32_setup_iio_triggers(priv);
if (ret) if (ret)
......
...@@ -292,7 +292,7 @@ ssize_t ad9834_show_out0_wavetype_available(struct device *dev, ...@@ -292,7 +292,7 @@ ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
return sprintf(buf, "%s\n", str); return sprintf(buf, "%s\n", str);
} }
static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, S_IRUGO, static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, 0444,
ad9834_show_out0_wavetype_available, NULL, 0); ad9834_show_out0_wavetype_available, NULL, 0);
static static
...@@ -312,27 +312,27 @@ ssize_t ad9834_show_out1_wavetype_available(struct device *dev, ...@@ -312,27 +312,27 @@ ssize_t ad9834_show_out1_wavetype_available(struct device *dev,
return sprintf(buf, "%s\n", str); return sprintf(buf, "%s\n", str);
} }
static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, S_IRUGO, static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, 0444,
ad9834_show_out1_wavetype_available, NULL, 0); ad9834_show_out1_wavetype_available, NULL, 0);
/** /**
* see dds.h for further information * see dds.h for further information
*/ */
static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0); static IIO_DEV_ATTR_FREQ(0, 0, 0200, NULL, ad9834_write, AD9834_REG_FREQ0);
static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1); static IIO_DEV_ATTR_FREQ(0, 1, 0200, NULL, ad9834_write, AD9834_REG_FREQ1);
static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL); static IIO_DEV_ATTR_FREQSYMBOL(0, 0200, NULL, ad9834_write, AD9834_FSEL);
static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0); static IIO_DEV_ATTR_PHASE(0, 0, 0200, NULL, ad9834_write, AD9834_REG_PHASE0);
static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1); static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9834_write, AD9834_REG_PHASE1);
static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL); static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, ad9834_write, AD9834_PSEL);
static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL,
ad9834_write, AD9834_PIN_SW); ad9834_write, AD9834_PIN_SW);
static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET); static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, ad9834_write, AD9834_RESET);
static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL, static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL,
ad9834_write, AD9834_OPBITEN); ad9834_write, AD9834_OPBITEN);
static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0);
static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1);
......
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ #define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \
IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_wavetype,\ IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_wavetype,\
S_IWUSR, NULL, _store, _addr) 0200, NULL, _store, _addr)
/** /**
* /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available * /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available
......
...@@ -3,16 +3,6 @@ ...@@ -3,16 +3,6 @@
# #
menu "Light sensors" menu "Light sensors"
config SENSORS_ISL29028
tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor"
depends on I2C
select REGMAP_I2C
help
Provides driver for the Intersil's ISL29028 device.
This driver supports the sysfs interface to get the ALS, IR intensity,
Proximity value via iio. The ISL29028 provides the concurrent sensing
of ambient light and proximity.
config TSL2x7x config TSL2x7x
tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors" tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors"
depends on I2C depends on I2C
......
...@@ -2,5 +2,4 @@ ...@@ -2,5 +2,4 @@
# Makefile for industrial I/O Light sensors # Makefile for industrial I/O Light sensors
# #
obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o obj-$(CONFIG_TSL2x7x) += tsl2x7x.o
obj-$(CONFIG_TSL2x7x) += tsl2x7x_core.o
...@@ -13,10 +13,6 @@ ...@@ -13,10 +13,6 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. * more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -919,7 +915,7 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) ...@@ -919,7 +915,7 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
tsl2x7x_chip_on(indio_dev); tsl2x7x_chip_on(indio_dev);
} }
static ssize_t tsl2x7x_power_state_show(struct device *dev, static ssize_t power_state_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -928,7 +924,7 @@ static ssize_t tsl2x7x_power_state_show(struct device *dev, ...@@ -928,7 +924,7 @@ static ssize_t tsl2x7x_power_state_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status); return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status);
} }
static ssize_t tsl2x7x_power_state_store(struct device *dev, static ssize_t power_state_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -946,7 +942,7 @@ static ssize_t tsl2x7x_power_state_store(struct device *dev, ...@@ -946,7 +942,7 @@ static ssize_t tsl2x7x_power_state_store(struct device *dev,
return len; return len;
} }
static ssize_t tsl2x7x_gain_available_show(struct device *dev, static ssize_t in_illuminance0_calibscale_available_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -964,14 +960,14 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev, ...@@ -964,14 +960,14 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120"); return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
} }
static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev, static ssize_t in_proximity0_calibscale_available_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8"); return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8");
} }
static ssize_t tsl2x7x_als_time_show(struct device *dev, static ssize_t in_illuminance0_integration_time_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -986,7 +982,7 @@ static ssize_t tsl2x7x_als_time_show(struct device *dev, ...@@ -986,7 +982,7 @@ static ssize_t tsl2x7x_als_time_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
} }
static ssize_t tsl2x7x_als_time_store(struct device *dev, static ssize_t in_illuminance0_integration_time_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1014,7 +1010,7 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev, ...@@ -1014,7 +1010,7 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev,
static IIO_CONST_ATTR(in_illuminance0_integration_time_available, static IIO_CONST_ATTR(in_illuminance0_integration_time_available,
".00272 - .696"); ".00272 - .696");
static ssize_t tsl2x7x_als_cal_target_show(struct device *dev, static ssize_t in_illuminance0_target_input_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -1024,7 +1020,7 @@ static ssize_t tsl2x7x_als_cal_target_show(struct device *dev, ...@@ -1024,7 +1020,7 @@ static ssize_t tsl2x7x_als_cal_target_show(struct device *dev,
chip->tsl2x7x_settings.als_cal_target); chip->tsl2x7x_settings.als_cal_target);
} }
static ssize_t tsl2x7x_als_cal_target_store(struct device *dev, static ssize_t in_illuminance0_target_input_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1044,7 +1040,7 @@ static ssize_t tsl2x7x_als_cal_target_store(struct device *dev, ...@@ -1044,7 +1040,7 @@ static ssize_t tsl2x7x_als_cal_target_store(struct device *dev,
} }
/* persistence settings */ /* persistence settings */
static ssize_t tsl2x7x_als_persistence_show(struct device *dev, static ssize_t in_intensity0_thresh_period_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -1061,7 +1057,7 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev, ...@@ -1061,7 +1057,7 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
} }
static ssize_t tsl2x7x_als_persistence_store(struct device *dev, static ssize_t in_intensity0_thresh_period_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1092,7 +1088,7 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev, ...@@ -1092,7 +1088,7 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
} }
static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, static ssize_t in_proximity0_thresh_period_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -1109,7 +1105,7 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, ...@@ -1109,7 +1105,7 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
} }
static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, static ssize_t in_proximity0_thresh_period_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1140,7 +1136,7 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, ...@@ -1140,7 +1136,7 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
} }
static ssize_t tsl2x7x_do_calibrate(struct device *dev, static ssize_t in_illuminance0_calibrate_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1158,7 +1154,7 @@ static ssize_t tsl2x7x_do_calibrate(struct device *dev, ...@@ -1158,7 +1154,7 @@ static ssize_t tsl2x7x_do_calibrate(struct device *dev,
return len; return len;
} }
static ssize_t tsl2x7x_luxtable_show(struct device *dev, static ssize_t in_illuminance0_lux_table_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -1186,7 +1182,7 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev, ...@@ -1186,7 +1182,7 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev,
return offset; return offset;
} }
static ssize_t tsl2x7x_luxtable_store(struct device *dev, static ssize_t in_illuminance0_lux_table_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1226,7 +1222,7 @@ static ssize_t tsl2x7x_luxtable_store(struct device *dev, ...@@ -1226,7 +1222,7 @@ static ssize_t tsl2x7x_luxtable_store(struct device *dev,
return len; return len;
} }
static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev, static ssize_t in_proximity0_calibrate_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
...@@ -1498,35 +1494,25 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev, ...@@ -1498,35 +1494,25 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
return 0; return 0;
} }
static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, static DEVICE_ATTR_RW(power_state);
tsl2x7x_power_state_show, tsl2x7x_power_state_store);
static DEVICE_ATTR(in_proximity0_calibscale_available, S_IRUGO, static DEVICE_ATTR_RO(in_proximity0_calibscale_available);
tsl2x7x_prox_gain_available_show, NULL);
static DEVICE_ATTR(in_illuminance0_calibscale_available, S_IRUGO, static DEVICE_ATTR_RO(in_illuminance0_calibscale_available);
tsl2x7x_gain_available_show, NULL);
static DEVICE_ATTR(in_illuminance0_integration_time, S_IRUGO | S_IWUSR, static DEVICE_ATTR_RW(in_illuminance0_integration_time);
tsl2x7x_als_time_show, tsl2x7x_als_time_store);
static DEVICE_ATTR(in_illuminance0_target_input, S_IRUGO | S_IWUSR, static DEVICE_ATTR_RW(in_illuminance0_target_input);
tsl2x7x_als_cal_target_show, tsl2x7x_als_cal_target_store);
static DEVICE_ATTR(in_illuminance0_calibrate, S_IWUSR, NULL, static DEVICE_ATTR_WO(in_illuminance0_calibrate);
tsl2x7x_do_calibrate);
static DEVICE_ATTR(in_proximity0_calibrate, S_IWUSR, NULL, static DEVICE_ATTR_WO(in_proximity0_calibrate);
tsl2x7x_do_prox_calibrate);
static DEVICE_ATTR(in_illuminance0_lux_table, S_IRUGO | S_IWUSR, static DEVICE_ATTR_RW(in_illuminance0_lux_table);
tsl2x7x_luxtable_show, tsl2x7x_luxtable_store);
static DEVICE_ATTR(in_intensity0_thresh_period, S_IRUGO | S_IWUSR, static DEVICE_ATTR_RW(in_intensity0_thresh_period);
tsl2x7x_als_persistence_show, tsl2x7x_als_persistence_store);
static DEVICE_ATTR(in_proximity0_thresh_period, S_IRUGO | S_IWUSR, static DEVICE_ATTR_RW(in_proximity0_thresh_period);
tsl2x7x_prox_persistence_show, tsl2x7x_prox_persistence_store);
/* Use the default register values to identify the Taos device */ /* Use the default register values to identify the Taos device */
static int tsl2x7x_device_id(unsigned char *id, int target) static int tsl2x7x_device_id(unsigned char *id, int target)
......
...@@ -107,8 +107,7 @@ static int ade7753_spi_write_reg_8(struct device *dev, ...@@ -107,8 +107,7 @@ static int ade7753_spi_write_reg_8(struct device *dev,
return ret; return ret;
} }
static int ade7753_spi_write_reg_16(struct device *dev, static int ade7753_spi_write_reg_16(struct device *dev, u8 reg_address,
u8 reg_address,
u16 value) u16 value)
{ {
int ret; int ret;
...@@ -298,92 +297,92 @@ static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY); ...@@ -298,92 +297,92 @@ static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY); static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY); static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY); static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY);
static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CFDEN(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_CFDEN); ADE7753_CFDEN);
static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CFNUM(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_CFNUM); ADE7753_CFNUM);
static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM); static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM);
static IIO_DEV_ATTR_PHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_PHCAL(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_PHCAL); ADE7753_PHCAL);
static IIO_DEV_ATTR_APOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APOS(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_APOS); ADE7753_APOS);
static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_SAGCYC(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_SAGCYC); ADE7753_SAGCYC);
static IIO_DEV_ATTR_SAGLVL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_SAGLVL(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_SAGLVL); ADE7753_SAGLVL);
static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_LINECYC(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_LINECYC); ADE7753_LINECYC);
static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_WDIV(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_WDIV); ADE7753_WDIV);
static IIO_DEV_ATTR_IRMS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_IRMS(0644,
ade7753_read_24bit, ade7753_read_24bit,
NULL, NULL,
ADE7753_IRMS); ADE7753_IRMS);
static IIO_DEV_ATTR_VRMS(S_IRUGO, static IIO_DEV_ATTR_VRMS(0444,
ade7753_read_24bit, ade7753_read_24bit,
NULL, NULL,
ADE7753_VRMS); ADE7753_VRMS);
static IIO_DEV_ATTR_IRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_IRMSOS(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_IRMSOS); ADE7753_IRMSOS);
static IIO_DEV_ATTR_VRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VRMSOS(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_VRMSOS); ADE7753_VRMSOS);
static IIO_DEV_ATTR_WGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_WGAIN(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_WGAIN); ADE7753_WGAIN);
static IIO_DEV_ATTR_VAGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VAGAIN(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_VAGAIN); ADE7753_VAGAIN);
static IIO_DEV_ATTR_PGA_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_PGA_GAIN(0644,
ade7753_read_16bit, ade7753_read_16bit,
ade7753_write_16bit, ade7753_write_16bit,
ADE7753_GAIN); ADE7753_GAIN);
static IIO_DEV_ATTR_IPKLVL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_IPKLVL(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_IPKLVL); ADE7753_IPKLVL);
static IIO_DEV_ATTR_VPKLVL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VPKLVL(0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_VPKLVL); ADE7753_VPKLVL);
static IIO_DEV_ATTR_IPEAK(S_IRUGO, static IIO_DEV_ATTR_IPEAK(0444,
ade7753_read_24bit, ade7753_read_24bit,
NULL, NULL,
ADE7753_IPEAK); ADE7753_IPEAK);
static IIO_DEV_ATTR_VPEAK(S_IRUGO, static IIO_DEV_ATTR_VPEAK(0444,
ade7753_read_24bit, ade7753_read_24bit,
NULL, NULL,
ADE7753_VPEAK); ADE7753_VPEAK);
static IIO_DEV_ATTR_VPERIOD(S_IRUGO, static IIO_DEV_ATTR_VPERIOD(0444,
ade7753_read_16bit, ade7753_read_16bit,
NULL, NULL,
ADE7753_PERIOD); ADE7753_PERIOD);
static IIO_DEV_ATTR_CH_OFF(1, S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CH_OFF(1, 0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_CH1OS); ADE7753_CH1OS);
static IIO_DEV_ATTR_CH_OFF(2, S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CH_OFF(2, 0644,
ade7753_read_8bit, ade7753_read_8bit,
ade7753_write_8bit, ade7753_write_8bit,
ADE7753_CH2OS); ADE7753_CH2OS);
...@@ -514,7 +513,7 @@ static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit); ...@@ -514,7 +513,7 @@ static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit);
static IIO_CONST_ATTR(in_temp_offset, "-25 C"); static IIO_CONST_ATTR(in_temp_offset, "-25 C");
static IIO_CONST_ATTR(in_temp_scale, "0.67 C"); static IIO_CONST_ATTR(in_temp_scale, "0.67 C");
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_SAMP_FREQ(0644,
ade7753_read_frequency, ade7753_read_frequency,
ade7753_write_frequency); ade7753_write_frequency);
......
...@@ -316,111 +316,111 @@ static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY); ...@@ -316,111 +316,111 @@ static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY); static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY); static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY); static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY);
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VPEAK(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_VPEAK); ADE7754_VPEAK);
static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_IPEAK(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_VPEAK); ADE7754_VPEAK);
static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APHCAL(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_APHCAL); ADE7754_APHCAL);
static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BPHCAL(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_BPHCAL); ADE7754_BPHCAL);
static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CPHCAL(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_CPHCAL); ADE7754_CPHCAL);
static IIO_DEV_ATTR_AAPOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AAPOS(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_AAPOS); ADE7754_AAPOS);
static IIO_DEV_ATTR_BAPOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BAPOS(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_BAPOS); ADE7754_BAPOS);
static IIO_DEV_ATTR_CAPOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CAPOS(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_CAPOS); ADE7754_CAPOS);
static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_WDIV(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_WDIV); ADE7754_WDIV);
static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VADIV(0644,
ade7754_read_8bit, ade7754_read_8bit,
ade7754_write_8bit, ade7754_write_8bit,
ADE7754_VADIV); ADE7754_VADIV);
static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CFNUM(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_CFNUM); ADE7754_CFNUM);
static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CFDEN(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_CFDEN); ADE7754_CFDEN);
static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_AAPGAIN); ADE7754_AAPGAIN);
static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_BAPGAIN); ADE7754_BAPGAIN);
static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(0644,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_CAPGAIN); ADE7754_CAPGAIN);
static IIO_DEV_ATTR_AIRMS(S_IRUGO, static IIO_DEV_ATTR_AIRMS(0444,
ade7754_read_24bit, ade7754_read_24bit,
NULL, NULL,
ADE7754_AIRMS); ADE7754_AIRMS);
static IIO_DEV_ATTR_BIRMS(S_IRUGO, static IIO_DEV_ATTR_BIRMS(0444,
ade7754_read_24bit, ade7754_read_24bit,
NULL, NULL,
ADE7754_BIRMS); ADE7754_BIRMS);
static IIO_DEV_ATTR_CIRMS(S_IRUGO, static IIO_DEV_ATTR_CIRMS(0444,
ade7754_read_24bit, ade7754_read_24bit,
NULL, NULL,
ADE7754_CIRMS); ADE7754_CIRMS);
static IIO_DEV_ATTR_AVRMS(S_IRUGO, static IIO_DEV_ATTR_AVRMS(0444,
ade7754_read_24bit, ade7754_read_24bit,
NULL, NULL,
ADE7754_AVRMS); ADE7754_AVRMS);
static IIO_DEV_ATTR_BVRMS(S_IRUGO, static IIO_DEV_ATTR_BVRMS(0444,
ade7754_read_24bit, ade7754_read_24bit,
NULL, NULL,
ADE7754_BVRMS); ADE7754_BVRMS);
static IIO_DEV_ATTR_CVRMS(S_IRUGO, static IIO_DEV_ATTR_CVRMS(0444,
ade7754_read_24bit, ade7754_read_24bit,
NULL, NULL,
ADE7754_CVRMS); ADE7754_CVRMS);
static IIO_DEV_ATTR_AIRMSOS(S_IRUGO, static IIO_DEV_ATTR_AIRMSOS(0444,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_AIRMSOS); ADE7754_AIRMSOS);
static IIO_DEV_ATTR_BIRMSOS(S_IRUGO, static IIO_DEV_ATTR_BIRMSOS(0444,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_BIRMSOS); ADE7754_BIRMSOS);
static IIO_DEV_ATTR_CIRMSOS(S_IRUGO, static IIO_DEV_ATTR_CIRMSOS(0444,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_CIRMSOS); ADE7754_CIRMSOS);
static IIO_DEV_ATTR_AVRMSOS(S_IRUGO, static IIO_DEV_ATTR_AVRMSOS(0444,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_AVRMSOS); ADE7754_AVRMSOS);
static IIO_DEV_ATTR_BVRMSOS(S_IRUGO, static IIO_DEV_ATTR_BVRMSOS(0444,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_BVRMSOS); ADE7754_BVRMSOS);
static IIO_DEV_ATTR_CVRMSOS(S_IRUGO, static IIO_DEV_ATTR_CVRMSOS(0444,
ade7754_read_16bit, ade7754_read_16bit,
ade7754_write_16bit, ade7754_write_16bit,
ADE7754_CVRMSOS); ADE7754_CVRMSOS);
...@@ -549,7 +549,7 @@ static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit); ...@@ -549,7 +549,7 @@ static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit);
static IIO_CONST_ATTR(in_temp_offset, "129 C"); static IIO_CONST_ATTR(in_temp_offset, "129 C");
static IIO_CONST_ATTR(in_temp_scale, "4 C"); static IIO_CONST_ATTR(in_temp_scale, "4 C");
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_SAMP_FREQ(0644,
ade7754_read_frequency, ade7754_read_frequency,
ade7754_write_frequency); ade7754_write_frequency);
......
...@@ -301,103 +301,103 @@ static int ade7758_reset(struct device *dev) ...@@ -301,103 +301,103 @@ static int ade7758_reset(struct device *dev)
return ret; return ret;
} }
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VPEAK(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_VPEAK); ADE7758_VPEAK);
static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_IPEAK(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_VPEAK); ADE7758_VPEAK);
static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APHCAL(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_APHCAL); ADE7758_APHCAL);
static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BPHCAL(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_BPHCAL); ADE7758_BPHCAL);
static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CPHCAL(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_CPHCAL); ADE7758_CPHCAL);
static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_WDIV(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_WDIV); ADE7758_WDIV);
static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VADIV(0644,
ade7758_read_8bit, ade7758_read_8bit,
ade7758_write_8bit, ade7758_write_8bit,
ADE7758_VADIV); ADE7758_VADIV);
static IIO_DEV_ATTR_AIRMS(S_IRUGO, static IIO_DEV_ATTR_AIRMS(0444,
ade7758_read_24bit, ade7758_read_24bit,
NULL, NULL,
ADE7758_AIRMS); ADE7758_AIRMS);
static IIO_DEV_ATTR_BIRMS(S_IRUGO, static IIO_DEV_ATTR_BIRMS(0444,
ade7758_read_24bit, ade7758_read_24bit,
NULL, NULL,
ADE7758_BIRMS); ADE7758_BIRMS);
static IIO_DEV_ATTR_CIRMS(S_IRUGO, static IIO_DEV_ATTR_CIRMS(0444,
ade7758_read_24bit, ade7758_read_24bit,
NULL, NULL,
ADE7758_CIRMS); ADE7758_CIRMS);
static IIO_DEV_ATTR_AVRMS(S_IRUGO, static IIO_DEV_ATTR_AVRMS(0444,
ade7758_read_24bit, ade7758_read_24bit,
NULL, NULL,
ADE7758_AVRMS); ADE7758_AVRMS);
static IIO_DEV_ATTR_BVRMS(S_IRUGO, static IIO_DEV_ATTR_BVRMS(0444,
ade7758_read_24bit, ade7758_read_24bit,
NULL, NULL,
ADE7758_BVRMS); ADE7758_BVRMS);
static IIO_DEV_ATTR_CVRMS(S_IRUGO, static IIO_DEV_ATTR_CVRMS(0444,
ade7758_read_24bit, ade7758_read_24bit,
NULL, NULL,
ADE7758_CVRMS); ADE7758_CVRMS);
static IIO_DEV_ATTR_AIRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AIRMSOS(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_AIRMSOS); ADE7758_AIRMSOS);
static IIO_DEV_ATTR_BIRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BIRMSOS(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_BIRMSOS); ADE7758_BIRMSOS);
static IIO_DEV_ATTR_CIRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CIRMSOS(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_CIRMSOS); ADE7758_CIRMSOS);
static IIO_DEV_ATTR_AVRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AVRMSOS(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_AVRMSOS); ADE7758_AVRMSOS);
static IIO_DEV_ATTR_BVRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BVRMSOS(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_BVRMSOS); ADE7758_BVRMSOS);
static IIO_DEV_ATTR_CVRMSOS(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CVRMSOS(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_CVRMSOS); ADE7758_CVRMSOS);
static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AIGAIN(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_AIGAIN); ADE7758_AIGAIN);
static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BIGAIN(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_BIGAIN); ADE7758_BIGAIN);
static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CIGAIN(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_CIGAIN); ADE7758_CIGAIN);
static IIO_DEV_ATTR_AVRMSGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AVRMSGAIN(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_AVRMSGAIN); ADE7758_AVRMSGAIN);
static IIO_DEV_ATTR_BVRMSGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BVRMSGAIN(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_BVRMSGAIN); ADE7758_BVRMSGAIN);
static IIO_DEV_ATTR_CVRMSGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CVRMSGAIN(0644,
ade7758_read_16bit, ade7758_read_16bit,
ade7758_write_16bit, ade7758_write_16bit,
ADE7758_CVRMSGAIN); ADE7758_CVRMSGAIN);
......
...@@ -186,127 +186,127 @@ static int ade7854_reset(struct device *dev) ...@@ -186,127 +186,127 @@ static int ade7854_reset(struct device *dev)
return st->write_reg_16(dev, ADE7854_CONFIG, val); return st->write_reg_16(dev, ADE7854_CONFIG, val);
} }
static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AIGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_AIGAIN); ADE7854_AIGAIN);
static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BIGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_BIGAIN); ADE7854_BIGAIN);
static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CIGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_CIGAIN); ADE7854_CIGAIN);
static IIO_DEV_ATTR_NIGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_NIGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_NIGAIN); ADE7854_NIGAIN);
static IIO_DEV_ATTR_AVGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_AVGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_AVGAIN); ADE7854_AVGAIN);
static IIO_DEV_ATTR_BVGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BVGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_BVGAIN); ADE7854_BVGAIN);
static IIO_DEV_ATTR_CVGAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CVGAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_CVGAIN); ADE7854_CVGAIN);
static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_AVAGAIN); ADE7854_AVAGAIN);
static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_BVAGAIN); ADE7854_BVAGAIN);
static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_CVAGAIN); ADE7854_CVAGAIN);
static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_AWATTOS); ADE7854_AWATTOS);
static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_BWATTOS); ADE7854_BWATTOS);
static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_CWATTOS); ADE7854_CWATTOS);
static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_AVARGAIN); ADE7854_AVARGAIN);
static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_BVARGAIN); ADE7854_BVARGAIN);
static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_CVARGAIN); ADE7854_CVARGAIN);
static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_AVAROS); ADE7854_AVAROS);
static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_BVAROS); ADE7854_BVAROS);
static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(0644,
ade7854_read_24bit, ade7854_read_24bit,
ade7854_write_24bit, ade7854_write_24bit,
ADE7854_CVAROS); ADE7854_CVAROS);
static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_VPEAK(0644,
ade7854_read_32bit, ade7854_read_32bit,
ade7854_write_32bit, ade7854_write_32bit,
ADE7854_VPEAK); ADE7854_VPEAK);
static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_IPEAK(0644,
ade7854_read_32bit, ade7854_read_32bit,
ade7854_write_32bit, ade7854_write_32bit,
ADE7854_VPEAK); ADE7854_VPEAK);
static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_APHCAL(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_APHCAL); ADE7854_APHCAL);
static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_BPHCAL(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_BPHCAL); ADE7854_BPHCAL);
static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CPHCAL(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_CPHCAL); ADE7854_CPHCAL);
static IIO_DEV_ATTR_CF1DEN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CF1DEN(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_CF1DEN); ADE7854_CF1DEN);
static IIO_DEV_ATTR_CF2DEN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CF2DEN(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_CF2DEN); ADE7854_CF2DEN);
static IIO_DEV_ATTR_CF3DEN(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CF3DEN(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_CF3DEN); ADE7854_CF3DEN);
static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_LINECYC(0644,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_LINECYC); ADE7854_LINECYC);
static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_SAGCYC(0644,
ade7854_read_8bit, ade7854_read_8bit,
ade7854_write_8bit, ade7854_write_8bit,
ADE7854_SAGCYC); ADE7854_SAGCYC);
static IIO_DEV_ATTR_CFCYC(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_CFCYC(0644,
ade7854_read_8bit, ade7854_read_8bit,
ade7854_write_8bit, ade7854_write_8bit,
ADE7854_CFCYC); ADE7854_CFCYC);
static IIO_DEV_ATTR_PEAKCYC(S_IWUSR | S_IRUGO, static IIO_DEV_ATTR_PEAKCYC(0644,
ade7854_read_8bit, ade7854_read_8bit,
ade7854_write_8bit, ade7854_write_8bit,
ADE7854_PEAKCYC); ADE7854_PEAKCYC);
...@@ -318,55 +318,55 @@ static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit, ...@@ -318,55 +318,55 @@ static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit,
ADE7854_ANGLE1); ADE7854_ANGLE1);
static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit, static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit,
ADE7854_ANGLE2); ADE7854_ANGLE2);
static IIO_DEV_ATTR_AIRMS(S_IRUGO, static IIO_DEV_ATTR_AIRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_AIRMS); ADE7854_AIRMS);
static IIO_DEV_ATTR_BIRMS(S_IRUGO, static IIO_DEV_ATTR_BIRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_BIRMS); ADE7854_BIRMS);
static IIO_DEV_ATTR_CIRMS(S_IRUGO, static IIO_DEV_ATTR_CIRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_CIRMS); ADE7854_CIRMS);
static IIO_DEV_ATTR_NIRMS(S_IRUGO, static IIO_DEV_ATTR_NIRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_NIRMS); ADE7854_NIRMS);
static IIO_DEV_ATTR_AVRMS(S_IRUGO, static IIO_DEV_ATTR_AVRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_AVRMS); ADE7854_AVRMS);
static IIO_DEV_ATTR_BVRMS(S_IRUGO, static IIO_DEV_ATTR_BVRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_BVRMS); ADE7854_BVRMS);
static IIO_DEV_ATTR_CVRMS(S_IRUGO, static IIO_DEV_ATTR_CVRMS(0444,
ade7854_read_24bit, ade7854_read_24bit,
NULL, NULL,
ADE7854_CVRMS); ADE7854_CVRMS);
static IIO_DEV_ATTR_AIRMSOS(S_IRUGO, static IIO_DEV_ATTR_AIRMSOS(0444,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_AIRMSOS); ADE7854_AIRMSOS);
static IIO_DEV_ATTR_BIRMSOS(S_IRUGO, static IIO_DEV_ATTR_BIRMSOS(0444,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_BIRMSOS); ADE7854_BIRMSOS);
static IIO_DEV_ATTR_CIRMSOS(S_IRUGO, static IIO_DEV_ATTR_CIRMSOS(0444,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_CIRMSOS); ADE7854_CIRMSOS);
static IIO_DEV_ATTR_AVRMSOS(S_IRUGO, static IIO_DEV_ATTR_AVRMSOS(0444,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_AVRMSOS); ADE7854_AVRMSOS);
static IIO_DEV_ATTR_BVRMSOS(S_IRUGO, static IIO_DEV_ATTR_BVRMSOS(0444,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_BVRMSOS); ADE7854_BVRMSOS);
static IIO_DEV_ATTR_CVRMSOS(S_IRUGO, static IIO_DEV_ATTR_CVRMSOS(0444,
ade7854_read_16bit, ade7854_read_16bit,
ade7854_write_16bit, ade7854_write_16bit,
ADE7854_CVRMSOS); ADE7854_CVRMSOS);
......
...@@ -233,12 +233,14 @@ struct hid_sensor_common { ...@@ -233,12 +233,14 @@ struct hid_sensor_common {
atomic_t user_requested_state; atomic_t user_requested_state;
int poll_interval; int poll_interval;
int raw_hystersis; int raw_hystersis;
int latency_ms;
struct iio_trigger *trigger; struct iio_trigger *trigger;
int timestamp_ns_scale; int timestamp_ns_scale;
struct hid_sensor_hub_attribute_info poll; struct hid_sensor_hub_attribute_info poll;
struct hid_sensor_hub_attribute_info report_state; struct hid_sensor_hub_attribute_info report_state;
struct hid_sensor_hub_attribute_info power_state; struct hid_sensor_hub_attribute_info power_state;
struct hid_sensor_hub_attribute_info sensitivity; struct hid_sensor_hub_attribute_info sensitivity;
struct hid_sensor_hub_attribute_info report_latency;
struct work_struct work; struct work_struct work;
}; };
...@@ -276,5 +278,8 @@ s32 hid_sensor_read_poll_value(struct hid_sensor_common *st); ...@@ -276,5 +278,8 @@ s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st, int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st,
int64_t raw_value); int64_t raw_value);
bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st);
int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency);
int hid_sensor_get_report_latency(struct hid_sensor_common *st);
#endif #endif
...@@ -90,6 +90,8 @@ ...@@ -90,6 +90,8 @@
#define HID_USAGE_SENSOR_ORIENT_TILT_Z 0x200481 #define HID_USAGE_SENSOR_ORIENT_TILT_Z 0x200481
#define HID_USAGE_SENSOR_DEVICE_ORIENTATION 0x20008A #define HID_USAGE_SENSOR_DEVICE_ORIENTATION 0x20008A
#define HID_USAGE_SENSOR_RELATIVE_ORIENTATION 0x20008E
#define HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION 0x2000C1
#define HID_USAGE_SENSOR_ORIENT_ROTATION_MATRIX 0x200482 #define HID_USAGE_SENSOR_ORIENT_ROTATION_MATRIX 0x200482
#define HID_USAGE_SENSOR_ORIENT_QUATERNION 0x200483 #define HID_USAGE_SENSOR_ORIENT_QUATERNION 0x200483
#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX 0x200484 #define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX 0x200484
...@@ -150,6 +152,9 @@ ...@@ -150,6 +152,9 @@
#define HID_USAGE_SENSOR_PROP_REPORT_STATE 0x200316 #define HID_USAGE_SENSOR_PROP_REPORT_STATE 0x200316
#define HID_USAGE_SENSOR_PROY_POWER_STATE 0x200319 #define HID_USAGE_SENSOR_PROY_POWER_STATE 0x200319
/* Batch mode selectors */
#define HID_USAGE_SENSOR_PROP_REPORT_LATENCY 0x20031B
/* Per data field properties */ /* Per data field properties */
#define HID_USAGE_SENSOR_DATA_MOD_NONE 0x00 #define HID_USAGE_SENSOR_DATA_MOD_NONE 0x00
#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS 0x1000 #define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS 0x1000
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define _STM32_TIMER_TRIGGER_H_ #define _STM32_TIMER_TRIGGER_H_
#define TIM1_TRGO "tim1_trgo" #define TIM1_TRGO "tim1_trgo"
#define TIM1_TRGO2 "tim1_trgo2"
#define TIM1_CH1 "tim1_ch1" #define TIM1_CH1 "tim1_ch1"
#define TIM1_CH2 "tim1_ch2" #define TIM1_CH2 "tim1_ch2"
#define TIM1_CH3 "tim1_ch3" #define TIM1_CH3 "tim1_ch3"
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#define TIM7_TRGO "tim7_trgo" #define TIM7_TRGO "tim7_trgo"
#define TIM8_TRGO "tim8_trgo" #define TIM8_TRGO "tim8_trgo"
#define TIM8_TRGO2 "tim8_trgo2"
#define TIM8_CH1 "tim8_ch1" #define TIM8_CH1 "tim8_ch1"
#define TIM8_CH2 "tim8_ch2" #define TIM8_CH2 "tim8_ch2"
#define TIM8_CH3 "tim8_ch3" #define TIM8_CH3 "tim8_ch3"
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#define TIM_CR1_DIR BIT(4) /* Counter Direction */ #define TIM_CR1_DIR BIT(4) /* Counter Direction */
#define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */ #define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */
#define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */ #define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
#define TIM_CR2_MMS2 GENMASK(23, 20) /* Master mode selection 2 */
#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */ #define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */ #define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
#define TIM_DIER_UIE BIT(0) /* Update interrupt */ #define TIM_DIER_UIE BIT(0) /* Update interrupt */
...@@ -60,6 +61,7 @@ ...@@ -60,6 +61,7 @@
#define MAX_TIM_PSC 0xFFFF #define MAX_TIM_PSC 0xFFFF
#define TIM_CR2_MMS_SHIFT 4 #define TIM_CR2_MMS_SHIFT 4
#define TIM_CR2_MMS2_SHIFT 20
#define TIM_SMCR_TS_SHIFT 4 #define TIM_SMCR_TS_SHIFT 4
#define TIM_BDTR_BKF_MASK 0xF #define TIM_BDTR_BKF_MASK 0xF
#define TIM_BDTR_BKF_SHIFT 16 #define TIM_BDTR_BKF_SHIFT 16
......
CC = $(CROSS_COMPILE)gcc CC = $(CROSS_COMPILE)gcc
CFLAGS += -Wall -g -D_GNU_SOURCE CFLAGS += -Wall -g -D_GNU_SOURCE -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
BINDIR=usr/bin BINDIR=usr/bin
INSTALL_PROGRAM=install -m 755 -p INSTALL_PROGRAM=install -m 755 -p
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <stdint.h> #include <stdint.h>
/* Made up value to limit allocation sizes */ /* Made up value to limit allocation sizes */
#define IIO_MAX_NAME_LENGTH 30 #define IIO_MAX_NAME_LENGTH 64
#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements" #define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
#define FORMAT_TYPE_FILE "%s_type" #define FORMAT_TYPE_FILE "%s_type"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment