Second set of new device support, features and cleanup for IIO in the 4.17 cycle

The uptick in staging cleanup is partly due to GSoC Applications
 process being underway and one of Daniel's tasks being to try
 cleaning up an IIO driver to move out of staging.
 Naturally there is some normal staging cleanup progress in here
 as well.
 
 New device support
 * Microchip mcp4018
   - New driver supproting MCP4017, MCP4018 and MCP4019 digital pots.
 * On Semiconductor lv0104cs
   - New driver to support this ambient light sensor.
 
 Cleanup
 * axp20x_adc
   - remove a !! in favour of clear ternary operator.
 * ad2s1210 (staging cleanup)
   - Reorganise to avoid ending a line with [
   - Remove some unnecessary defines.
   - Remove unsed variable.
 * ad5380
   - Replace magic 0 with IIO_CHAN_INFO_RAW
 * ad5764
   - Replace magic 0 with IIO_CHA_INFO_RAW
 * ad7150 (staging cleanup)
   - Align arguements with parenthesis.
 * ad7152 (staging cleanup)
   - Align arguements.
 * ad7746 (staging cleanup)
   - Align arguements.
 * ad7816
   - Remove pointless void pointer cast.
 * ade7753
   - Replace IIO_DEV_ATTR_CH_OFF with equivalent to avoid confusing
     checkpatch (this macro didn't really help anyway).  Also drop the
     macro from the meter.h header.
 * ade7754 (staging cleanup)
   - Add names to funciton definition arguements.
   - Align arguements with open parenthesis where possible.
 * ade7758 (staging cleanup)
   - Remove __func__ from dev_dbg statements as provided by dynamic
     debug anyway.
   - Align arguements with open parenthesis where possible.
 * ade7759 (staging cleanup)
   - Replace IIO_DEV_ATTR_CH_OFF with equiavalent to avoid confusing
     checkpatch.
 * adis16201 (staging cleanup)
   - Headers in alphabetical order.
   - Blank lines before returns.
 * adis16209 (staging cleanup)
   - Headers in alphabetical order
   - Change some definition names to make them more meaningful (2 rounds
     of this).
   - Add explicit _REG prefix to register names to make them
     obviously different from fields within those registers.
   - Remove some superflous comments and group definitions better.
   - Use a switch statement to make it semantically obvious that we
     only have two options (rather than an unlimited 'else').
   - Use sign_extent32 instead of open coding.
 * adt7316 (staging cleanup)
   - Move an export next to symbol.
 * bmc150
   - drop redundant __func__ in dynamic debug.
 * ccs811
   - Rename varaible to better reflect what it does.
 * cros_ec
   - Reduce sampling frequency before suspending to avoid preventing
     suspend.
 * dummy
   - Correct whitespace in Kconfig.
   - Add extra description in Kconfig.
 * ds1803
   - Remove a VLA which we always know is 2 long.
 * hid-sensor-accel
   - Replace magic number 0 by IIO_CHAN_INFO_RAW.
 * hid-sensor-gyro
   - Replace magic number 0 by IIO_CHAN_INFO_RAW.
 * hid-sensor-light
   - Replace magic number 0 by IIO_CHAN_INFO_RAW.
 * hid-sensor-magn
   - Replace magic number 0 by IIO_CHAN_INFO_RAW.
 * lm3533
   - Replace magic number 0 by IIO_CHAN_INFO_RAW
 * mlx90632
   - Squash a smatch warning - no runtime effect.
 * stm32_dfsdm:
   - Cleanup the dt bindings.
 * sx9500
   - Add GPIO ACPI mapping table to behave correctly when firmware
     doesn't provide the mapping.
 * tsl2x7x (staging cleanup)
   - Fix the proximity sensor functionality.
   - Remove platform data provided power functions.  There are much
     better ways to do this these days.
   - Introduce some common functions to avoid various repititions.
   - Stop using mutex_trylock when mutex_lock and wait a bit is fine.
   - Improve error handling in various places.
   - Drop some 'Camel case' (which wasn't actually strickly camel case
     but was a bit odd.
   - Drop some _available sysfs attributes for things that don't exist
     (for particular supported parts).
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAlqlObQRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FoissQ/+IQjcyxNdtOhHagvRgZ5z+6GYj6JzIX8s
 Qqnep34sc6yUaygbJBXdcBQ5qdnPjrTk2CD3VYANOdC1bqXa80yuTGCGN6lBIBEr
 /qBso6UbUiobA1PXektUj7Qel5HfVfYCyQ4NssSwKbdza6pyqoZA+iPzwiztWAwE
 JsU5EdsTVxB/39kMOnoQJM6l5Lc5Ljg5pS3Du++3U49neiDk1Z/+VXsimFSPK3zt
 FrSmMehNRYr0iFPwi7IZf8beG5ixmpRyY+KZzdM45Gm4hrpgE9ZIMd7A8B+ypx5N
 WM1HJxu3PC6xHc7DIbcJG82sQ9DDrIeCkN4wN29ESE0JUt/GPvySSFZRAhsVp+xO
 8rObv0r9Va+ones5WhZeAx/x3FowommZ2Jn+0FpX5H0X0mgi34au4YiOOAhg2gz5
 9fnj39k7WarYozn1VVY8D8copO6C7j/UQVup/qfjmufkc7bDrQMml3rBWZbNxSUC
 0TfZZJ9k+bxw2fvIedrjU/CFYbJJSpkRF/Sm3TZW28OMpxt/3qmAECtREOXVLyl2
 cJnJpw8ERWbyeHJxhULurc2ekJVFeOS1sZ+sWU7P0LFt+J3dkOgZP1GJpXXhCWQa
 GmgIm7vYYtAsVjDZ+FwH4ir/wSUeufscFEHs1oVhmIRh7jRCaJWycgLKZcK+rVRK
 docrwE4wGrk=
 =6eOr
 -----END PGP SIGNATURE-----

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

Jonathan writes:

Second set of new device support, features and cleanup for IIO in the 4.17 cycle

The uptick in staging cleanup is partly due to GSoC Applications
process being underway and one of Daniel's tasks being to try
cleaning up an IIO driver to move out of staging.
Naturally there is some normal staging cleanup progress in here
as well.

New device support
* Microchip mcp4018
  - New driver supproting MCP4017, MCP4018 and MCP4019 digital pots.
* On Semiconductor lv0104cs
  - New driver to support this ambient light sensor.

Cleanup
* axp20x_adc
  - remove a !! in favour of clear ternary operator.
* ad2s1210 (staging cleanup)
  - Reorganise to avoid ending a line with [
  - Remove some unnecessary defines.
  - Remove unsed variable.
* ad5380
  - Replace magic 0 with IIO_CHAN_INFO_RAW
* ad5764
  - Replace magic 0 with IIO_CHA_INFO_RAW
* ad7150 (staging cleanup)
  - Align arguements with parenthesis.
* ad7152 (staging cleanup)
  - Align arguements.
* ad7746 (staging cleanup)
  - Align arguements.
* ad7816
  - Remove pointless void pointer cast.
* ade7753
  - Replace IIO_DEV_ATTR_CH_OFF with equivalent to avoid confusing
    checkpatch (this macro didn't really help anyway).  Also drop the
    macro from the meter.h header.
* ade7754 (staging cleanup)
  - Add names to funciton definition arguements.
  - Align arguements with open parenthesis where possible.
* ade7758 (staging cleanup)
  - Remove __func__ from dev_dbg statements as provided by dynamic
    debug anyway.
  - Align arguements with open parenthesis where possible.
* ade7759 (staging cleanup)
  - Replace IIO_DEV_ATTR_CH_OFF with equiavalent to avoid confusing
    checkpatch.
* adis16201 (staging cleanup)
  - Headers in alphabetical order.
  - Blank lines before returns.
* adis16209 (staging cleanup)
  - Headers in alphabetical order
  - Change some definition names to make them more meaningful (2 rounds
    of this).
  - Add explicit _REG prefix to register names to make them
    obviously different from fields within those registers.
  - Remove some superflous comments and group definitions better.
  - Use a switch statement to make it semantically obvious that we
    only have two options (rather than an unlimited 'else').
  - Use sign_extent32 instead of open coding.
* adt7316 (staging cleanup)
  - Move an export next to symbol.
* bmc150
  - drop redundant __func__ in dynamic debug.
* ccs811
  - Rename varaible to better reflect what it does.
* cros_ec
  - Reduce sampling frequency before suspending to avoid preventing
    suspend.
* dummy
  - Correct whitespace in Kconfig.
  - Add extra description in Kconfig.
* ds1803
  - Remove a VLA which we always know is 2 long.
* hid-sensor-accel
  - Replace magic number 0 by IIO_CHAN_INFO_RAW.
* hid-sensor-gyro
  - Replace magic number 0 by IIO_CHAN_INFO_RAW.
* hid-sensor-light
  - Replace magic number 0 by IIO_CHAN_INFO_RAW.
* hid-sensor-magn
  - Replace magic number 0 by IIO_CHAN_INFO_RAW.
* lm3533
  - Replace magic number 0 by IIO_CHAN_INFO_RAW
* mlx90632
  - Squash a smatch warning - no runtime effect.
* stm32_dfsdm:
  - Cleanup the dt bindings.
* sx9500
  - Add GPIO ACPI mapping table to behave correctly when firmware
    doesn't provide the mapping.
* tsl2x7x (staging cleanup)
  - Fix the proximity sensor functionality.
  - Remove platform data provided power functions.  There are much
    better ways to do this these days.
  - Introduce some common functions to avoid various repititions.
  - Stop using mutex_trylock when mutex_lock and wait a bit is fine.
  - Improve error handling in various places.
  - Drop some 'Camel case' (which wasn't actually strickly camel case
    but was a bit odd.
  - Drop some _available sysfs attributes for things that don't exist
    (for particular supported parts).
This commit is contained in:
Greg Kroah-Hartman 2018-03-14 12:32:11 +01:00
commit 6761f0ac66
44 changed files with 1233 additions and 458 deletions

View File

@ -32,6 +32,10 @@ Optional properties:
to "clock" property. Frequency must be a multiple of the rcc to "clock" property. Frequency must be a multiple of the rcc
clock frequency. If not, SPI CLKOUT frequency will not be clock frequency. If not, SPI CLKOUT frequency will not be
accurate. accurate.
- pinctrl-names: Set to "default".
- pinctrl-0: List of phandles pointing to pin configuration
nodes to set pins in mode of operation for dfsdm
on external pin.
Contents of a STM32 DFSDM child nodes: Contents of a STM32 DFSDM child nodes:
-------------------------------------- --------------------------------------
@ -68,8 +72,8 @@ Optional properties:
- st,adc-channel-types: Single-ended channel input type. - st,adc-channel-types: Single-ended channel input type.
- "SPI_R": SPI with data on rising edge (default) - "SPI_R": SPI with data on rising edge (default)
- "SPI_F": SPI with data on falling edge - "SPI_F": SPI with data on falling edge
- "MANCH_R": manchester codec, rising edge = logic 0 - "MANCH_R": manchester codec, rising edge = logic 0, falling edge = logic 1
- "MANCH_F": manchester codec, falling edge = logic 1 - "MANCH_F": manchester codec, rising edge = logic 1, falling edge = logic 0
- st,adc-channel-clk-src: Conversion clock source. - st,adc-channel-clk-src: Conversion clock source.
- "CLKIN": external SPI clock (CLKIN x) - "CLKIN": external SPI clock (CLKIN x)
- "CLKOUT": internal SPI clock (CLKOUT) (default) - "CLKOUT": internal SPI clock (CLKOUT) (default)

View File

@ -8585,11 +8585,12 @@ W: https://linuxtv.org
S: Maintained S: Maintained
F: drivers/media/radio/radio-maxiradio* F: drivers/media/radio/radio-maxiradio*
MCP4531 MICROCHIP DIGITAL POTENTIOMETER DRIVER MCP4018 AND MCP4531 MICROCHIP DIGITAL POTENTIOMETER DRIVERS
M: Peter Rosin <peda@axentia.se> M: Peter Rosin <peda@axentia.se>
L: linux-iio@vger.kernel.org L: linux-iio@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531 F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531
F: drivers/iio/potentiometer/mcp4018.c
F: drivers/iio/potentiometer/mcp4531.c F: drivers/iio/potentiometer/mcp4531.c
MEASUREMENT COMPUTING CIO-DAC IIO DRIVER MEASUREMENT COMPUTING CIO-DAC IIO DRIVER

View File

@ -336,8 +336,7 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
return ret; return ret;
} }
dev_dbg(dev, "%s: %x %x\n", __func__, data->slope_thres, dev_dbg(dev, "%x %x\n", data->slope_thres, data->slope_dur);
data->slope_dur);
return ret; return ret;
} }
@ -1716,7 +1715,6 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
struct bmc150_accel_data *data = iio_priv(indio_dev); struct bmc150_accel_data *data = iio_priv(indio_dev);
int ret; int ret;
dev_dbg(dev, __func__);
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0); ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
if (ret < 0) if (ret < 0)
return -EAGAIN; return -EAGAIN;
@ -1731,8 +1729,6 @@ static int bmc150_accel_runtime_resume(struct device *dev)
int ret; int ret;
int sleep_val; int sleep_val;
dev_dbg(dev, __func__);
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -155,7 +155,7 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
*val = 0; *val = 0;
*val2 = 0; *val2 = 0;
switch (mask) { switch (mask) {
case 0: case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&accel_state->common_attributes, true); hid_sensor_power_state(&accel_state->common_attributes, true);
report_id = accel_state->accel[chan->scan_index].report_id; report_id = accel_state->accel[chan->scan_index].report_id;
address = accel_3d_addresses[chan->scan_index]; address = accel_3d_addresses[chan->scan_index];

View File

@ -445,7 +445,7 @@ static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,
return -EINVAL; return -EINVAL;
} }
*val = !!(*val) * 700000; *val = *val ? 700000 : 0;
return IIO_VAL_INT; return IIO_VAL_INT;
} }
@ -542,15 +542,17 @@ static int axp20x_write_raw(struct iio_dev *indio_dev,
if (val != 0 && val != 700000) if (val != 0 && val != 700000)
return -EINVAL; return -EINVAL;
val = val ? 1 : 0;
switch (chan->channel) { switch (chan->channel) {
case AXP20X_GPIO0_V: case AXP20X_GPIO0_V:
reg = AXP20X_GPIO10_IN_RANGE_GPIO0; reg = AXP20X_GPIO10_IN_RANGE_GPIO0;
regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val); regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(val);
break; break;
case AXP20X_GPIO1_V: case AXP20X_GPIO1_V:
reg = AXP20X_GPIO10_IN_RANGE_GPIO1; reg = AXP20X_GPIO10_IN_RANGE_GPIO1;
regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val); regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(val);
break; break;
default: default:

View File

@ -69,7 +69,7 @@ struct ccs811_reading {
__be16 voc; __be16 voc;
u8 status; u8 status;
u8 error; u8 error;
__be16 resistance; __be16 raw_data;
} __attribute__((__packed__)); } __attribute__((__packed__));
struct ccs811_data { struct ccs811_data {
@ -210,12 +210,12 @@ static int ccs811_read_raw(struct iio_dev *indio_dev,
switch (chan->type) { switch (chan->type) {
case IIO_VOLTAGE: case IIO_VOLTAGE:
*val = be16_to_cpu(data->buffer.resistance) & *val = be16_to_cpu(data->buffer.raw_data) &
CCS811_VOLTAGE_MASK; CCS811_VOLTAGE_MASK;
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
break; break;
case IIO_CURRENT: case IIO_CURRENT:
*val = be16_to_cpu(data->buffer.resistance) >> 10; *val = be16_to_cpu(data->buffer.raw_data) >> 10;
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
break; break;
case IIO_CONCENTRATION: case IIO_CONCENTRATION:

View File

@ -289,6 +289,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_sensors_ids);
static struct platform_driver cros_ec_sensors_platform_driver = { static struct platform_driver cros_ec_sensors_platform_driver = {
.driver = { .driver = {
.name = "cros-ec-sensors", .name = "cros-ec-sensors",
.pm = &cros_ec_sensors_pm_ops,
}, },
.probe = cros_ec_sensors_probe, .probe = cros_ec_sensors_probe,
.id_table = cros_ec_sensors_ids, .id_table = cros_ec_sensors_ids,

View File

@ -446,5 +446,54 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
} }
EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write); EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write);
static int __maybe_unused cros_ec_sensors_prepare(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
if (st->curr_sampl_freq == 0)
return 0;
/*
* If the sensors are sampled at high frequency, we will not be able to
* sleep. Set sampling to a long period if necessary.
*/
if (st->curr_sampl_freq < CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY) {
mutex_lock(&st->cmd_lock);
st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
st->param.ec_rate.data = CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY;
cros_ec_motion_send_host_cmd(st, 0);
mutex_unlock(&st->cmd_lock);
}
return 0;
}
static void __maybe_unused cros_ec_sensors_complete(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
if (st->curr_sampl_freq == 0)
return;
if (st->curr_sampl_freq < CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY) {
mutex_lock(&st->cmd_lock);
st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
st->param.ec_rate.data = st->curr_sampl_freq;
cros_ec_motion_send_host_cmd(st, 0);
mutex_unlock(&st->cmd_lock);
}
}
const struct dev_pm_ops cros_ec_sensors_pm_ops = {
#ifdef CONFIG_PM_SLEEP
.prepare = cros_ec_sensors_prepare,
.complete = cros_ec_sensors_complete
#endif
};
EXPORT_SYMBOL_GPL(cros_ec_sensors_pm_ops);
MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions"); MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -169,6 +169,8 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
int val, int val2, long mask); int val, int val2, long mask);
extern const struct dev_pm_ops cros_ec_sensors_pm_ops;
/* List of extended channel specification for all sensors */ /* List of extended channel specification for all sensors */
extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[]; extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];

View File

@ -158,7 +158,7 @@ static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan,
long info) long info)
{ {
switch (info) { switch (info) {
case 0: case IIO_CHAN_INFO_RAW:
return AD5380_REG_DATA(chan->address); return AD5380_REG_DATA(chan->address);
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
return AD5380_REG_OFFSET(chan->address); return AD5380_REG_OFFSET(chan->address);

View File

@ -168,7 +168,7 @@ static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg,
static int ad5764_chan_info_to_reg(struct iio_chan_spec const *chan, long info) static int ad5764_chan_info_to_reg(struct iio_chan_spec const *chan, long info)
{ {
switch (info) { switch (info) {
case 0: case IIO_CHAN_INFO_RAW:
return AD5764_REG_DATA(chan->address); return AD5764_REG_DATA(chan->address);
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
return AD5764_REG_OFFSET(chan->address); return AD5764_REG_OFFSET(chan->address);

View File

@ -9,20 +9,24 @@ config IIO_DUMMY_EVGEN
tristate tristate
config IIO_SIMPLE_DUMMY config IIO_SIMPLE_DUMMY
tristate "An example driver with no hardware requirements" tristate "An example driver with no hardware requirements"
depends on IIO_SW_DEVICE depends on IIO_SW_DEVICE
help help
Driver intended mainly as documentation for how to write Driver intended mainly as documentation for how to write
a driver. May also be useful for testing userspace code a driver. May also be useful for testing userspace code
without hardware. without hardware.
if IIO_SIMPLE_DUMMY if IIO_SIMPLE_DUMMY
config IIO_SIMPLE_DUMMY_EVENTS config IIO_SIMPLE_DUMMY_EVENTS
bool "Event generation support" bool "Event generation support"
select IIO_DUMMY_EVGEN select IIO_DUMMY_EVGEN
help help
Add some dummy events to the simple dummy driver. Add some dummy events to the simple dummy driver.
The purpose of this is to generate 'fake' event interrupts thus
allowing that driver's code to be as close as possible to that
a normal driver talking to hardware.
config IIO_SIMPLE_DUMMY_BUFFER config IIO_SIMPLE_DUMMY_BUFFER
bool "Buffered capture support" bool "Buffered capture support"
@ -32,6 +36,9 @@ config IIO_SIMPLE_DUMMY_BUFFER
help help
Add buffered data capture to the simple dummy driver. Add buffered data capture to the simple dummy driver.
Buffer handling elements of industrial I/O reference driver.
Uses the kfifo buffer.
endif # IIO_SIMPLE_DUMMY endif # IIO_SIMPLE_DUMMY
endmenu endmenu

View File

@ -115,7 +115,7 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
*val = 0; *val = 0;
*val2 = 0; *val2 = 0;
switch (mask) { switch (mask) {
case 0: case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&gyro_state->common_attributes, true); hid_sensor_power_state(&gyro_state->common_attributes, true);
report_id = gyro_state->gyro[chan->scan_index].report_id; report_id = gyro_state->gyro[chan->scan_index].report_id;
address = gyro_3d_addresses[chan->scan_index]; address = gyro_3d_addresses[chan->scan_index];

View File

@ -275,6 +275,16 @@ config LTR501
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called ltr501. will be called ltr501.
config LV0104CS
tristate "LV0104CS Ambient Light Sensor"
depends on I2C
help
Say Y here if you want to build support for the On Semiconductor
LV0104CS ambient light sensor.
To compile this driver as a module, choose M here:
the module will be called lv0104cs.
config MAX44000 config MAX44000
tristate "MAX44000 Ambient and Infrared Proximity Sensor" tristate "MAX44000 Ambient and Infrared Proximity Sensor"
depends on I2C depends on I2C

View File

@ -26,6 +26,7 @@ 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
obj-$(CONFIG_LTR501) += ltr501.o obj-$(CONFIG_LTR501) += ltr501.o
obj-$(CONFIG_LV0104CS) += lv0104cs.o
obj-$(CONFIG_MAX44000) += max44000.o obj-$(CONFIG_MAX44000) += max44000.o
obj-$(CONFIG_OPT3001) += opt3001.o obj-$(CONFIG_OPT3001) += opt3001.o
obj-$(CONFIG_PA12203001) += pa12203001.o obj-$(CONFIG_PA12203001) += pa12203001.o

View File

@ -276,6 +276,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_light_prox_ids);
static struct platform_driver cros_ec_light_prox_platform_driver = { static struct platform_driver cros_ec_light_prox_platform_driver = {
.driver = { .driver = {
.name = "cros-ec-light-prox", .name = "cros-ec-light-prox",
.pm = &cros_ec_sensors_pm_ops,
}, },
.probe = cros_ec_light_prox_probe, .probe = cros_ec_light_prox_probe,
.id_table = cros_ec_light_prox_ids, .id_table = cros_ec_light_prox_ids,

View File

@ -97,7 +97,7 @@ static int als_read_raw(struct iio_dev *indio_dev,
*val = 0; *val = 0;
*val2 = 0; *val2 = 0;
switch (mask) { switch (mask) {
case 0: case IIO_CHAN_INFO_RAW:
switch (chan->scan_index) { switch (chan->scan_index) {
case CHANNEL_SCAN_INDEX_INTENSITY: case CHANNEL_SCAN_INDEX_INTENSITY:
case CHANNEL_SCAN_INDEX_ILLUM: case CHANNEL_SCAN_INDEX_ILLUM:

View File

@ -199,7 +199,7 @@ static int lm3533_als_read_raw(struct iio_dev *indio_dev,
int ret; int ret;
switch (mask) { switch (mask) {
case 0: case IIO_CHAN_INFO_RAW:
switch (chan->type) { switch (chan->type) {
case IIO_LIGHT: case IIO_LIGHT:
ret = lm3533_als_get_adc(indio_dev, false, val); ret = lm3533_als_get_adc(indio_dev, false, val);

View File

@ -0,0 +1,531 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* lv0104cs.c: LV0104CS Ambient Light Sensor Driver
*
* Copyright (C) 2018
* Author: Jeff LaBundy <jeff@labundy.com>
*
* 7-bit I2C slave address: 0x13
*
* Link to data sheet: http://www.onsemi.com/pub/Collateral/LV0104CS-D.PDF
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define LV0104CS_REGVAL_MEASURE 0xE0
#define LV0104CS_REGVAL_SLEEP 0x00
#define LV0104CS_SCALE_0_25X 0
#define LV0104CS_SCALE_1X 1
#define LV0104CS_SCALE_2X 2
#define LV0104CS_SCALE_8X 3
#define LV0104CS_SCALE_SHIFT 3
#define LV0104CS_INTEG_12_5MS 0
#define LV0104CS_INTEG_100MS 1
#define LV0104CS_INTEG_200MS 2
#define LV0104CS_INTEG_SHIFT 1
#define LV0104CS_CALIBSCALE_UNITY 31
struct lv0104cs_private {
struct i2c_client *client;
struct mutex lock;
u8 calibscale;
u8 scale;
u8 int_time;
};
struct lv0104cs_mapping {
int val;
int val2;
u8 regval;
};
static const struct lv0104cs_mapping lv0104cs_calibscales[] = {
{ 0, 666666, 0x81 },
{ 0, 800000, 0x82 },
{ 0, 857142, 0x83 },
{ 0, 888888, 0x84 },
{ 0, 909090, 0x85 },
{ 0, 923076, 0x86 },
{ 0, 933333, 0x87 },
{ 0, 941176, 0x88 },
{ 0, 947368, 0x89 },
{ 0, 952380, 0x8A },
{ 0, 956521, 0x8B },
{ 0, 960000, 0x8C },
{ 0, 962962, 0x8D },
{ 0, 965517, 0x8E },
{ 0, 967741, 0x8F },
{ 0, 969696, 0x90 },
{ 0, 971428, 0x91 },
{ 0, 972972, 0x92 },
{ 0, 974358, 0x93 },
{ 0, 975609, 0x94 },
{ 0, 976744, 0x95 },
{ 0, 977777, 0x96 },
{ 0, 978723, 0x97 },
{ 0, 979591, 0x98 },
{ 0, 980392, 0x99 },
{ 0, 981132, 0x9A },
{ 0, 981818, 0x9B },
{ 0, 982456, 0x9C },
{ 0, 983050, 0x9D },
{ 0, 983606, 0x9E },
{ 0, 984126, 0x9F },
{ 1, 0, 0x80 },
{ 1, 16129, 0xBF },
{ 1, 16666, 0xBE },
{ 1, 17241, 0xBD },
{ 1, 17857, 0xBC },
{ 1, 18518, 0xBB },
{ 1, 19230, 0xBA },
{ 1, 20000, 0xB9 },
{ 1, 20833, 0xB8 },
{ 1, 21739, 0xB7 },
{ 1, 22727, 0xB6 },
{ 1, 23809, 0xB5 },
{ 1, 24999, 0xB4 },
{ 1, 26315, 0xB3 },
{ 1, 27777, 0xB2 },
{ 1, 29411, 0xB1 },
{ 1, 31250, 0xB0 },
{ 1, 33333, 0xAF },
{ 1, 35714, 0xAE },
{ 1, 38461, 0xAD },
{ 1, 41666, 0xAC },
{ 1, 45454, 0xAB },
{ 1, 50000, 0xAA },
{ 1, 55555, 0xA9 },
{ 1, 62500, 0xA8 },
{ 1, 71428, 0xA7 },
{ 1, 83333, 0xA6 },
{ 1, 100000, 0xA5 },
{ 1, 125000, 0xA4 },
{ 1, 166666, 0xA3 },
{ 1, 250000, 0xA2 },
{ 1, 500000, 0xA1 },
};
static const struct lv0104cs_mapping lv0104cs_scales[] = {
{ 0, 250000, LV0104CS_SCALE_0_25X << LV0104CS_SCALE_SHIFT },
{ 1, 0, LV0104CS_SCALE_1X << LV0104CS_SCALE_SHIFT },
{ 2, 0, LV0104CS_SCALE_2X << LV0104CS_SCALE_SHIFT },
{ 8, 0, LV0104CS_SCALE_8X << LV0104CS_SCALE_SHIFT },
};
static const struct lv0104cs_mapping lv0104cs_int_times[] = {
{ 0, 12500, LV0104CS_INTEG_12_5MS << LV0104CS_INTEG_SHIFT },
{ 0, 100000, LV0104CS_INTEG_100MS << LV0104CS_INTEG_SHIFT },
{ 0, 200000, LV0104CS_INTEG_200MS << LV0104CS_INTEG_SHIFT },
};
static int lv0104cs_write_reg(struct i2c_client *client, u8 regval)
{
int ret;
ret = i2c_master_send(client, (char *)&regval, sizeof(regval));
if (ret < 0)
return ret;
if (ret != sizeof(regval))
return -EIO;
return 0;
}
static int lv0104cs_read_adc(struct i2c_client *client, u16 *adc_output)
{
__be16 regval;
int ret;
ret = i2c_master_recv(client, (char *)&regval, sizeof(regval));
if (ret < 0)
return ret;
if (ret != sizeof(regval))
return -EIO;
*adc_output = be16_to_cpu(regval);
return 0;
}
static int lv0104cs_get_lux(struct lv0104cs_private *lv0104cs,
int *val, int *val2)
{
u8 regval = LV0104CS_REGVAL_MEASURE;
u16 adc_output;
int ret;
regval |= lv0104cs_scales[lv0104cs->scale].regval;
regval |= lv0104cs_int_times[lv0104cs->int_time].regval;
ret = lv0104cs_write_reg(lv0104cs->client, regval);
if (ret)
return ret;
/* wait for integration time to pass (with margin) */
switch (lv0104cs->int_time) {
case LV0104CS_INTEG_12_5MS:
msleep(50);
break;
case LV0104CS_INTEG_100MS:
msleep(150);
break;
case LV0104CS_INTEG_200MS:
msleep(250);
break;
default:
return -EINVAL;
}
ret = lv0104cs_read_adc(lv0104cs->client, &adc_output);
if (ret)
return ret;
ret = lv0104cs_write_reg(lv0104cs->client, LV0104CS_REGVAL_SLEEP);
if (ret)
return ret;
/* convert ADC output to lux */
switch (lv0104cs->scale) {
case LV0104CS_SCALE_0_25X:
*val = adc_output * 4;
*val2 = 0;
return 0;
case LV0104CS_SCALE_1X:
*val = adc_output;
*val2 = 0;
return 0;
case LV0104CS_SCALE_2X:
*val = adc_output / 2;
*val2 = (adc_output % 2) * 500000;
return 0;
case LV0104CS_SCALE_8X:
*val = adc_output / 8;
*val2 = (adc_output % 8) * 125000;
return 0;
default:
return -EINVAL;
}
}
static int lv0104cs_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct lv0104cs_private *lv0104cs = iio_priv(indio_dev);
int ret;
if (chan->type != IIO_LIGHT)
return -EINVAL;
mutex_lock(&lv0104cs->lock);
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
ret = lv0104cs_get_lux(lv0104cs, val, val2);
if (ret)
goto err_mutex;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_CALIBSCALE:
*val = lv0104cs_calibscales[lv0104cs->calibscale].val;
*val2 = lv0104cs_calibscales[lv0104cs->calibscale].val2;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_SCALE:
*val = lv0104cs_scales[lv0104cs->scale].val;
*val2 = lv0104cs_scales[lv0104cs->scale].val2;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_INT_TIME:
*val = lv0104cs_int_times[lv0104cs->int_time].val;
*val2 = lv0104cs_int_times[lv0104cs->int_time].val2;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret = -EINVAL;
}
err_mutex:
mutex_unlock(&lv0104cs->lock);
return ret;
}
static int lv0104cs_set_calibscale(struct lv0104cs_private *lv0104cs,
int val, int val2)
{
int calibscale = val * 1000000 + val2;
int floor, ceil, mid;
int ret, i, index;
/* round to nearest quantized calibscale (sensitivity) */
for (i = 0; i < ARRAY_SIZE(lv0104cs_calibscales) - 1; i++) {
floor = lv0104cs_calibscales[i].val * 1000000
+ lv0104cs_calibscales[i].val2;
ceil = lv0104cs_calibscales[i + 1].val * 1000000
+ lv0104cs_calibscales[i + 1].val2;
mid = (floor + ceil) / 2;
/* round down */
if (calibscale >= floor && calibscale < mid) {
index = i;
break;
}
/* round up */
if (calibscale >= mid && calibscale <= ceil) {
index = i + 1;
break;
}
}
if (i == ARRAY_SIZE(lv0104cs_calibscales) - 1)
return -EINVAL;
mutex_lock(&lv0104cs->lock);
/* set calibscale (sensitivity) */
ret = lv0104cs_write_reg(lv0104cs->client,
lv0104cs_calibscales[index].regval);
if (ret)
goto err_mutex;
lv0104cs->calibscale = index;
err_mutex:
mutex_unlock(&lv0104cs->lock);
return ret;
}
static int lv0104cs_set_scale(struct lv0104cs_private *lv0104cs,
int val, int val2)
{
int i;
/* hard matching */
for (i = 0; i < ARRAY_SIZE(lv0104cs_scales); i++) {
if (val != lv0104cs_scales[i].val)
continue;
if (val2 == lv0104cs_scales[i].val2)
break;
}
if (i == ARRAY_SIZE(lv0104cs_scales))
return -EINVAL;
mutex_lock(&lv0104cs->lock);
lv0104cs->scale = i;
mutex_unlock(&lv0104cs->lock);
return 0;
}
static int lv0104cs_set_int_time(struct lv0104cs_private *lv0104cs,
int val, int val2)
{
int i;
/* hard matching */
for (i = 0; i < ARRAY_SIZE(lv0104cs_int_times); i++) {
if (val != lv0104cs_int_times[i].val)
continue;
if (val2 == lv0104cs_int_times[i].val2)
break;
}
if (i == ARRAY_SIZE(lv0104cs_int_times))
return -EINVAL;
mutex_lock(&lv0104cs->lock);
lv0104cs->int_time = i;
mutex_unlock(&lv0104cs->lock);
return 0;
}
static int lv0104cs_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct lv0104cs_private *lv0104cs = iio_priv(indio_dev);
if (chan->type != IIO_LIGHT)
return -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_CALIBSCALE:
return lv0104cs_set_calibscale(lv0104cs, val, val2);
case IIO_CHAN_INFO_SCALE:
return lv0104cs_set_scale(lv0104cs, val, val2);
case IIO_CHAN_INFO_INT_TIME:
return lv0104cs_set_int_time(lv0104cs, val, val2);
default:
return -EINVAL;
}
}
static ssize_t lv0104cs_show_calibscale_avail(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t len = 0;
int i;
for (i = 0; i < ARRAY_SIZE(lv0104cs_calibscales); i++) {
len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
lv0104cs_calibscales[i].val,
lv0104cs_calibscales[i].val2);
}
buf[len - 1] = '\n';
return len;
}
static ssize_t lv0104cs_show_scale_avail(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t len = 0;
int i;
for (i = 0; i < ARRAY_SIZE(lv0104cs_scales); i++) {
len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
lv0104cs_scales[i].val,
lv0104cs_scales[i].val2);
}
buf[len - 1] = '\n';
return len;
}
static ssize_t lv0104cs_show_int_time_avail(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t len = 0;
int i;
for (i = 0; i < ARRAY_SIZE(lv0104cs_int_times); i++) {
len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
lv0104cs_int_times[i].val,
lv0104cs_int_times[i].val2);
}
buf[len - 1] = '\n';
return len;
}
static IIO_DEVICE_ATTR(calibscale_available, 0444,
lv0104cs_show_calibscale_avail, NULL, 0);
static IIO_DEVICE_ATTR(scale_available, 0444,
lv0104cs_show_scale_avail, NULL, 0);
static IIO_DEV_ATTR_INT_TIME_AVAIL(lv0104cs_show_int_time_avail);
static struct attribute *lv0104cs_attributes[] = {
&iio_dev_attr_calibscale_available.dev_attr.attr,
&iio_dev_attr_scale_available.dev_attr.attr,
&iio_dev_attr_integration_time_available.dev_attr.attr,
NULL
};
static const struct attribute_group lv0104cs_attribute_group = {
.attrs = lv0104cs_attributes,
};
static const struct iio_info lv0104cs_info = {
.attrs = &lv0104cs_attribute_group,
.read_raw = &lv0104cs_read_raw,
.write_raw = &lv0104cs_write_raw,
};
static const struct iio_chan_spec lv0104cs_channels[] = {
{
.type = IIO_LIGHT,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_INT_TIME),
},
};
static int lv0104cs_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct lv0104cs_private *lv0104cs;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*lv0104cs));
if (!indio_dev)
return -ENOMEM;
lv0104cs = iio_priv(indio_dev);
i2c_set_clientdata(client, lv0104cs);
lv0104cs->client = client;
mutex_init(&lv0104cs->lock);
lv0104cs->calibscale = LV0104CS_CALIBSCALE_UNITY;
lv0104cs->scale = LV0104CS_SCALE_1X;
lv0104cs->int_time = LV0104CS_INTEG_200MS;
ret = lv0104cs_write_reg(lv0104cs->client,
lv0104cs_calibscales[LV0104CS_CALIBSCALE_UNITY].regval);
if (ret)
return ret;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->dev.parent = &client->dev;
indio_dev->channels = lv0104cs_channels;
indio_dev->num_channels = ARRAY_SIZE(lv0104cs_channels);
indio_dev->name = client->name;
indio_dev->info = &lv0104cs_info;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id lv0104cs_id[] = {
{ "lv0104cs", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lv0104cs_id);
static struct i2c_driver lv0104cs_i2c_driver = {
.driver = {
.name = "lv0104cs",
},
.id_table = lv0104cs_id,
.probe = lv0104cs_probe,
};
module_i2c_driver(lv0104cs_i2c_driver);
MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
MODULE_DESCRIPTION("LV0104CS Ambient Light Sensor Driver");
MODULE_LICENSE("GPL");

View File

@ -167,7 +167,7 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
*val = 0; *val = 0;
*val2 = 0; *val2 = 0;
switch (mask) { switch (mask) {
case 0: case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&magn_state->magn_flux_attributes, true); hid_sensor_power_state(&magn_state->magn_flux_attributes, true);
report_id = report_id =
magn_state->magn[chan->address].report_id; magn_state->magn[chan->address].report_id;

View File

@ -47,6 +47,17 @@ config MAX5487
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 max5487. module will be called max5487.
config MCP4018
tristate "Microchip MCP4017/18/19 Digital Potentiometer driver"
depends on I2C
help
Say yes here to build support for the Microchip
MCP4017, MCP4018, MCP4019
digital potentiometer chips.
To compile this driver as a module, choose M here: the
module will be called mcp4018.
config MCP4131 config MCP4131
tristate "Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X Digital Potentiometer driver" tristate "Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X Digital Potentiometer driver"
depends on SPI depends on SPI

View File

@ -8,6 +8,7 @@ obj-$(CONFIG_AD5272) += ad5272.o
obj-$(CONFIG_DS1803) += ds1803.o obj-$(CONFIG_DS1803) += ds1803.o
obj-$(CONFIG_MAX5481) += max5481.o obj-$(CONFIG_MAX5481) += max5481.o
obj-$(CONFIG_MAX5487) += max5487.o obj-$(CONFIG_MAX5487) += max5487.o
obj-$(CONFIG_MCP4018) += mcp4018.o
obj-$(CONFIG_MCP4131) += mcp4131.o obj-$(CONFIG_MCP4131) += mcp4131.o
obj-$(CONFIG_MCP4531) += mcp4531.o obj-$(CONFIG_MCP4531) += mcp4531.o
obj-$(CONFIG_TPL0102) += tpl0102.o obj-$(CONFIG_TPL0102) += tpl0102.o

View File

@ -64,7 +64,7 @@ static int ds1803_read_raw(struct iio_dev *indio_dev,
struct ds1803_data *data = iio_priv(indio_dev); struct ds1803_data *data = iio_priv(indio_dev);
int pot = chan->channel; int pot = chan->channel;
int ret; int ret;
u8 result[indio_dev->num_channels]; u8 result[ARRAY_SIZE(ds1803_channels)];
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:

View File

@ -0,0 +1,194 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Industrial I/O driver for Microchip digital potentiometers
* Copyright (c) 2018 Axentia Technologies AB
* Author: Peter Rosin <peda@axentia.se>
*
* Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22147a.pdf
*
* DEVID #Wipers #Positions Resistor Opts (kOhm)
* mcp4017 1 128 5, 10, 50, 100
* mcp4018 1 128 5, 10, 50, 100
* mcp4019 1 128 5, 10, 50, 100
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#define MCP4018_WIPER_MAX 127
struct mcp4018_cfg {
int kohms;
};
enum mcp4018_type {
MCP4018_502,
MCP4018_103,
MCP4018_503,
MCP4018_104,
};
static const struct mcp4018_cfg mcp4018_cfg[] = {
[MCP4018_502] = { .kohms = 5, },
[MCP4018_103] = { .kohms = 10, },
[MCP4018_503] = { .kohms = 50, },
[MCP4018_104] = { .kohms = 100, },
};
struct mcp4018_data {
struct i2c_client *client;
const struct mcp4018_cfg *cfg;
};
static const struct iio_chan_spec mcp4018_channel = {
.type = IIO_RESISTANCE,
.indexed = 1,
.output = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
};
static int mcp4018_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct mcp4018_data *data = iio_priv(indio_dev);
s32 ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = i2c_smbus_read_byte(data->client);
if (ret < 0)
return ret;
*val = ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = 1000 * data->cfg->kohms;
*val2 = MCP4018_WIPER_MAX;
return IIO_VAL_FRACTIONAL;
}
return -EINVAL;
}
static int mcp4018_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct mcp4018_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (val > MCP4018_WIPER_MAX || val < 0)
return -EINVAL;
break;
default:
return -EINVAL;
}
return i2c_smbus_write_byte(data->client, val);
}
static const struct iio_info mcp4018_info = {
.read_raw = mcp4018_read_raw,
.write_raw = mcp4018_write_raw,
};
#ifdef CONFIG_OF
#define MCP4018_COMPATIBLE(of_compatible, cfg) { \
.compatible = of_compatible, \
.data = &mcp4018_cfg[cfg], \
}
static const struct of_device_id mcp4018_of_match[] = {
MCP4018_COMPATIBLE("microchip,mcp4017-502", MCP4018_502),
MCP4018_COMPATIBLE("microchip,mcp4017-103", MCP4018_103),
MCP4018_COMPATIBLE("microchip,mcp4017-503", MCP4018_503),
MCP4018_COMPATIBLE("microchip,mcp4017-104", MCP4018_104),
MCP4018_COMPATIBLE("microchip,mcp4018-502", MCP4018_502),
MCP4018_COMPATIBLE("microchip,mcp4018-103", MCP4018_103),
MCP4018_COMPATIBLE("microchip,mcp4018-503", MCP4018_503),
MCP4018_COMPATIBLE("microchip,mcp4018-104", MCP4018_104),
MCP4018_COMPATIBLE("microchip,mcp4019-502", MCP4018_502),
MCP4018_COMPATIBLE("microchip,mcp4019-103", MCP4018_103),
MCP4018_COMPATIBLE("microchip,mcp4019-503", MCP4018_503),
MCP4018_COMPATIBLE("microchip,mcp4019-104", MCP4018_104),
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mcp4018_of_match);
#endif
static int mcp4018_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct mcp4018_data *data;
struct iio_dev *indio_dev;
const struct of_device_id *match;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE)) {
dev_err(dev, "SMBUS Byte transfers not supported\n");
return -EOPNOTSUPP;
}
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
match = of_match_device(of_match_ptr(mcp4018_of_match), dev);
if (match)
data->cfg = of_device_get_match_data(dev);
else
data->cfg = &mcp4018_cfg[id->driver_data];
indio_dev->dev.parent = dev;
indio_dev->info = &mcp4018_info;
indio_dev->channels = &mcp4018_channel;
indio_dev->num_channels = 1;
indio_dev->name = client->name;
return devm_iio_device_register(dev, indio_dev);
}
static const struct i2c_device_id mcp4018_id[] = {
{ "mcp4017-502", MCP4018_502 },
{ "mcp4017-103", MCP4018_103 },
{ "mcp4017-503", MCP4018_503 },
{ "mcp4017-104", MCP4018_104 },
{ "mcp4018-502", MCP4018_502 },
{ "mcp4018-103", MCP4018_103 },
{ "mcp4018-503", MCP4018_503 },
{ "mcp4018-104", MCP4018_104 },
{ "mcp4019-502", MCP4018_502 },
{ "mcp4019-103", MCP4018_103 },
{ "mcp4019-503", MCP4018_503 },
{ "mcp4019-104", MCP4018_104 },
{}
};
MODULE_DEVICE_TABLE(i2c, mcp4018_id);
static struct i2c_driver mcp4018_driver = {
.driver = {
.name = "mcp4018",
.of_match_table = of_match_ptr(mcp4018_of_match),
},
.probe = mcp4018_probe,
.id_table = mcp4018_id,
};
module_i2c_driver(mcp4018_driver);
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_DESCRIPTION("MCP4018 digital potentiometer");
MODULE_LICENSE("GPL");

View File

@ -32,9 +32,6 @@
#define SX9500_DRIVER_NAME "sx9500" #define SX9500_DRIVER_NAME "sx9500"
#define SX9500_IRQ_NAME "sx9500_event" #define SX9500_IRQ_NAME "sx9500_event"
#define SX9500_GPIO_INT "interrupt"
#define SX9500_GPIO_RESET "reset"
/* Register definitions. */ /* Register definitions. */
#define SX9500_REG_IRQ_SRC 0x00 #define SX9500_REG_IRQ_SRC 0x00
#define SX9500_REG_STAT 0x01 #define SX9500_REG_STAT 0x01
@ -866,26 +863,44 @@ static int sx9500_init_device(struct iio_dev *indio_dev)
return sx9500_init_compensation(indio_dev); return sx9500_init_compensation(indio_dev);
} }
static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
static const struct acpi_gpio_params interrupt_gpios = { 2, 0, false };
static const struct acpi_gpio_mapping acpi_sx9500_gpios[] = {
{ "reset-gpios", &reset_gpios, 1 },
/*
* Some platforms have a bug in ACPI GPIO description making IRQ
* GPIO to be output only. Ask the GPIO core to ignore this limit.
*/
{ "interrupt-gpios", &interrupt_gpios, 1, ACPI_GPIO_QUIRK_NO_IO_RESTRICTION },
{ },
};
static void sx9500_gpio_probe(struct i2c_client *client, static void sx9500_gpio_probe(struct i2c_client *client,
struct sx9500_data *data) struct sx9500_data *data)
{ {
struct gpio_desc *gpiod_int; struct gpio_desc *gpiod_int;
struct device *dev; struct device *dev;
int ret;
if (!client) if (!client)
return; return;
dev = &client->dev; dev = &client->dev;
ret = devm_acpi_dev_add_driver_gpios(dev, acpi_sx9500_gpios);
if (ret)
dev_dbg(dev, "Unable to add GPIO mapping table\n");
if (client->irq <= 0) { if (client->irq <= 0) {
gpiod_int = devm_gpiod_get(dev, SX9500_GPIO_INT, GPIOD_IN); gpiod_int = devm_gpiod_get(dev, "interrupt", GPIOD_IN);
if (IS_ERR(gpiod_int)) if (IS_ERR(gpiod_int))
dev_err(dev, "gpio get irq failed\n"); dev_err(dev, "gpio get irq failed\n");
else else
client->irq = gpiod_to_irq(gpiod_int); client->irq = gpiod_to_irq(gpiod_int);
} }
data->gpiod_rst = devm_gpiod_get(dev, SX9500_GPIO_RESET, GPIOD_OUT_HIGH); data->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(data->gpiod_rst)) { if (IS_ERR(data->gpiod_rst)) {
dev_warn(dev, "gpio get reset pin failed\n"); dev_warn(dev, "gpio get reset pin failed\n");
data->gpiod_rst = NULL; data->gpiod_rst = NULL;

View File

@ -506,6 +506,8 @@ static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val)
ret = mlx90632_read_ambient_raw(data->regmap, &ambient_new_raw, ret = mlx90632_read_ambient_raw(data->regmap, &ambient_new_raw,
&ambient_old_raw); &ambient_old_raw);
if (ret < 0)
return ret;
*val = mlx90632_calc_temp_ambient(ambient_new_raw, ambient_old_raw, *val = mlx90632_calc_temp_ambient(ambient_new_raw, ambient_old_raw,
PT, PR, PG, PO, Gb); PT, PR, PG, PO, Gb);
return ret; return ret;

View File

@ -7,13 +7,13 @@
*/ */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
@ -232,6 +232,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
*val = val16; *val = val16;
return IIO_VAL_INT; return IIO_VAL_INT;
} }
return -EINVAL; return -EINVAL;
} }
@ -262,6 +263,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
addr = adis16201_addresses[chan->scan_index]; addr = adis16201_addresses[chan->scan_index];
return adis_write_reg_16(st, addr, val16); return adis_write_reg_16(st, addr, val16);
} }
return -EINVAL; return -EINVAL;
} }
@ -336,6 +338,7 @@ static int adis16201_probe(struct spi_device *spi)
ret = adis_init(st, indio_dev, spi, &adis16201_data); ret = adis_init(st, indio_dev, spi, &adis16201_data);
if (ret) if (ret)
return ret; return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret) if (ret)
return ret; return ret;
@ -348,6 +351,7 @@ static int adis16201_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret < 0) if (ret < 0)
goto error_cleanup_buffer_trigger; goto error_cleanup_buffer_trigger;
return 0; return 0;
error_cleanup_buffer_trigger: error_cleanup_buffer_trigger:

View File

@ -9,147 +9,82 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/list.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/iio/buffer.h> #include <linux/iio/buffer.h>
#include <linux/iio/imu/adis.h> #include <linux/iio/imu/adis.h>
#define ADIS16209_STARTUP_DELAY 220 /* ms */ #define ADIS16209_STARTUP_DELAY_MS 220
#define ADIS16209_FLASH_CNT_REG 0x00
/* Flash memory write count */
#define ADIS16209_FLASH_CNT 0x00
/* Output, power supply */
#define ADIS16209_SUPPLY_OUT 0x02
/* Output, x-axis accelerometer */
#define ADIS16209_XACCL_OUT 0x04
/* Output, y-axis accelerometer */
#define ADIS16209_YACCL_OUT 0x06
/* Data Output Register Definitions */
#define ADIS16209_SUPPLY_OUT_REG 0x02
#define ADIS16209_XACCL_OUT_REG 0x04
#define ADIS16209_YACCL_OUT_REG 0x06
/* Output, auxiliary ADC input */ /* Output, auxiliary ADC input */
#define ADIS16209_AUX_ADC 0x08 #define ADIS16209_AUX_ADC_REG 0x08
/* Output, temperature */ /* Output, temperature */
#define ADIS16209_TEMP_OUT 0x0A #define ADIS16209_TEMP_OUT_REG 0x0A
/* Output, +/- 90 degrees X-axis inclination */
/* Output, x-axis inclination */ #define ADIS16209_XINCL_OUT_REG 0x0C
#define ADIS16209_XINCL_OUT 0x0C #define ADIS16209_YINCL_OUT_REG 0x0E
/* Output, y-axis inclination */
#define ADIS16209_YINCL_OUT 0x0E
/* Output, +/-180 vertical rotational position */ /* Output, +/-180 vertical rotational position */
#define ADIS16209_ROT_OUT 0x10 #define ADIS16209_ROT_OUT_REG 0x10
/* Calibration, x-axis acceleration offset null */ /*
#define ADIS16209_XACCL_NULL 0x12 * Calibration Register Definitions.
* Acceleration, inclination or rotation offset null.
*/
#define ADIS16209_XACCL_NULL_REG 0x12
#define ADIS16209_YACCL_NULL_REG 0x14
#define ADIS16209_XINCL_NULL_REG 0x16
#define ADIS16209_YINCL_NULL_REG 0x18
#define ADIS16209_ROT_NULL_REG 0x1A
/* Calibration, y-axis acceleration offset null */ /* Alarm Register Definitions */
#define ADIS16209_YACCL_NULL 0x14 #define ADIS16209_ALM_MAG1_REG 0x20
#define ADIS16209_ALM_MAG2_REG 0x22
#define ADIS16209_ALM_SMPL1_REG 0x24
#define ADIS16209_ALM_SMPL2_REG 0x26
#define ADIS16209_ALM_CTRL_REG 0x28
/* Calibration, x-axis inclination offset null */ #define ADIS16209_AUX_DAC_REG 0x30
#define ADIS16209_XINCL_NULL 0x16 #define ADIS16209_GPIO_CTRL_REG 0x32
#define ADIS16209_SMPL_PRD_REG 0x36
/* Calibration, y-axis inclination offset null */ #define ADIS16209_AVG_CNT_REG 0x38
#define ADIS16209_YINCL_NULL 0x18 #define ADIS16209_SLP_CNT_REG 0x3A
/* Calibration, vertical rotation offset null */
#define ADIS16209_ROT_NULL 0x1A
/* Alarm 1 amplitude threshold */
#define ADIS16209_ALM_MAG1 0x20
/* Alarm 2 amplitude threshold */
#define ADIS16209_ALM_MAG2 0x22
/* Alarm 1, sample period */
#define ADIS16209_ALM_SMPL1 0x24
/* Alarm 2, sample period */
#define ADIS16209_ALM_SMPL2 0x26
/* Alarm control */
#define ADIS16209_ALM_CTRL 0x28
/* Auxiliary DAC data */
#define ADIS16209_AUX_DAC 0x30
/* General-purpose digital input/output control */
#define ADIS16209_GPIO_CTRL 0x32
/* Miscellaneous control */
#define ADIS16209_MSC_CTRL 0x34
/* Internal sample period (rate) control */
#define ADIS16209_SMPL_PRD 0x36
/* Operation, filter configuration */
#define ADIS16209_AVG_CNT 0x38
/* Operation, sleep mode control */
#define ADIS16209_SLP_CNT 0x3A
/* Diagnostics, system status register */
#define ADIS16209_DIAG_STAT 0x3C
/* Operation, system command register */
#define ADIS16209_GLOB_CMD 0x3E
/* MSC_CTRL */
/* Self-test at power-on: 1 = disabled, 0 = enabled */
#define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST BIT(10)
/* Self-test enable */
#define ADIS16209_MSC_CTRL_SELF_TEST_EN BIT(8)
/* Data-ready enable: 1 = enabled, 0 = disabled */
#define ADIS16209_MSC_CTRL_DATA_RDY_EN BIT(2)
#define ADIS16209_MSC_CTRL_REG 0x34
#define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST BIT(10)
#define ADIS16209_MSC_CTRL_SELF_TEST_EN BIT(8)
#define ADIS16209_MSC_CTRL_DATA_RDY_EN BIT(2)
/* Data-ready polarity: 1 = active high, 0 = active low */ /* Data-ready polarity: 1 = active high, 0 = active low */
#define ADIS16209_MSC_CTRL_ACTIVE_HIGH BIT(1) #define ADIS16209_MSC_CTRL_ACTIVE_HIGH BIT(1)
#define ADIS16209_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */
#define ADIS16209_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
/* DIAG_STAT */
/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16209_DIAG_STAT_ALARM2 BIT(9)
/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
#define ADIS16209_DIAG_STAT_ALARM1 BIT(8)
/* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */
#define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT 5
/* SPI communications failure */
#define ADIS16209_DIAG_STAT_SPI_FAIL_BIT 3
/* Flash update failure */
#define ADIS16209_DIAG_STAT_FLASH_UPT_BIT 2
#define ADIS16209_STAT_REG 0x3C
#define ADIS16209_STAT_ALARM2 BIT(9)
#define ADIS16209_STAT_ALARM1 BIT(8)
#define ADIS16209_STAT_SELFTEST_FAIL_BIT 5
#define ADIS16209_STAT_SPI_FAIL_BIT 3
#define ADIS16209_STAT_FLASH_UPT_FAIL_BIT 2
/* Power supply above 3.625 V */ /* Power supply above 3.625 V */
#define ADIS16209_DIAG_STAT_POWER_HIGH_BIT 1 #define ADIS16209_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */ /* Power supply below 3.15 V */
#define ADIS16209_DIAG_STAT_POWER_LOW_BIT 0 #define ADIS16209_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */ #define ADIS16209_CMD_REG 0x3E
#define ADIS16209_CMD_SW_RESET BIT(7)
#define ADIS16209_CMD_CLEAR_STAT BIT(4)
#define ADIS16209_CMD_FACTORY_CAL BIT(1)
#define ADIS16209_GLOB_CMD_SW_RESET BIT(7) #define ADIS16209_ERROR_ACTIVE BIT(14)
#define ADIS16209_GLOB_CMD_CLEAR_STAT BIT(4)
#define ADIS16209_GLOB_CMD_FACTORY_CAL BIT(1)
#define ADIS16209_ERROR_ACTIVE BIT(14)
enum adis16209_scan { enum adis16209_scan {
ADIS16209_SCAN_SUPPLY, ADIS16209_SCAN_SUPPLY,
@ -165,10 +100,10 @@ enum adis16209_scan {
static const u8 adis16209_addresses[8][1] = { static const u8 adis16209_addresses[8][1] = {
[ADIS16209_SCAN_SUPPLY] = { }, [ADIS16209_SCAN_SUPPLY] = { },
[ADIS16209_SCAN_AUX_ADC] = { }, [ADIS16209_SCAN_AUX_ADC] = { },
[ADIS16209_SCAN_ACC_X] = { ADIS16209_XACCL_NULL }, [ADIS16209_SCAN_ACC_X] = { ADIS16209_XACCL_NULL_REG },
[ADIS16209_SCAN_ACC_Y] = { ADIS16209_YACCL_NULL }, [ADIS16209_SCAN_ACC_Y] = { ADIS16209_YACCL_NULL_REG },
[ADIS16209_SCAN_INCLI_X] = { ADIS16209_XINCL_NULL }, [ADIS16209_SCAN_INCLI_X] = { ADIS16209_XINCL_NULL_REG },
[ADIS16209_SCAN_INCLI_Y] = { ADIS16209_YINCL_NULL }, [ADIS16209_SCAN_INCLI_Y] = { ADIS16209_YINCL_NULL_REG },
[ADIS16209_SCAN_ROT] = { }, [ADIS16209_SCAN_ROT] = { },
[ADIS16209_SCAN_TEMP] = { }, [ADIS16209_SCAN_TEMP] = { },
}; };
@ -220,30 +155,50 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
switch (chan->type) { switch (chan->type) {
case IIO_VOLTAGE: case IIO_VOLTAGE:
*val = 0; *val = 0;
if (chan->channel == 0) switch (chan->channel) {
case 0:
*val2 = 305180; /* 0.30518 mV */ *val2 = 305180; /* 0.30518 mV */
else break;
case 1:
*val2 = 610500; /* 0.6105 mV */ *val2 = 610500; /* 0.6105 mV */
break;
default:
return -EINVAL;
}
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_TEMP: case IIO_TEMP:
*val = -470; /* -0.47 C */ *val = -470;
*val2 = 0; *val2 = 0;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_ACCEL: case IIO_ACCEL:
/*
* IIO base unit for sensitivity of accelerometer
* is milli g.
* 1 LSB represents 0.244 mg.
*/
*val = 0; *val = 0;
*val2 = IIO_G_TO_M_S_2(244140); /* 0.244140 mg */ *val2 = IIO_G_TO_M_S_2(244140);
return IIO_VAL_INT_PLUS_NANO; return IIO_VAL_INT_PLUS_NANO;
case IIO_INCLI: case IIO_INCLI:
case IIO_ROT: case IIO_ROT:
/*
* IIO base units for rotation are degrees.
* 1 LSB represents 0.025 milli degrees.
*/
*val = 0; *val = 0;
*val2 = 25000; /* 0.025 degree */ *val2 = 25000;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
default: default:
return -EINVAL; return -EINVAL;
} }
break; break;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
*val = 25000 / -470 - 0x4FE; /* 25 C = 0x4FE */ /*
* The raw ADC value is 0x4FE when the temperature
* is 25 degrees and the scale factor per milli
* degree celcius is -470.
*/
*val = 25000 / -470 - 0x4FE;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
switch (chan->type) { switch (chan->type) {
@ -257,27 +212,27 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
ret = adis_read_reg_16(st, addr, &val16); ret = adis_read_reg_16(st, addr, &val16);
if (ret) if (ret)
return ret; return ret;
val16 &= (1 << bits) - 1;
val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); *val = sign_extend32(val16, bits - 1);
*val = val16;
return IIO_VAL_INT; return IIO_VAL_INT;
} }
return -EINVAL; return -EINVAL;
} }
static const struct iio_chan_spec adis16209_channels[] = { static const struct iio_chan_spec adis16209_channels[] = {
ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 0, 14), ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT_REG, ADIS16209_SCAN_SUPPLY,
ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 0, 12), 0, 14),
ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X, ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT_REG, ADIS16209_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT_REG, ADIS16209_SCAN_ACC_X,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14), BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y, ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT_REG, ADIS16209_SCAN_ACC_Y,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14), BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 0, 12), ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC_REG, ADIS16209_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT_REG, ADIS16209_SCAN_INCLI_X,
0, 0, 14), 0, 0, 14),
ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT_REG, ADIS16209_SCAN_INCLI_Y,
0, 0, 14), 0, 0, 14),
ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 0, 14), ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT_REG, ADIS16209_SCAN_ROT, 0, 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(8) IIO_CHAN_SOFT_TIMESTAMP(8)
}; };
@ -288,29 +243,29 @@ static const struct iio_info adis16209_info = {
}; };
static const char * const adis16209_status_error_msgs[] = { static const char * const adis16209_status_error_msgs[] = {
[ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", [ADIS16209_STAT_SELFTEST_FAIL_BIT] = "Self test failure",
[ADIS16209_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", [ADIS16209_STAT_SPI_FAIL_BIT] = "SPI failure",
[ADIS16209_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", [ADIS16209_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed",
[ADIS16209_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", [ADIS16209_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
[ADIS16209_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
}; };
static const struct adis_data adis16209_data = { static const struct adis_data adis16209_data = {
.read_delay = 30, .read_delay = 30,
.msc_ctrl_reg = ADIS16209_MSC_CTRL, .msc_ctrl_reg = ADIS16209_MSC_CTRL_REG,
.glob_cmd_reg = ADIS16209_GLOB_CMD, .glob_cmd_reg = ADIS16209_CMD_REG,
.diag_stat_reg = ADIS16209_DIAG_STAT, .diag_stat_reg = ADIS16209_STAT_REG,
.self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN, .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN,
.self_test_no_autoclear = true, .self_test_no_autoclear = true,
.startup_delay = ADIS16209_STARTUP_DELAY, .startup_delay = ADIS16209_STARTUP_DELAY_MS,
.status_error_msgs = adis16209_status_error_msgs, .status_error_msgs = adis16209_status_error_msgs,
.status_error_mask = BIT(ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT) | .status_error_mask = BIT(ADIS16209_STAT_SELFTEST_FAIL_BIT) |
BIT(ADIS16209_DIAG_STAT_SPI_FAIL_BIT) | BIT(ADIS16209_STAT_SPI_FAIL_BIT) |
BIT(ADIS16209_DIAG_STAT_FLASH_UPT_BIT) | BIT(ADIS16209_STAT_FLASH_UPT_FAIL_BIT) |
BIT(ADIS16209_DIAG_STAT_POWER_HIGH_BIT) | BIT(ADIS16209_STAT_POWER_HIGH_BIT) |
BIT(ADIS16209_DIAG_STAT_POWER_LOW_BIT), BIT(ADIS16209_STAT_POWER_LOW_BIT),
}; };
static int adis16209_probe(struct spi_device *spi) static int adis16209_probe(struct spi_device *spi)
@ -319,12 +274,10 @@ static int adis16209_probe(struct spi_device *spi)
struct adis *st; struct adis *st;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
st = iio_priv(indio_dev); st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev); spi_set_drvdata(spi, indio_dev);
indio_dev->name = spi->dev.driver->name; indio_dev->name = spi->dev.driver->name;
@ -341,7 +294,6 @@ static int adis16209_probe(struct spi_device *spi)
if (ret) if (ret)
return ret; return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(st); ret = adis_initial_startup(st);
if (ret) if (ret)
goto error_cleanup_buffer_trigger; goto error_cleanup_buffer_trigger;

View File

@ -254,7 +254,7 @@ static const struct attribute_group ad7816_attribute_group = {
static irqreturn_t ad7816_event_handler(int irq, void *private) static irqreturn_t ad7816_event_handler(int irq, void *private)
{ {
iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI, iio_push_event(private, IIO_EVENT_CODE_AD7816_OTI,
iio_get_time_ns((struct iio_dev *)private)); iio_get_time_ns(private));
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -2079,9 +2079,8 @@ static int adt7316_enable(struct device *dev)
return _adt7316_store_enabled(chip, 1); return _adt7316_store_enabled(chip, 1);
} }
SIMPLE_DEV_PM_OPS(adt7316_pm_ops, adt7316_disable, adt7316_enable);
EXPORT_SYMBOL_GPL(adt7316_pm_ops); EXPORT_SYMBOL_GPL(adt7316_pm_ops);
SIMPLE_DEV_PM_OPS(adt7316_pm_ops, adt7316_disable, adt7316_enable);
#endif #endif
static const struct iio_info adt7316_info = { static const struct iio_info adt7316_info = {

View File

@ -124,8 +124,9 @@ static int ad7150_read_raw(struct iio_dev *indio_dev,
} }
static int ad7150_read_event_config(struct iio_dev *indio_dev, static int ad7150_read_event_config(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, enum iio_event_type type, const struct iio_chan_spec *chan,
enum iio_event_direction dir) enum iio_event_type type,
enum iio_event_direction dir)
{ {
int ret; int ret;
u8 threshtype; u8 threshtype;

View File

@ -426,8 +426,8 @@ out:
} }
static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev, static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
long mask) long mask)
{ {
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
@ -493,7 +493,7 @@ static const struct iio_chan_spec ad7152_channels[] = {
*/ */
static int ad7152_probe(struct i2c_client *client, static int ad7152_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
int ret = 0; int ret = 0;
struct ad7152_chip_info *chip; struct ad7152_chip_info *chip;

View File

@ -217,7 +217,7 @@ static const unsigned char ad7746_cap_filter_rate_table[][2] = {
}; };
static int ad7746_select_channel(struct iio_dev *indio_dev, static int ad7746_select_channel(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan) struct iio_chan_spec const *chan)
{ {
struct ad7746_chip_info *chip = iio_priv(indio_dev); struct ad7746_chip_info *chip = iio_priv(indio_dev);
int ret, delay, idx; int ret, delay, idx;
@ -487,13 +487,13 @@ static int ad7746_write_raw(struct iio_dev *indio_dev,
AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0; AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0;
ret = i2c_smbus_write_byte_data(chip->client, ret = i2c_smbus_write_byte_data(chip->client,
AD7746_REG_CAPDACA, AD7746_REG_CAPDACA,
chip->capdac[chan->channel][0]); chip->capdac[chan->channel][0]);
if (ret < 0) if (ret < 0)
goto out; goto out;
ret = i2c_smbus_write_byte_data(chip->client, ret = i2c_smbus_write_byte_data(chip->client,
AD7746_REG_CAPDACB, AD7746_REG_CAPDACB,
chip->capdac[chan->channel][1]); chip->capdac[chan->channel][1]);
if (ret < 0) if (ret < 0)
goto out; goto out;
@ -675,7 +675,7 @@ static const struct iio_info ad7746_info = {
*/ */
static int ad7746_probe(struct i2c_client *client, static int ad7746_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct ad7746_platform_data *pdata = client->dev.platform_data; struct ad7746_platform_data *pdata = client->dev.platform_data;
struct ad7746_chip_info *chip; struct ad7746_chip_info *chip;

View File

@ -109,15 +109,15 @@
#define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F #define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F
/*Prox diode to use */ /*Prox diode to use */
#define TSL2X7X_DIODE0 0x10 #define TSL2X7X_DIODE0 0x01
#define TSL2X7X_DIODE1 0x20 #define TSL2X7X_DIODE1 0x02
#define TSL2X7X_DIODE_BOTH 0x30 #define TSL2X7X_DIODE_BOTH 0x03
/* LED Power */ /* LED Power */
#define TSL2X7X_100_mA 0x00 #define TSL2X7X_100_mA 0x00
#define TSL2X7X_50_mA 0x40 #define TSL2X7X_50_mA 0x01
#define TSL2X7X_25_mA 0x80 #define TSL2X7X_25_mA 0x02
#define TSL2X7X_13_mA 0xD0 #define TSL2X7X_13_mA 0x03
#define TSL2X7X_MAX_TIMER_CNT 0xFF #define TSL2X7X_MAX_TIMER_CNT 0xFF
#define TSL2X7X_MIN_ITIME 3 #define TSL2X7X_MIN_ITIME 3
@ -228,7 +228,7 @@ static const struct tsl2x7x_settings tsl2x7x_default_settings = {
.als_time = 219, /* 101 ms */ .als_time = 219, /* 101 ms */
.als_gain = 0, .als_gain = 0,
.prx_time = 254, /* 5.4 ms */ .prx_time = 254, /* 5.4 ms */
.prox_gain = 1, .prox_gain = 0,
.wait_time = 245, .wait_time = 245,
.prox_config = 0, .prox_config = 0,
.als_gain_trim = 1000, .als_gain_trim = 1000,
@ -240,7 +240,9 @@ static const struct tsl2x7x_settings tsl2x7x_default_settings = {
.prox_thres_low = 0, .prox_thres_low = 0,
.prox_thres_high = 512, .prox_thres_high = 512,
.prox_max_samples_cal = 30, .prox_max_samples_cal = 30,
.prox_pulse_count = 8 .prox_pulse_count = 8,
.prox_diode = TSL2X7X_DIODE1,
.prox_power = TSL2X7X_100_mA
}; };
static const s16 tsl2x7x_als_gain[] = { static const s16 tsl2x7x_als_gain[] = {
@ -279,6 +281,49 @@ static const u8 device_channel_config[] = {
ALSPRX2 ALSPRX2
}; };
static int tsl2x7x_clear_interrupts(struct tsl2X7X_chip *chip, int reg)
{
int ret;
ret = i2c_smbus_write_byte(chip->client,
TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | reg);
if (ret < 0)
dev_err(&chip->client->dev,
"%s: failed to clear interrupt status %x: %d\n",
__func__, reg, ret);
return ret;
}
static int tsl2x7x_read_status(struct tsl2X7X_chip *chip)
{
int ret;
ret = i2c_smbus_read_byte_data(chip->client,
TSL2X7X_CMD_REG | TSL2X7X_STATUS);
if (ret < 0)
dev_err(&chip->client->dev,
"%s: failed to read STATUS register: %d\n", __func__,
ret);
return ret;
}
static int tsl2x7x_write_control_reg(struct tsl2X7X_chip *chip, u8 data)
{
int ret;
ret = i2c_smbus_write_byte_data(chip->client,
TSL2X7X_CMD_REG | TSL2X7X_CNTRL, data);
if (ret < 0) {
dev_err(&chip->client->dev,
"%s: failed to write to control register %x: %d\n",
__func__, data, ret);
}
return ret;
}
/** /**
* tsl2x7x_get_lux() - Reads and calculates current lux value. * tsl2x7x_get_lux() - Reads and calculates current lux value.
* @indio_dev: pointer to IIO device * @indio_dev: pointer to IIO device
@ -307,8 +352,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
u32 ch0lux = 0; u32 ch0lux = 0;
u32 ch1lux = 0; u32 ch1lux = 0;
if (mutex_trylock(&chip->als_mutex) == 0) mutex_lock(&chip->als_mutex);
return chip->als_cur_info.lux; /* busy, so return LAST VALUE */
if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) { if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) {
/* device is not enabled */ /* device is not enabled */
@ -318,13 +362,10 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
goto out_unlock; goto out_unlock;
} }
ret = i2c_smbus_read_byte_data(chip->client, ret = tsl2x7x_read_status(chip);
TSL2X7X_CMD_REG | TSL2X7X_STATUS); if (ret < 0)
if (ret < 0) {
dev_err(&chip->client->dev,
"%s: Failed to read STATUS Reg\n", __func__);
goto out_unlock; goto out_unlock;
}
/* is data new & valid */ /* is data new & valid */
if (!(ret & TSL2X7X_STA_ADC_VALID)) { if (!(ret & TSL2X7X_STA_ADC_VALID)) {
dev_err(&chip->client->dev, dev_err(&chip->client->dev,
@ -346,16 +387,9 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
buf[i] = ret; buf[i] = ret;
} }
/* clear any existing interrupt status */ ret = tsl2x7x_clear_interrupts(chip, TSL2X7X_CMD_ALS_INT_CLR);
ret = i2c_smbus_write_byte(chip->client, if (ret < 0)
TSL2X7X_CMD_REG | goto out_unlock;
TSL2X7X_CMD_SPL_FN |
TSL2X7X_CMD_ALS_INT_CLR);
if (ret < 0) {
dev_err(&chip->client->dev,
"i2c_write_command failed - err = %d\n", ret);
goto out_unlock; /* have no data, so return failure */
}
/* extract ALS/lux data */ /* extract ALS/lux data */
ch0 = le16_to_cpup((const __le16 *)&buf[0]); ch0 = le16_to_cpup((const __le16 *)&buf[0]);
@ -445,18 +479,11 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
u8 chdata[2]; u8 chdata[2];
struct tsl2X7X_chip *chip = iio_priv(indio_dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev);
if (mutex_trylock(&chip->prox_mutex) == 0) { mutex_lock(&chip->prox_mutex);
dev_err(&chip->client->dev,
"%s: Can't get prox mutex\n", __func__);
return -EBUSY;
}
ret = i2c_smbus_read_byte_data(chip->client, ret = tsl2x7x_read_status(chip);
TSL2X7X_CMD_REG | TSL2X7X_STATUS); if (ret < 0)
if (ret < 0) {
dev_err(&chip->client->dev, "i2c err=%d\n", ret);
goto prox_poll_err; goto prox_poll_err;
}
switch (chip->id) { switch (chip->id) {
case tsl2571: case tsl2571:
@ -464,16 +491,20 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
case tmd2671: case tmd2671:
case tsl2771: case tsl2771:
case tmd2771: case tmd2771:
if (!(ret & TSL2X7X_STA_ADC_VALID)) if (!(ret & TSL2X7X_STA_ADC_VALID)) {
ret = -EINVAL;
goto prox_poll_err; goto prox_poll_err;
}
break; break;
case tsl2572: case tsl2572:
case tsl2672: case tsl2672:
case tmd2672: case tmd2672:
case tsl2772: case tsl2772:
case tmd2772: case tmd2772:
if (!(ret & TSL2X7X_STA_PRX_VALID)) if (!(ret & TSL2X7X_STA_PRX_VALID)) {
ret = -EINVAL;
goto prox_poll_err; goto prox_poll_err;
}
break; break;
} }
@ -487,14 +518,13 @@ static int tsl2x7x_get_prox(struct iio_dev *indio_dev)
chdata[i] = ret; chdata[i] = ret;
} }
chip->prox_data = chip->prox_data = le16_to_cpup((const __le16 *)&chdata[0]);
le16_to_cpup((const __le16 *)&chdata[0]); ret = chip->prox_data;
prox_poll_err: prox_poll_err:
mutex_unlock(&chip->prox_mutex); mutex_unlock(&chip->prox_mutex);
return chip->prox_data; return ret;
} }
/** /**
@ -582,15 +612,11 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
int i; int i;
int ret = 0; int ret = 0;
u8 *dev_reg; u8 *dev_reg;
u8 utmp;
int als_count; int als_count;
int als_time; int als_time;
struct tsl2X7X_chip *chip = iio_priv(indio_dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev);
u8 reg_val = 0; u8 reg_val = 0;
if (chip->pdata && chip->pdata->power_on)
chip->pdata->power_on(indio_dev);
/* Non calculated parameters */ /* Non calculated parameters */
chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = chip->settings.prx_time; chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = chip->settings.prx_time;
chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = chip->settings.wait_time; chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = chip->settings.wait_time;
@ -635,9 +661,10 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
/* Set the gain based on tsl2x7x_settings struct */ /* Set the gain based on tsl2x7x_settings struct */
chip->tsl2x7x_config[TSL2X7X_GAIN] = chip->tsl2x7x_config[TSL2X7X_GAIN] =
chip->settings.als_gain | (chip->settings.als_gain & 0xFF) |
(TSL2X7X_100_mA | TSL2X7X_DIODE1) | ((chip->settings.prox_gain & 0xFF) << 2) |
(chip->settings.prox_gain << 2); (chip->settings.prox_diode << 4) |
(chip->settings.prox_power << 6);
/* set chip struct re scaling and saturation */ /* set chip struct re scaling and saturation */
chip->als_saturation = als_count * 922; /* 90% of full scale */ chip->als_saturation = als_count * 922; /* 90% of full scale */
@ -647,14 +674,9 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
* TSL2X7X Specific power-on / adc enable sequence * TSL2X7X Specific power-on / adc enable sequence
* Power on the device 1st. * Power on the device 1st.
*/ */
utmp = TSL2X7X_CNTL_PWR_ON; ret = tsl2x7x_write_control_reg(chip, TSL2X7X_CNTL_PWR_ON);
ret = i2c_smbus_write_byte_data(chip->client, if (ret < 0)
TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp);
if (ret < 0) {
dev_err(&chip->client->dev,
"%s: failed on CNTRL reg.\n", __func__);
return ret; return ret;
}
/* /*
* Use the following shadow copy for our delay before enabling ADC. * Use the following shadow copy for our delay before enabling ADC.
@ -679,16 +701,12 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
* NOW enable the ADC * NOW enable the ADC
* initialize the desired mode of operation * initialize the desired mode of operation
*/ */
utmp = TSL2X7X_CNTL_PWR_ON | ret = tsl2x7x_write_control_reg(chip,
TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON |
TSL2X7X_CNTL_PROX_DET_ENBL; TSL2X7X_CNTL_ADC_ENBL |
ret = i2c_smbus_write_byte_data(chip->client, TSL2X7X_CNTL_PROX_DET_ENBL);
TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); if (ret < 0)
if (ret < 0) {
dev_err(&chip->client->dev,
"%s: failed on 2nd CTRL reg.\n", __func__);
return ret; return ret;
}
chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING; chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING;
@ -701,25 +719,14 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL; reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL;
reg_val |= chip->settings.interrupts_en; reg_val |= chip->settings.interrupts_en;
ret = i2c_smbus_write_byte_data(chip->client, ret = tsl2x7x_write_control_reg(chip, reg_val);
TSL2X7X_CMD_REG | TSL2X7X_CNTRL,
reg_val);
if (ret < 0) if (ret < 0)
dev_err(&chip->client->dev, return ret;
"%s: failed in tsl2x7x_IOCTL_INT_SET.\n",
__func__);
/* Clear out any initial interrupts */ ret = tsl2x7x_clear_interrupts(chip,
ret = i2c_smbus_write_byte(chip->client, TSL2X7X_CMD_PROXALS_INT_CLR);
TSL2X7X_CMD_REG | if (ret < 0)
TSL2X7X_CMD_SPL_FN | return ret;
TSL2X7X_CMD_PROXALS_INT_CLR);
if (ret < 0) {
dev_err(&chip->client->dev,
"%s: Failed to clear Int status\n",
__func__);
return ret;
}
} }
return ret; return ret;
@ -727,19 +734,11 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
static int tsl2x7x_chip_off(struct iio_dev *indio_dev) static int tsl2x7x_chip_off(struct iio_dev *indio_dev)
{ {
int ret;
struct tsl2X7X_chip *chip = iio_priv(indio_dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev);
/* turn device off */ /* turn device off */
chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
return tsl2x7x_write_control_reg(chip, 0x00);
ret = i2c_smbus_write_byte_data(chip->client,
TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00);
if (chip->pdata && chip->pdata->power_off)
chip->pdata->power_off(chip->client);
return ret;
} }
/** /**
@ -777,7 +776,7 @@ unlock:
} }
static void tsl2x7x_prox_calculate(int *data, int length, static void tsl2x7x_prox_calculate(int *data, int length,
struct tsl2x7x_prox_stat *statP) struct tsl2x7x_prox_stat *stat)
{ {
int i; int i;
int sample_sum; int sample_sum;
@ -787,21 +786,21 @@ static void tsl2x7x_prox_calculate(int *data, int length,
length = 1; length = 1;
sample_sum = 0; sample_sum = 0;
statP->min = INT_MAX; stat->min = INT_MAX;
statP->max = INT_MIN; stat->max = INT_MIN;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
sample_sum += data[i]; sample_sum += data[i];
statP->min = min(statP->min, data[i]); stat->min = min(stat->min, data[i]);
statP->max = max(statP->max, data[i]); stat->max = max(stat->max, data[i]);
} }
statP->mean = sample_sum / length; stat->mean = sample_sum / length;
sample_sum = 0; sample_sum = 0;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
tmp = data[i] - statP->mean; tmp = data[i] - stat->mean;
sample_sum += tmp * tmp; sample_sum += tmp * tmp;
} }
statP->stddev = int_sqrt((long)sample_sum / length); stat->stddev = int_sqrt((long)sample_sum / length);
} }
/** /**
@ -811,12 +810,12 @@ static void tsl2x7x_prox_calculate(int *data, int length,
* Calculates a standard deviation based on the samples, * Calculates a standard deviation based on the samples,
* and sets the threshold accordingly. * and sets the threshold accordingly.
*/ */
static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) static int tsl2x7x_prox_cal(struct iio_dev *indio_dev)
{ {
int prox_history[MAX_SAMPLES_CAL + 1]; int prox_history[MAX_SAMPLES_CAL + 1];
int i; int i, ret;
struct tsl2x7x_prox_stat prox_stat_data[2]; struct tsl2x7x_prox_stat prox_stat_data[2];
struct tsl2x7x_prox_stat *calP; struct tsl2x7x_prox_stat *cal;
struct tsl2X7X_chip *chip = iio_priv(indio_dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev);
u8 tmp_irq_settings; u8 tmp_irq_settings;
u8 current_state = chip->tsl2x7x_chip_status; u8 current_state = chip->tsl2x7x_chip_status;
@ -829,40 +828,53 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
} }
/* have to stop to change settings */ /* have to stop to change settings */
tsl2x7x_chip_off(indio_dev); ret = tsl2x7x_chip_off(indio_dev);
if (ret < 0)
return ret;
/* Enable proximity detection save just in case prox not wanted yet*/ /* Enable proximity detection save just in case prox not wanted yet*/
tmp_irq_settings = chip->settings.interrupts_en; tmp_irq_settings = chip->settings.interrupts_en;
chip->settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL; chip->settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL;
/*turn on device if not already on*/ /*turn on device if not already on*/
tsl2x7x_chip_on(indio_dev); ret = tsl2x7x_chip_on(indio_dev);
if (ret < 0)
return ret;
/*gather the samples*/ /*gather the samples*/
for (i = 0; i < chip->settings.prox_max_samples_cal; i++) { for (i = 0; i < chip->settings.prox_max_samples_cal; i++) {
usleep_range(15000, 17500); usleep_range(15000, 17500);
tsl2x7x_get_prox(indio_dev); ret = tsl2x7x_get_prox(indio_dev);
if (ret < 0)
return ret;
prox_history[i] = chip->prox_data; prox_history[i] = chip->prox_data;
dev_info(&chip->client->dev, "2 i=%d prox data= %d\n", dev_info(&chip->client->dev, "2 i=%d prox data= %d\n",
i, chip->prox_data); i, chip->prox_data);
} }
tsl2x7x_chip_off(indio_dev); ret = tsl2x7x_chip_off(indio_dev);
calP = &prox_stat_data[PROX_STAT_CAL]; if (ret < 0)
return ret;
cal = &prox_stat_data[PROX_STAT_CAL];
tsl2x7x_prox_calculate(prox_history, tsl2x7x_prox_calculate(prox_history,
chip->settings.prox_max_samples_cal, calP); chip->settings.prox_max_samples_cal, cal);
chip->settings.prox_thres_high = (calP->max << 1) - calP->mean; chip->settings.prox_thres_high = (cal->max << 1) - cal->mean;
dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n", dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n",
calP->min, calP->mean, calP->max); cal->min, cal->mean, cal->max);
dev_info(&chip->client->dev, dev_info(&chip->client->dev,
"%s proximity threshold set to %d\n", "%s proximity threshold set to %d\n",
chip->client->name, chip->settings.prox_thres_high); chip->client->name, chip->settings.prox_thres_high);
/* back to the way they were */ /* back to the way they were */
chip->settings.interrupts_en = tmp_irq_settings; chip->settings.interrupts_en = tmp_irq_settings;
if (current_state == TSL2X7X_CHIP_WORKING) if (current_state == TSL2X7X_CHIP_WORKING) {
tsl2x7x_chip_on(indio_dev); ret = tsl2x7x_chip_on(indio_dev);
if (ret < 0)
return ret;
}
return 0;
} }
static ssize_t static ssize_t
@ -931,8 +943,11 @@ static ssize_t in_illuminance0_calibrate_store(struct device *dev,
if (strtobool(buf, &value)) if (strtobool(buf, &value))
return -EINVAL; return -EINVAL;
if (value) if (value) {
tsl2x7x_als_calibrate(indio_dev); ret = tsl2x7x_als_calibrate(indio_dev);
if (ret < 0)
return ret;
}
ret = tsl2x7x_invoke_change(indio_dev); ret = tsl2x7x_invoke_change(indio_dev);
if (ret < 0) if (ret < 0)
@ -997,8 +1012,11 @@ static ssize_t in_illuminance0_lux_table_store(struct device *dev,
return -EINVAL; return -EINVAL;
} }
if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
tsl2x7x_chip_off(indio_dev); ret = tsl2x7x_chip_off(indio_dev);
if (ret < 0)
return ret;
}
/* Zero out the table */ /* Zero out the table */
memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux)); memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux));
@ -1022,8 +1040,11 @@ static ssize_t in_proximity0_calibrate_store(struct device *dev,
if (strtobool(buf, &value)) if (strtobool(buf, &value))
return -EINVAL; return -EINVAL;
if (value) if (value) {
tsl2x7x_prox_cal(indio_dev); ret = tsl2x7x_prox_cal(indio_dev);
if (ret < 0)
return ret;
}
ret = tsl2x7x_invoke_change(indio_dev); ret = tsl2x7x_invoke_change(indio_dev);
if (ret < 0) if (ret < 0)
@ -1402,13 +1423,13 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
struct tsl2X7X_chip *chip = iio_priv(indio_dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev);
s64 timestamp = iio_get_time_ns(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev);
int ret; int ret;
u8 value;
value = i2c_smbus_read_byte_data(chip->client, ret = tsl2x7x_read_status(chip);
TSL2X7X_CMD_REG | TSL2X7X_STATUS); if (ret < 0)
return ret;
/* What type of interrupt do we need to process */ /* What type of interrupt do we need to process */
if (value & TSL2X7X_STA_PRX_INTR) { if (ret & TSL2X7X_STA_PRX_INTR) {
tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */ tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */
iio_push_event(indio_dev, iio_push_event(indio_dev,
IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
@ -1418,7 +1439,7 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
timestamp); timestamp);
} }
if (value & TSL2X7X_STA_ALS_INTR) { if (ret & TSL2X7X_STA_ALS_INTR) {
tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */ tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */
iio_push_event(indio_dev, iio_push_event(indio_dev,
IIO_UNMOD_EVENT_CODE(IIO_LIGHT, IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
@ -1427,14 +1448,10 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private)
IIO_EV_DIR_EITHER), IIO_EV_DIR_EITHER),
timestamp); timestamp);
} }
/* Clear interrupt now that we have handled it. */
ret = i2c_smbus_write_byte(chip->client, ret = tsl2x7x_clear_interrupts(chip, TSL2X7X_CMD_PROXALS_INT_CLR);
TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN |
TSL2X7X_CMD_PROXALS_INT_CLR);
if (ret < 0) if (ret < 0)
dev_err(&chip->client->dev, return ret;
"Failed to clear irq from event handler. err = %d\n",
ret);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -1461,7 +1478,6 @@ static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = {
&dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_target_input.attr,
&dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_calibrate.attr,
&dev_attr_in_illuminance0_lux_table.attr, &dev_attr_in_illuminance0_lux_table.attr,
&iio_const_attr_in_proximity0_calibscale_available.dev_attr.attr,
NULL NULL
}; };
@ -1792,12 +1808,6 @@ static int tsl2x7x_suspend(struct device *dev)
chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED;
} }
if (chip->pdata && chip->pdata->platform_power) {
pm_message_t pmm = {PM_EVENT_SUSPEND};
chip->pdata->platform_power(dev, pmm);
}
return ret; return ret;
} }
@ -1807,12 +1817,6 @@ static int tsl2x7x_resume(struct device *dev)
struct tsl2X7X_chip *chip = iio_priv(indio_dev); struct tsl2X7X_chip *chip = iio_priv(indio_dev);
int ret = 0; int ret = 0;
if (chip->pdata && chip->pdata->platform_power) {
pm_message_t pmm = {PM_EVENT_RESUME};
chip->pdata->platform_power(dev, pmm);
}
if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED) if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED)
ret = tsl2x7x_chip_on(indio_dev); ret = tsl2x7x_chip_on(indio_dev);

View File

@ -21,7 +21,6 @@
#ifndef __TSL2X7X_H #ifndef __TSL2X7X_H
#define __TSL2X7X_H #define __TSL2X7X_H
#include <linux/pm.h>
struct tsl2x7x_lux { struct tsl2x7x_lux {
unsigned int ratio; unsigned int ratio;
@ -79,6 +78,8 @@ struct tsl2x7x_settings {
int prox_thres_high; int prox_thres_high;
int prox_pulse_count; int prox_pulse_count;
int prox_max_samples_cal; int prox_max_samples_cal;
int prox_diode;
int prox_power;
}; };
/** /**
@ -91,9 +92,6 @@ struct tsl2x7x_settings {
* *
*/ */
struct tsl2X7X_platform_data { struct tsl2X7X_platform_data {
int (*platform_power)(struct device *dev, pm_message_t);
int (*power_on)(struct iio_dev *indio_dev);
int (*power_off)(struct i2c_client *dev);
struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE]; struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE];
struct tsl2x7x_settings *platform_default_settings; struct tsl2x7x_settings *platform_default_settings;
}; };

View File

@ -388,14 +388,16 @@ 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, 0644,
ade7753_read_8bit, static IIO_DEVICE_ATTR(choff_1, 0644,
ade7753_write_8bit, ade7753_read_8bit,
ADE7753_CH1OS); ade7753_write_8bit,
static IIO_DEV_ATTR_CH_OFF(2, 0644, ADE7753_CH1OS);
ade7753_read_8bit,
ade7753_write_8bit, static IIO_DEVICE_ATTR(choff_2, 0644,
ADE7753_CH2OS); ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_CH2OS);
static int ade7753_set_irq(struct device *dev, bool enable) static int ade7753_set_irq(struct device *dev, bool enable)
{ {

View File

@ -132,7 +132,7 @@ static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
} }
static int ade7754_spi_write_reg_16(struct device *dev, static int ade7754_spi_write_reg_16(struct device *dev,
u8 reg_address, u16 value) u8 reg_address, u16 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -140,8 +140,8 @@ static int ade7754_spi_write_reg_16(struct device *dev,
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
st->tx[0] = ADE7754_WRITE_REG(reg_address); st->tx[0] = ADE7754_WRITE_REG(reg_address);
st->tx[1] = (value >> 8) & 0xFF; st->tx[1] = (val >> 8) & 0xFF;
st->tx[2] = value & 0xFF; st->tx[2] = val & 0xFF;
ret = spi_write(st->us, st->tx, 3); ret = spi_write(st->us, st->tx, 3);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);

View File

@ -30,11 +30,11 @@ static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
* ade7758_data_rdy_trigger_set_state() set datardy interrupt state * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
**/ **/
static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig, static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state) bool state)
{ {
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); dev_dbg(&indio_dev->dev, "(%d)\n", state);
return ade7758_set_irq(&indio_dev->dev, state); return ade7758_set_irq(&indio_dev->dev, state);
} }
@ -63,8 +63,8 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev)
int ret; int ret;
st->trig = iio_trigger_alloc("%s-dev%d", st->trig = iio_trigger_alloc("%s-dev%d",
spi_get_device_id(st->us)->name, spi_get_device_id(st->us)->name,
indio_dev->id); indio_dev->id);
if (!st->trig) { if (!st->trig) {
ret = -ENOMEM; ret = -ENOMEM;
goto error_ret; goto error_ret;

View File

@ -328,14 +328,16 @@ static IIO_DEV_ATTR_ACTIVE_POWER_GAIN(0644,
ade7759_read_16bit, ade7759_read_16bit,
ade7759_write_16bit, ade7759_write_16bit,
ADE7759_APGAIN); ADE7759_APGAIN);
static IIO_DEV_ATTR_CH_OFF(1, 0644,
ade7759_read_8bit, static IIO_DEVICE_ATTR(choff_1, 0644,
ade7759_write_8bit, ade7759_read_8bit,
ADE7759_CH1OS); ade7759_write_8bit,
static IIO_DEV_ATTR_CH_OFF(2, 0644, ADE7759_CH1OS);
ade7759_read_8bit,
ade7759_write_8bit, static IIO_DEVICE_ATTR(choff_2, 0644,
ADE7759_CH2OS); ade7759_read_8bit,
ade7759_write_8bit,
ADE7759_CH2OS);
static int ade7759_set_irq(struct device *dev, bool enable) static int ade7759_set_irq(struct device *dev, bool enable)
{ {

View File

@ -17,7 +17,7 @@
static int ade7854_i2c_write_reg_8(struct device *dev, static int ade7854_i2c_write_reg_8(struct device *dev,
u16 reg_address, u16 reg_address,
u8 value) u8 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -26,7 +26,7 @@ static int ade7854_i2c_write_reg_8(struct device *dev,
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
st->tx[0] = (reg_address >> 8) & 0xFF; st->tx[0] = (reg_address >> 8) & 0xFF;
st->tx[1] = reg_address & 0xFF; st->tx[1] = reg_address & 0xFF;
st->tx[2] = value; st->tx[2] = val;
ret = i2c_master_send(st->i2c, st->tx, 3); ret = i2c_master_send(st->i2c, st->tx, 3);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -36,7 +36,7 @@ static int ade7854_i2c_write_reg_8(struct device *dev,
static int ade7854_i2c_write_reg_16(struct device *dev, static int ade7854_i2c_write_reg_16(struct device *dev,
u16 reg_address, u16 reg_address,
u16 value) u16 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -45,8 +45,8 @@ static int ade7854_i2c_write_reg_16(struct device *dev,
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
st->tx[0] = (reg_address >> 8) & 0xFF; st->tx[0] = (reg_address >> 8) & 0xFF;
st->tx[1] = reg_address & 0xFF; st->tx[1] = reg_address & 0xFF;
st->tx[2] = (value >> 8) & 0xFF; st->tx[2] = (val >> 8) & 0xFF;
st->tx[3] = value & 0xFF; st->tx[3] = val & 0xFF;
ret = i2c_master_send(st->i2c, st->tx, 4); ret = i2c_master_send(st->i2c, st->tx, 4);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -56,7 +56,7 @@ static int ade7854_i2c_write_reg_16(struct device *dev,
static int ade7854_i2c_write_reg_24(struct device *dev, static int ade7854_i2c_write_reg_24(struct device *dev,
u16 reg_address, u16 reg_address,
u32 value) u32 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -65,9 +65,9 @@ static int ade7854_i2c_write_reg_24(struct device *dev,
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
st->tx[0] = (reg_address >> 8) & 0xFF; st->tx[0] = (reg_address >> 8) & 0xFF;
st->tx[1] = reg_address & 0xFF; st->tx[1] = reg_address & 0xFF;
st->tx[2] = (value >> 16) & 0xFF; st->tx[2] = (val >> 16) & 0xFF;
st->tx[3] = (value >> 8) & 0xFF; st->tx[3] = (val >> 8) & 0xFF;
st->tx[4] = value & 0xFF; st->tx[4] = val & 0xFF;
ret = i2c_master_send(st->i2c, st->tx, 5); ret = i2c_master_send(st->i2c, st->tx, 5);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -77,7 +77,7 @@ static int ade7854_i2c_write_reg_24(struct device *dev,
static int ade7854_i2c_write_reg_32(struct device *dev, static int ade7854_i2c_write_reg_32(struct device *dev,
u16 reg_address, u16 reg_address,
u32 value) u32 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -86,10 +86,10 @@ static int ade7854_i2c_write_reg_32(struct device *dev,
mutex_lock(&st->buf_lock); mutex_lock(&st->buf_lock);
st->tx[0] = (reg_address >> 8) & 0xFF; st->tx[0] = (reg_address >> 8) & 0xFF;
st->tx[1] = reg_address & 0xFF; st->tx[1] = reg_address & 0xFF;
st->tx[2] = (value >> 24) & 0xFF; st->tx[2] = (val >> 24) & 0xFF;
st->tx[3] = (value >> 16) & 0xFF; st->tx[3] = (val >> 16) & 0xFF;
st->tx[4] = (value >> 8) & 0xFF; st->tx[4] = (val >> 8) & 0xFF;
st->tx[5] = value & 0xFF; st->tx[5] = val & 0xFF;
ret = i2c_master_send(st->i2c, st->tx, 6); ret = i2c_master_send(st->i2c, st->tx, 6);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);

View File

@ -16,8 +16,8 @@
#include "ade7854.h" #include "ade7854.h"
static int ade7854_spi_write_reg_8(struct device *dev, static int ade7854_spi_write_reg_8(struct device *dev,
u16 reg_address, u16 reg_address,
u8 value) u8 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -32,7 +32,7 @@ static int ade7854_spi_write_reg_8(struct device *dev,
st->tx[0] = ADE7854_WRITE_REG; st->tx[0] = ADE7854_WRITE_REG;
st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF; st->tx[2] = reg_address & 0xFF;
st->tx[3] = value & 0xFF; st->tx[3] = val & 0xFF;
ret = spi_sync_transfer(st->spi, &xfer, 1); ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -41,8 +41,8 @@ static int ade7854_spi_write_reg_8(struct device *dev,
} }
static int ade7854_spi_write_reg_16(struct device *dev, static int ade7854_spi_write_reg_16(struct device *dev,
u16 reg_address, u16 reg_address,
u16 value) u16 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -57,8 +57,8 @@ static int ade7854_spi_write_reg_16(struct device *dev,
st->tx[0] = ADE7854_WRITE_REG; st->tx[0] = ADE7854_WRITE_REG;
st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF; st->tx[2] = reg_address & 0xFF;
st->tx[3] = (value >> 8) & 0xFF; st->tx[3] = (val >> 8) & 0xFF;
st->tx[4] = value & 0xFF; st->tx[4] = val & 0xFF;
ret = spi_sync_transfer(st->spi, &xfer, 1); ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -67,8 +67,8 @@ static int ade7854_spi_write_reg_16(struct device *dev,
} }
static int ade7854_spi_write_reg_24(struct device *dev, static int ade7854_spi_write_reg_24(struct device *dev,
u16 reg_address, u16 reg_address,
u32 value) u32 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -83,9 +83,9 @@ static int ade7854_spi_write_reg_24(struct device *dev,
st->tx[0] = ADE7854_WRITE_REG; st->tx[0] = ADE7854_WRITE_REG;
st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF; st->tx[2] = reg_address & 0xFF;
st->tx[3] = (value >> 16) & 0xFF; st->tx[3] = (val >> 16) & 0xFF;
st->tx[4] = (value >> 8) & 0xFF; st->tx[4] = (val >> 8) & 0xFF;
st->tx[5] = value & 0xFF; st->tx[5] = val & 0xFF;
ret = spi_sync_transfer(st->spi, &xfer, 1); ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -94,8 +94,8 @@ static int ade7854_spi_write_reg_24(struct device *dev,
} }
static int ade7854_spi_write_reg_32(struct device *dev, static int ade7854_spi_write_reg_32(struct device *dev,
u16 reg_address, u16 reg_address,
u32 value) u32 val)
{ {
int ret; int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@ -110,10 +110,10 @@ static int ade7854_spi_write_reg_32(struct device *dev,
st->tx[0] = ADE7854_WRITE_REG; st->tx[0] = ADE7854_WRITE_REG;
st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[1] = (reg_address >> 8) & 0xFF;
st->tx[2] = reg_address & 0xFF; st->tx[2] = reg_address & 0xFF;
st->tx[3] = (value >> 24) & 0xFF; st->tx[3] = (val >> 24) & 0xFF;
st->tx[4] = (value >> 16) & 0xFF; st->tx[4] = (val >> 16) & 0xFF;
st->tx[5] = (value >> 8) & 0xFF; st->tx[5] = (val >> 8) & 0xFF;
st->tx[6] = value & 0xFF; st->tx[6] = val & 0xFF;
ret = spi_sync_transfer(st->spi, &xfer, 1); ret = spi_sync_transfer(st->spi, &xfer, 1);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
@ -122,8 +122,8 @@ static int ade7854_spi_write_reg_32(struct device *dev,
} }
static int ade7854_spi_read_reg_8(struct device *dev, static int ade7854_spi_read_reg_8(struct device *dev,
u16 reg_address, u16 reg_address,
u8 *val) u8 *val)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev); struct ade7854_state *st = iio_priv(indio_dev);
@ -149,7 +149,7 @@ static int ade7854_spi_read_reg_8(struct device *dev,
ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) { if (ret) {
dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X", dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X",
reg_address); reg_address);
goto error_ret; goto error_ret;
} }
*val = st->rx[0]; *val = st->rx[0];
@ -160,8 +160,8 @@ error_ret:
} }
static int ade7854_spi_read_reg_16(struct device *dev, static int ade7854_spi_read_reg_16(struct device *dev,
u16 reg_address, u16 reg_address,
u16 *val) u16 *val)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev); struct ade7854_state *st = iio_priv(indio_dev);
@ -186,7 +186,7 @@ static int ade7854_spi_read_reg_16(struct device *dev,
ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) { if (ret) {
dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X", dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X",
reg_address); reg_address);
goto error_ret; goto error_ret;
} }
*val = be16_to_cpup((const __be16 *)st->rx); *val = be16_to_cpup((const __be16 *)st->rx);
@ -197,8 +197,8 @@ error_ret:
} }
static int ade7854_spi_read_reg_24(struct device *dev, static int ade7854_spi_read_reg_24(struct device *dev,
u16 reg_address, u16 reg_address,
u32 *val) u32 *val)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev); struct ade7854_state *st = iio_priv(indio_dev);
@ -224,7 +224,7 @@ static int ade7854_spi_read_reg_24(struct device *dev,
ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) { if (ret) {
dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X", dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X",
reg_address); reg_address);
goto error_ret; goto error_ret;
} }
*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
@ -235,8 +235,8 @@ error_ret:
} }
static int ade7854_spi_read_reg_32(struct device *dev, static int ade7854_spi_read_reg_32(struct device *dev,
u16 reg_address, u16 reg_address,
u32 *val) u32 *val)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7854_state *st = iio_priv(indio_dev); struct ade7854_state *st = iio_priv(indio_dev);
@ -262,7 +262,7 @@ static int ade7854_spi_read_reg_32(struct device *dev,
ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
if (ret) { if (ret) {
dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X", dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X",
reg_address); reg_address);
goto error_ret; goto error_ret;
} }
*val = be32_to_cpup((const __be32 *)st->rx); *val = be32_to_cpup((const __be32 *)st->rx);

View File

@ -152,20 +152,20 @@
* @rx: receive buffer * @rx: receive buffer
**/ **/
struct ade7854_state { struct ade7854_state {
struct spi_device *spi; struct spi_device *spi;
struct i2c_client *i2c; struct i2c_client *i2c;
int (*read_reg_8)(struct device *, u16, u8 *); int (*read_reg_8)(struct device *dev, u16 reg_address, u8 *val);
int (*read_reg_16)(struct device *, u16, u16 *); int (*read_reg_16)(struct device *dev, u16 reg_address, u16 *val);
int (*read_reg_24)(struct device *, u16, u32 *); int (*read_reg_24)(struct device *dev, u16 reg_address, u32 *val);
int (*read_reg_32)(struct device *, u16, u32 *); int (*read_reg_32)(struct device *dev, u16 reg_address, u32 *val);
int (*write_reg_8)(struct device *, u16, u8); int (*write_reg_8)(struct device *dev, u16 reg_address, u8 val);
int (*write_reg_16)(struct device *, u16, u16); int (*write_reg_16)(struct device *dev, u16 reg_address, u16 val);
int (*write_reg_24)(struct device *, u16, u32); int (*write_reg_24)(struct device *dev, u16 reg_address, u32 val);
int (*write_reg_32)(struct device *, u16, u32); int (*write_reg_32)(struct device *dev, u16 reg_address, u32 val);
int irq; int irq;
struct mutex buf_lock; struct mutex buf_lock;
u8 tx[ADE7854_MAX_TX] ____cacheline_aligned; u8 tx[ADE7854_MAX_TX] ____cacheline_aligned;
u8 rx[ADE7854_MAX_RX]; u8 rx[ADE7854_MAX_RX];
}; };

View File

@ -348,9 +348,6 @@
#define IIO_DEV_ATTR_VPERIOD(_mode, _show, _store, _addr) \ #define IIO_DEV_ATTR_VPERIOD(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(vperiod, _mode, _show, _store, _addr) IIO_DEVICE_ATTR(vperiod, _mode, _show, _store, _addr)
#define IIO_DEV_ATTR_CH_OFF(_num, _mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(choff_##_num, _mode, _show, _store, _addr)
/* active energy register, AENERGY, is more than half full */ /* active energy register, AENERGY, is more than half full */
#define IIO_EVENT_ATTR_AENERGY_HALF_FULL(_evlist, _show, _store, _mask) \ #define IIO_EVENT_ATTR_AENERGY_HALF_FULL(_evlist, _show, _store, _mask) \
IIO_EVENT_ATTR_SH(aenergy_half_full, _evlist, _show, _store, _mask) IIO_EVENT_ATTR_SH(aenergy_half_full, _evlist, _show, _store, _mask)

View File

@ -35,8 +35,6 @@
#define AD2S1210_SET_RES1 0x02 #define AD2S1210_SET_RES1 0x02
#define AD2S1210_SET_RES0 0x01 #define AD2S1210_SET_RES0 0x01
#define AD2S1210_SET_ENRESOLUTION (AD2S1210_SET_ENRES1 | \
AD2S1210_SET_ENRES0)
#define AD2S1210_SET_RESOLUTION (AD2S1210_SET_RES1 | AD2S1210_SET_RES0) #define AD2S1210_SET_RESOLUTION (AD2S1210_SET_RES1 | AD2S1210_SET_RES0)
#define AD2S1210_REG_POSITION 0x80 #define AD2S1210_REG_POSITION 0x80
@ -53,10 +51,6 @@
#define AD2S1210_REG_SOFT_RESET 0xF0 #define AD2S1210_REG_SOFT_RESET 0xF0
#define AD2S1210_REG_FAULT 0xFF #define AD2S1210_REG_FAULT 0xFF
/* pin SAMPLE, A0, A1, RES0, RES1, is controlled by driver */
#define AD2S1210_SAA 3
#define AD2S1210_PN (AD2S1210_SAA + AD2S1210_RES)
#define AD2S1210_MIN_CLKIN 6144000 #define AD2S1210_MIN_CLKIN 6144000
#define AD2S1210_MAX_CLKIN 10240000 #define AD2S1210_MAX_CLKIN 10240000
#define AD2S1210_MIN_EXCIT 2000 #define AD2S1210_MIN_EXCIT 2000
@ -64,10 +58,6 @@
#define AD2S1210_MIN_FCW 0x4 #define AD2S1210_MIN_FCW 0x4
#define AD2S1210_MAX_FCW 0x50 #define AD2S1210_MAX_FCW 0x50
/* default input clock on serial interface */
#define AD2S1210_DEF_CLKIN 8192000
/* clock period in nano second */
#define AD2S1210_DEF_TCK (1000000000 / AD2S1210_DEF_CLKIN)
#define AD2S1210_DEF_EXCIT 10000 #define AD2S1210_DEF_EXCIT 10000
enum ad2s1210_mode { enum ad2s1210_mode {
@ -86,7 +76,6 @@ struct ad2s1210_state {
unsigned int fclkin; unsigned int fclkin;
unsigned int fexcit; unsigned int fexcit;
bool hysteresis; bool hysteresis;
bool old_data;
u8 resolution; u8 resolution;
enum ad2s1210_mode mode; enum ad2s1210_mode mode;
u8 rx[2] ____cacheline_aligned; u8 rx[2] ____cacheline_aligned;
@ -117,7 +106,6 @@ static int ad2s1210_config_write(struct ad2s1210_state *st, u8 data)
ret = spi_write(st->sdev, st->tx, 1); ret = spi_write(st->sdev, st->tx, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
st->old_data = true;
return 0; return 0;
} }
@ -139,7 +127,6 @@ static int ad2s1210_config_read(struct ad2s1210_state *st,
ret = spi_sync_transfer(st->sdev, &xfer, 1); ret = spi_sync_transfer(st->sdev, &xfer, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
st->old_data = true;
return st->rx[1]; return st->rx[1];
} }
@ -165,9 +152,10 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
static unsigned char ad2s1210_read_resolution_pin(struct ad2s1210_state *st) static unsigned char ad2s1210_read_resolution_pin(struct ad2s1210_state *st)
{ {
return ad2s1210_resolution_value[ int resolution = (gpio_get_value(st->pdata->res[0]) << 1) |
(gpio_get_value(st->pdata->res[0]) << 1) | gpio_get_value(st->pdata->res[1]);
gpio_get_value(st->pdata->res[1])];
return ad2s1210_resolution_value[resolution];
} }
static const int ad2s1210_res_pins[4][2] = { static const int ad2s1210_res_pins[4][2] = {