提交 2f37d65a 编写于 作者: L Linus Torvalds

Merge tag 'staging-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver updates from Greg KH:
 "Here is the big staging driver updates for 4.3-rc1.

  Lots of things all over the place, almost all of them trivial fixups
  and changes.  The usual IIO updates and new drivers and we have added
  the MOST driver subsystem which is getting cleaned up in the tree.
  The ozwpan driver is finally being deleted as it is obviously
  abandoned and no one cares about it.

  Full details are in the shortlog, and all of these have been in
  linux-next with no reported issues"

* tag 'staging-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (912 commits)
  staging/lustre/o2iblnd: remove references to ib_reg_phsy_mr()
  staging: wilc1000: fix build warning with setup_timer()
  staging: wilc1000: remove DECLARE_WILC_BUFFER()
  staging: wilc1000: remove void function return statements that are not useful
  staging: wilc1000: coreconfigurator.c: fix kmalloc error check
  staging: wilc1000: coreconfigurator.c: use kmalloc instead of WILC_MALLOC
  staging: wilc1000: remove unused codes of gps8ConfigPacket
  staging: wilc1000: remove unnecessary void pointer cast
  staging: wilc1000: remove WILC_NEW and WILC_NEW_EX
  staging: wilc1000: use kmalloc instead of WILC_NEW
  staging: wilc1000: Process WARN, INFO options of debug levels from user
  staging: wilc1000: remove unneeded tstrWILC_MsgQueueAttrs typedef
  staging: wilc1000: delete wilc_osconfig.h
  staging: wilc1000: delete wilc_log.h
  staging: wilc1000: delete wilc_timer.h
  staging: wilc1000: remove WILC_TimerStart()
  staging: wilc1000: remove WILC_TimerCreate()
  staging: wilc1000: remove WILC_TimerDestroy()
  staging: wilc1000: remove WILC_TimerStop()
  staging: wilc1000: remove tstrWILC_TimerAttrs typedef
  ...
...@@ -413,6 +413,11 @@ Description: ...@@ -413,6 +413,11 @@ Description:
to compute the calories burnt by the user. to compute the calories burnt by the user.
What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
What: /sys/.../iio:deviceX/in_anglvel_scale_available
What: /sys/.../iio:deviceX/in_magn_scale_available
What: /sys/.../iio:deviceX/in_illuminance_scale_available
What: /sys/.../iio:deviceX/in_intensity_scale_available
What: /sys/.../iio:deviceX/in_proximity_scale_available
What: /sys/.../iio:deviceX/in_voltageX_scale_available What: /sys/.../iio:deviceX/in_voltageX_scale_available
What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
What: /sys/.../iio:deviceX/out_voltageX_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available
...@@ -498,9 +503,9 @@ Description: ...@@ -498,9 +503,9 @@ Description:
outX_powerdown_mode_available. If Y is not present the outX_powerdown_mode_available. If Y is not present the
mode is shared across all outputs. mode is shared across all outputs.
What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available What: /sys/.../iio:deviceX/out_voltageY_powerdown_mode_available
What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available
What: /sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available What: /sys/.../iio:deviceX/out_altvoltageY_powerdown_mode_available
What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available
KernelVersion: 2.6.38 KernelVersion: 2.6.38
Contact: linux-iio@vger.kernel.org Contact: linux-iio@vger.kernel.org
...@@ -1035,13 +1040,6 @@ Contact: linux-iio@vger.kernel.org ...@@ -1035,13 +1040,6 @@ Contact: linux-iio@vger.kernel.org
Description: Description:
Number of scans contained by the buffer. Number of scans contained by the buffer.
What: /sys/bus/iio/devices/iio:deviceX/buffer/bytes_per_datum
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
Bytes per scan. Due to alignment fun, the scan may be larger
than implied directly by the scan_element parameters.
What: /sys/bus/iio/devices/iio:deviceX/buffer/enable What: /sys/bus/iio/devices/iio:deviceX/buffer/enable
KernelVersion: 2.6.35 KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org Contact: linux-iio@vger.kernel.org
......
...@@ -9,3 +9,12 @@ Description: ...@@ -9,3 +9,12 @@ Description:
automated testing or in situations, where other trigger methods automated testing or in situations, where other trigger methods
are not applicable. For example no RTC or spare GPIOs. are not applicable. For example no RTC or spare GPIOs.
X is the IIO index of the trigger. X is the IIO index of the trigger.
What: /sys/bus/iio/devices/triggerX/name
KernelVersion: 2.6.39
Contact: linux-iio@vger.kernel.org
Description:
The name attribute holds a description string for the current
trigger. In order to associate the trigger with an IIO device
one should write this name string to
/sys/bus/iio/devices/iio:deviceY/trigger/current_trigger.
...@@ -15,7 +15,7 @@ DOCBOOKS := z8530book.xml device-drivers.xml \ ...@@ -15,7 +15,7 @@ DOCBOOKS := z8530book.xml device-drivers.xml \
80211.xml debugobjects.xml sh.xml regulator.xml \ 80211.xml debugobjects.xml sh.xml regulator.xml \
alsa-driver-api.xml writing-an-alsa-driver.xml \ alsa-driver-api.xml writing-an-alsa-driver.xml \
tracepoint.xml drm.xml media_api.xml w1.xml \ tracepoint.xml drm.xml media_api.xml w1.xml \
writing_musb_glue_layer.xml crypto-API.xml writing_musb_glue_layer.xml crypto-API.xml iio.xml
include Documentation/DocBook/media/Makefile include Documentation/DocBook/media/Makefile
......
此差异已折叠。
...@@ -18,6 +18,7 @@ Required properties: ...@@ -18,6 +18,7 @@ Required properties:
"mcp3202" "mcp3202"
"mcp3204" "mcp3204"
"mcp3208" "mcp3208"
"mcp3301"
Examples: Examples:
......
...@@ -17,6 +17,11 @@ Recommended properties: ...@@ -17,6 +17,11 @@ Recommended properties:
- Frequency in normal mode (ADLPC=0, ADHSC=0) - Frequency in normal mode (ADLPC=0, ADHSC=0)
- Frequency in high-speed mode (ADLPC=0, ADHSC=1) - Frequency in high-speed mode (ADLPC=0, ADHSC=1)
- Frequency in low-power mode (ADLPC=1, ADHSC=0) - Frequency in low-power mode (ADLPC=1, ADHSC=0)
- min-sample-time: Minimum sampling time in nanoseconds. This value has
to be chosen according to the conversion mode and the connected analog
source resistance (R_as) and capacitance (C_as). Refer the datasheet's
operating requirements. A safe default across a wide range of R_as and
C_as as well as conversion modes is 1000ns.
Example: Example:
adc0: adc@4003b000 { adc0: adc@4003b000 {
......
* MEMSIC MMC35240 magnetometer sensor
Required properties:
- compatible : should be "memsic,mmc35240"
- reg : the I2C address of the magnetometer
Example:
mmc35240@30 {
compatible = "memsic,mmc35240";
reg = <0x30>;
};
...@@ -35,6 +35,7 @@ Accelerometers: ...@@ -35,6 +35,7 @@ Accelerometers:
- st,lsm303dl-accel - st,lsm303dl-accel
- st,lsm303dlm-accel - st,lsm303dlm-accel
- st,lsm330-accel - st,lsm330-accel
- st,lsm303agr-accel
Gyroscopes: Gyroscopes:
- st,l3g4200d-gyro - st,l3g4200d-gyro
...@@ -46,6 +47,7 @@ Gyroscopes: ...@@ -46,6 +47,7 @@ Gyroscopes:
- st,lsm330-gyro - st,lsm330-gyro
Magnetometers: Magnetometers:
- st,lsm303agr-magn
- st,lsm303dlh-magn - st,lsm303dlh-magn
- st,lsm303dlhc-magn - st,lsm303dlhc-magn
- st,lsm303dlm-magn - st,lsm303dlm-magn
......
* Freescale i.MX28 LRADC device driver * Freescale MXS LRADC device driver
Required properties: Required properties:
- compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc" - compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc"
......
What is sm712fb?
=================
This is a graphics framebuffer driver for Silicon Motion SM712 based processors.
How to use it?
==============
Switching modes is done using the video=sm712fb:... boot parameter.
If you want, for example, enable a resolution of 1280x1024x24bpp you should
pass to the kernel this command line: "video=sm712fb:0x31B".
You should not compile-in vesafb.
Currently supported video modes are:
[Graphic modes]
bpp | 640x480 800x600 1024x768 1280x1024
----+--------------------------------------------
8 | 0x301 0x303 0x305 0x307
16 | 0x311 0x314 0x317 0x31A
24 | 0x312 0x315 0x318 0x31B
Missing Features
================
(alias TODO list)
* 2D acceleratrion
* dual-head support
...@@ -9348,6 +9348,15 @@ S: Maintained ...@@ -9348,6 +9348,15 @@ S: Maintained
F: drivers/media/i2c/ov2659.c F: drivers/media/i2c/ov2659.c
F: include/media/ov2659.h F: include/media/ov2659.h
SILICON MOTION SM712 FRAME BUFFER DRIVER
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
M: Teddy Wang <teddy.wang@siliconmotion.com>
M: Sudip Mukherjee <sudip@vectorindia.org>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/fbdev/sm712*
F: Documentation/fb/sm712fb.txt
SIS 190 ETHERNET DRIVER SIS 190 ETHERNET DRIVER
M: Francois Romieu <romieu@fr.zoreil.com> M: Francois Romieu <romieu@fr.zoreil.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
...@@ -9745,11 +9754,6 @@ W: http://wiki.laptop.org/go/DCON ...@@ -9745,11 +9754,6 @@ W: http://wiki.laptop.org/go/DCON
S: Maintained S: Maintained
F: drivers/staging/olpc_dcon/ F: drivers/staging/olpc_dcon/
STAGING - OZMO DEVICES USB OVER WIFI DRIVER
M: Shigekatsu Tateno <shigekatsu.tateno@atmel.com>
S: Maintained
F: drivers/staging/ozwpan/
STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER
M: Willy Tarreau <willy@meta-x.org> M: Willy Tarreau <willy@meta-x.org>
S: Odd Fixes S: Odd Fixes
...@@ -9768,14 +9772,6 @@ L: linux-wireless@vger.kernel.org ...@@ -9768,14 +9772,6 @@ L: linux-wireless@vger.kernel.org
S: Maintained S: Maintained
F: drivers/staging/rtl8723au/ F: drivers/staging/rtl8723au/
STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
M: Teddy Wang <teddy.wang@siliconmotion.com>
M: Sudip Mukherjee <sudip@vectorindia.org>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/staging/sm7xxfb/
STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com> M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
M: Teddy Wang <teddy.wang@siliconmotion.com> M: Teddy Wang <teddy.wang@siliconmotion.com>
......
...@@ -86,18 +86,6 @@ config KXSD9 ...@@ -86,18 +86,6 @@ config KXSD9
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called kxsd9. will be called kxsd9.
config MMA8452
tristate "Freescale MMA8452Q Accelerometer Driver"
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for the Freescale MMA8452Q 3-axis
accelerometer.
To compile this driver as a module, choose M here: the module
will be called mma8452.
config KXCJK1013 config KXCJK1013
tristate "Kionix 3-Axis Accelerometer Driver" tristate "Kionix 3-Axis Accelerometer Driver"
depends on I2C depends on I2C
...@@ -111,6 +99,18 @@ config KXCJK1013 ...@@ -111,6 +99,18 @@ config KXCJK1013
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called kxcjk-1013. be called kxcjk-1013.
config MMA8452
tristate "Freescale MMA8452Q Accelerometer Driver"
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for the Freescale MMA8452Q 3-axis
accelerometer.
To compile this driver as a module, choose M here: the module
will be called mma8452.
config MMA9551_CORE config MMA9551_CORE
tristate tristate
...@@ -140,6 +140,8 @@ config MMA9553 ...@@ -140,6 +140,8 @@ config MMA9553
config STK8312 config STK8312
tristate "Sensortek STK8312 3-Axis Accelerometer Driver" tristate "Sensortek STK8312 3-Axis Accelerometer Driver"
depends on I2C depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help help
Say yes here to get support for the Sensortek STK8312 3-axis Say yes here to get support for the Sensortek STK8312 3-axis
accelerometer. accelerometer.
......
...@@ -846,7 +846,6 @@ MODULE_DEVICE_TABLE(i2c, bma180_ids); ...@@ -846,7 +846,6 @@ MODULE_DEVICE_TABLE(i2c, bma180_ids);
static struct i2c_driver bma180_driver = { static struct i2c_driver bma180_driver = {
.driver = { .driver = {
.name = "bma180", .name = "bma180",
.owner = THIS_MODULE,
.pm = BMA180_PM_OPS, .pm = BMA180_PM_OPS,
}, },
.probe = bma180_probe, .probe = bma180_probe,
......
...@@ -151,6 +151,7 @@ struct bmc150_scale_info { ...@@ -151,6 +151,7 @@ struct bmc150_scale_info {
}; };
struct bmc150_accel_chip_info { struct bmc150_accel_chip_info {
const char *name;
u8 chip_id; u8 chip_id;
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
int num_channels; int num_channels;
...@@ -241,7 +242,6 @@ static const struct { ...@@ -241,7 +242,6 @@ static const struct {
{500000, BMC150_ACCEL_SLEEP_500_MS}, {500000, BMC150_ACCEL_SLEEP_500_MS},
{1000000, BMC150_ACCEL_SLEEP_1_SEC} }; {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
static int bmc150_accel_set_mode(struct bmc150_accel_data *data, static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
enum bmc150_power_modes mode, enum bmc150_power_modes mode,
int dur_us) int dur_us)
...@@ -259,8 +259,9 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data, ...@@ -259,8 +259,9 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
dur_val = dur_val =
bmc150_accel_sleep_value_table[i].reg_value; bmc150_accel_sleep_value_table[i].reg_value;
} }
} else } else {
dur_val = 0; dur_val = 0;
}
if (dur_val < 0) if (dur_val < 0)
return -EINVAL; return -EINVAL;
...@@ -345,65 +346,6 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t, ...@@ -345,65 +346,6 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
return 0; return 0;
} }
static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
{
int ret;
ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
if (ret < 0) {
dev_err(&data->client->dev,
"Error: Reading chip id\n");
return ret;
}
dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
if (ret != data->chip_info->chip_id) {
dev_err(&data->client->dev, "Invalid chip %x\n", ret);
return -ENODEV;
}
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
if (ret < 0)
return ret;
/* Set Bandwidth */
ret = bmc150_accel_set_bw(data, BMC150_ACCEL_DEF_BW, 0);
if (ret < 0)
return ret;
/* Set Default Range */
ret = i2c_smbus_write_byte_data(data->client,
BMC150_ACCEL_REG_PMU_RANGE,
BMC150_ACCEL_DEF_RANGE_4G);
if (ret < 0) {
dev_err(&data->client->dev,
"Error writing reg_pmu_range\n");
return ret;
}
data->range = BMC150_ACCEL_DEF_RANGE_4G;
/* Set default slope duration and thresholds */
data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD;
data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION;
ret = bmc150_accel_update_slope(data);
if (ret < 0)
return ret;
/* Set default as latched interrupts */
ret = i2c_smbus_write_byte_data(data->client,
BMC150_ACCEL_REG_INT_RST_LATCH,
BMC150_ACCEL_INT_MODE_LATCH_INT |
BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret < 0) {
dev_err(&data->client->dev,
"Error writing reg_int_rst_latch\n");
return ret;
}
return 0;
}
static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val,
int *val2) int *val2)
{ {
...@@ -437,12 +379,13 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) ...@@ -437,12 +379,13 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
{ {
int ret; int ret;
if (on) if (on) {
ret = pm_runtime_get_sync(&data->client->dev); ret = pm_runtime_get_sync(&data->client->dev);
else { } else {
pm_runtime_mark_last_busy(&data->client->dev); pm_runtime_mark_last_busy(&data->client->dev);
ret = pm_runtime_put_autosuspend(&data->client->dev); ret = pm_runtime_put_autosuspend(&data->client->dev);
} }
if (ret < 0) { if (ret < 0) {
dev_err(&data->client->dev, dev_err(&data->client->dev,
"Failed: bmc150_accel_set_power_state for %d\n", on); "Failed: bmc150_accel_set_power_state for %d\n", on);
...@@ -514,13 +457,13 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i, ...@@ -514,13 +457,13 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
} }
/* /*
* We will expect the enable and disable to do operation in * We will expect the enable and disable to do operation in reverse
* in reverse order. This will happen here anyway as our * order. This will happen here anyway, as our resume operation uses
* resume operation uses sync mode runtime pm calls, the * sync mode runtime pm calls. The suspend operation will be delayed
* suspend operation will be delayed by autosuspend delay * by autosuspend delay.
* So the disable operation will still happen in reverse of * So the disable operation will still happen in reverse order of
* enable operation. When runtime pm is disabled the mode * enable operation. When runtime pm is disabled the mode is always on,
* is always on so sequence doesn't matter * so sequence doesn't matter.
*/ */
ret = bmc150_accel_set_power_state(data, state); ret = bmc150_accel_set_power_state(data, state);
if (ret < 0) if (ret < 0)
...@@ -574,7 +517,6 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i, ...@@ -574,7 +517,6 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
return ret; return ret;
} }
static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
{ {
int ret, i; int ret, i;
...@@ -674,8 +616,9 @@ static int bmc150_accel_read_raw(struct iio_dev *indio_dev, ...@@ -674,8 +616,9 @@ static int bmc150_accel_read_raw(struct iio_dev *indio_dev,
if (chan->type == IIO_TEMP) { if (chan->type == IIO_TEMP) {
*val = BMC150_ACCEL_TEMP_CENTER_VAL; *val = BMC150_ACCEL_TEMP_CENTER_VAL;
return IIO_VAL_INT; return IIO_VAL_INT;
} else } else {
return -EINVAL; return -EINVAL;
}
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = 0; *val = 0;
switch (chan->type) { switch (chan->type) {
...@@ -776,7 +719,7 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev, ...@@ -776,7 +719,7 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev,
switch (info) { switch (info) {
case IIO_EV_INFO_VALUE: case IIO_EV_INFO_VALUE:
data->slope_thres = val & 0xFF; data->slope_thres = val & BMC150_ACCEL_SLOPE_THRES_MASK;
break; break;
case IIO_EV_INFO_PERIOD: case IIO_EV_INFO_PERIOD:
data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK; data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK;
...@@ -793,7 +736,6 @@ static int bmc150_accel_read_event_config(struct iio_dev *indio_dev, ...@@ -793,7 +736,6 @@ static int bmc150_accel_read_event_config(struct iio_dev *indio_dev,
enum iio_event_type type, enum iio_event_type type,
enum iio_event_direction dir) enum iio_event_direction dir)
{ {
struct bmc150_accel_data *data = iio_priv(indio_dev); struct bmc150_accel_data *data = iio_priv(indio_dev);
return data->ev_enable_state; return data->ev_enable_state;
...@@ -963,6 +905,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev, ...@@ -963,6 +905,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3]; u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
int64_t tstamp; int64_t tstamp;
uint64_t sample_period; uint64_t sample_period;
ret = i2c_smbus_read_byte_data(data->client, ret = i2c_smbus_read_byte_data(data->client,
BMC150_ACCEL_REG_FIFO_STATUS); BMC150_ACCEL_REG_FIFO_STATUS);
if (ret < 0) { if (ret < 0) {
...@@ -1120,6 +1063,7 @@ enum { ...@@ -1120,6 +1063,7 @@ enum {
static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
[bmc150] = { [bmc150] = {
.name = "BMC150A",
.chip_id = 0xFA, .chip_id = 0xFA,
.channels = bmc150_accel_channels, .channels = bmc150_accel_channels,
.num_channels = ARRAY_SIZE(bmc150_accel_channels), .num_channels = ARRAY_SIZE(bmc150_accel_channels),
...@@ -1129,6 +1073,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { ...@@ -1129,6 +1073,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{76590, BMC150_ACCEL_DEF_RANGE_16G} }, {76590, BMC150_ACCEL_DEF_RANGE_16G} },
}, },
[bmi055] = { [bmi055] = {
.name = "BMI055A",
.chip_id = 0xFA, .chip_id = 0xFA,
.channels = bmc150_accel_channels, .channels = bmc150_accel_channels,
.num_channels = ARRAY_SIZE(bmc150_accel_channels), .num_channels = ARRAY_SIZE(bmc150_accel_channels),
...@@ -1138,6 +1083,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { ...@@ -1138,6 +1083,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{76590, BMC150_ACCEL_DEF_RANGE_16G} }, {76590, BMC150_ACCEL_DEF_RANGE_16G} },
}, },
[bma255] = { [bma255] = {
.name = "BMA0255",
.chip_id = 0xFA, .chip_id = 0xFA,
.channels = bmc150_accel_channels, .channels = bmc150_accel_channels,
.num_channels = ARRAY_SIZE(bmc150_accel_channels), .num_channels = ARRAY_SIZE(bmc150_accel_channels),
...@@ -1147,6 +1093,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { ...@@ -1147,6 +1093,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{76590, BMC150_ACCEL_DEF_RANGE_16G} }, {76590, BMC150_ACCEL_DEF_RANGE_16G} },
}, },
[bma250e] = { [bma250e] = {
.name = "BMA250E",
.chip_id = 0xF9, .chip_id = 0xF9,
.channels = bma250e_accel_channels, .channels = bma250e_accel_channels,
.num_channels = ARRAY_SIZE(bma250e_accel_channels), .num_channels = ARRAY_SIZE(bma250e_accel_channels),
...@@ -1156,6 +1103,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { ...@@ -1156,6 +1103,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{306457, BMC150_ACCEL_DEF_RANGE_16G} }, {306457, BMC150_ACCEL_DEF_RANGE_16G} },
}, },
[bma222e] = { [bma222e] = {
.name = "BMA222E",
.chip_id = 0xF8, .chip_id = 0xF8,
.channels = bma222e_accel_channels, .channels = bma222e_accel_channels,
.num_channels = ARRAY_SIZE(bma222e_accel_channels), .num_channels = ARRAY_SIZE(bma222e_accel_channels),
...@@ -1165,6 +1113,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { ...@@ -1165,6 +1113,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{1225831, BMC150_ACCEL_DEF_RANGE_16G} }, {1225831, BMC150_ACCEL_DEF_RANGE_16G} },
}, },
[bma280] = { [bma280] = {
.name = "BMA0280",
.chip_id = 0xFB, .chip_id = 0xFB,
.channels = bma280_accel_channels, .channels = bma280_accel_channels,
.num_channels = ARRAY_SIZE(bma280_accel_channels), .num_channels = ARRAY_SIZE(bma280_accel_channels),
...@@ -1314,26 +1263,32 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev) ...@@ -1314,26 +1263,32 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
dir = IIO_EV_DIR_RISING; dir = IIO_EV_DIR_RISING;
if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X) if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, iio_push_event(indio_dev,
IIO_MOD_EVENT_CODE(IIO_ACCEL,
0, 0,
IIO_MOD_X, IIO_MOD_X,
IIO_EV_TYPE_ROC, IIO_EV_TYPE_ROC,
dir), dir),
data->timestamp); data->timestamp);
if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y) if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, iio_push_event(indio_dev,
IIO_MOD_EVENT_CODE(IIO_ACCEL,
0, 0,
IIO_MOD_Y, IIO_MOD_Y,
IIO_EV_TYPE_ROC, IIO_EV_TYPE_ROC,
dir), dir),
data->timestamp); data->timestamp);
if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z) if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, iio_push_event(indio_dev,
IIO_MOD_EVENT_CODE(IIO_ACCEL,
0, 0,
IIO_MOD_Z, IIO_MOD_Z,
IIO_EV_TYPE_ROC, IIO_EV_TYPE_ROC,
dir), dir),
data->timestamp); data->timestamp);
return ret; return ret;
} }
...@@ -1365,7 +1320,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private) ...@@ -1365,7 +1320,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
BMC150_ACCEL_INT_MODE_LATCH_INT | BMC150_ACCEL_INT_MODE_LATCH_INT |
BMC150_ACCEL_INT_MODE_LATCH_RESET); BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret) if (ret)
dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n"); dev_err(&data->client->dev,
"Error writing reg_int_rst_latch\n");
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} else { } else {
ret = IRQ_NONE; ret = IRQ_NONE;
...@@ -1403,20 +1360,6 @@ static irqreturn_t bmc150_accel_irq_handler(int irq, void *private) ...@@ -1403,20 +1360,6 @@ static irqreturn_t bmc150_accel_irq_handler(int irq, void *private)
return IRQ_NONE; return IRQ_NONE;
} }
static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
{
const struct acpi_device_id *id;
id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!id)
return NULL;
*data = (int) id->driver_data;
return dev_name(dev);
}
static int bmc150_accel_gpio_probe(struct i2c_client *client, static int bmc150_accel_gpio_probe(struct i2c_client *client,
struct bmc150_accel_data *data) struct bmc150_accel_data *data)
{ {
...@@ -1611,6 +1554,70 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = { ...@@ -1611,6 +1554,70 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
.postdisable = bmc150_accel_buffer_postdisable, .postdisable = bmc150_accel_buffer_postdisable,
}; };
static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
{
int ret, i;
ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
if (ret < 0) {
dev_err(&data->client->dev, "Error: Reading chip id\n");
return ret;
}
dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
for (i = 0; i < ARRAY_SIZE(bmc150_accel_chip_info_tbl); i++) {
if (bmc150_accel_chip_info_tbl[i].chip_id == ret) {
data->chip_info = &bmc150_accel_chip_info_tbl[i];
break;
}
}
if (!data->chip_info) {
dev_err(&data->client->dev, "Unsupported chip %x\n", ret);
return -ENODEV;
}
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
if (ret < 0)
return ret;
/* Set Bandwidth */
ret = bmc150_accel_set_bw(data, BMC150_ACCEL_DEF_BW, 0);
if (ret < 0)
return ret;
/* Set Default Range */
ret = i2c_smbus_write_byte_data(data->client,
BMC150_ACCEL_REG_PMU_RANGE,
BMC150_ACCEL_DEF_RANGE_4G);
if (ret < 0) {
dev_err(&data->client->dev, "Error writing reg_pmu_range\n");
return ret;
}
data->range = BMC150_ACCEL_DEF_RANGE_4G;
/* Set default slope duration and thresholds */
data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD;
data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION;
ret = bmc150_accel_update_slope(data);
if (ret < 0)
return ret;
/* Set default as latched interrupts */
ret = i2c_smbus_write_byte_data(data->client,
BMC150_ACCEL_REG_INT_RST_LATCH,
BMC150_ACCEL_INT_MODE_LATCH_INT |
BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret < 0) {
dev_err(&data->client->dev,
"Error writing reg_int_rst_latch\n");
return ret;
}
return 0;
}
static int bmc150_accel_probe(struct i2c_client *client, static int bmc150_accel_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -1618,7 +1625,6 @@ static int bmc150_accel_probe(struct i2c_client *client, ...@@ -1618,7 +1625,6 @@ static int bmc150_accel_probe(struct i2c_client *client,
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
int ret; int ret;
const char *name = NULL; const char *name = NULL;
int chip_id = 0;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev) if (!indio_dev)
...@@ -1628,15 +1634,8 @@ static int bmc150_accel_probe(struct i2c_client *client, ...@@ -1628,15 +1634,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
i2c_set_clientdata(client, indio_dev); i2c_set_clientdata(client, indio_dev);
data->client = client; data->client = client;
if (id) { if (id)
name = id->name; name = id->name;
chip_id = id->driver_data;
}
if (ACPI_HANDLE(&client->dev))
name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
ret = bmc150_accel_chip_init(data); ret = bmc150_accel_chip_init(data);
if (ret < 0) if (ret < 0)
...@@ -1647,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client, ...@@ -1647,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
indio_dev->dev.parent = &client->dev; indio_dev->dev.parent = &client->dev;
indio_dev->channels = data->chip_info->channels; indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->num_channels; indio_dev->num_channels = data->chip_info->num_channels;
indio_dev->name = name; indio_dev->name = name ? name : data->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &bmc150_accel_info; indio_dev->info = &bmc150_accel_info;
...@@ -1663,7 +1662,7 @@ static int bmc150_accel_probe(struct i2c_client *client, ...@@ -1663,7 +1662,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
if (client->irq < 0) if (client->irq < 0)
client->irq = bmc150_accel_gpio_probe(client, data); client->irq = bmc150_accel_gpio_probe(client, data);
if (client->irq >= 0) { if (client->irq > 0) {
ret = devm_request_threaded_irq( ret = devm_request_threaded_irq(
&client->dev, client->irq, &client->dev, client->irq,
bmc150_accel_irq_handler, bmc150_accel_irq_handler,
......
...@@ -658,10 +658,8 @@ static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val) ...@@ -658,10 +658,8 @@ static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val)
int ret, i; int ret, i;
enum kxcjk1013_mode store_mode; enum kxcjk1013_mode store_mode;
for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) { for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) {
if (KXCJK1013_scale_table[i].scale == val) { if (KXCJK1013_scale_table[i].scale == val) {
ret = kxcjk1013_get_mode(data, &store_mode); ret = kxcjk1013_get_mode(data, &store_mode);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -820,7 +818,6 @@ static int kxcjk1013_read_event_config(struct iio_dev *indio_dev, ...@@ -820,7 +818,6 @@ static int kxcjk1013_read_event_config(struct iio_dev *indio_dev,
enum iio_event_type type, enum iio_event_type type,
enum iio_event_direction dir) enum iio_event_direction dir)
{ {
struct kxcjk1013_data *data = iio_priv(indio_dev); struct kxcjk1013_data *data = iio_priv(indio_dev);
return data->ev_enable_state; return data->ev_enable_state;
...@@ -1243,7 +1240,7 @@ static int kxcjk1013_probe(struct i2c_client *client, ...@@ -1243,7 +1240,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
if (client->irq < 0) if (client->irq < 0)
client->irq = kxcjk1013_gpio_probe(client, data); client->irq = kxcjk1013_gpio_probe(client, data);
if (client->irq >= 0) { if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq, ret = devm_request_threaded_irq(&client->dev, client->irq,
kxcjk1013_data_rdy_trig_poll, kxcjk1013_data_rdy_trig_poll,
kxcjk1013_event_handler, kxcjk1013_event_handler,
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/buffer.h> #include <linux/iio/buffer.h>
#include <linux/iio/trigger.h> #include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h> #include <linux/iio/trigger_consumer.h>
...@@ -25,49 +24,46 @@ ...@@ -25,49 +24,46 @@
#include <linux/delay.h> #include <linux/delay.h>
#define MMA8452_STATUS 0x00 #define MMA8452_STATUS 0x00
#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
#define MMA8452_OUT_X 0x01 /* MSB first, 12-bit */ #define MMA8452_OUT_X 0x01 /* MSB first, 12-bit */
#define MMA8452_OUT_Y 0x03 #define MMA8452_OUT_Y 0x03
#define MMA8452_OUT_Z 0x05 #define MMA8452_OUT_Z 0x05
#define MMA8452_INT_SRC 0x0c #define MMA8452_INT_SRC 0x0c
#define MMA8452_WHO_AM_I 0x0d #define MMA8452_WHO_AM_I 0x0d
#define MMA8452_DATA_CFG 0x0e #define MMA8452_DATA_CFG 0x0e
#define MMA8452_DATA_CFG_FS_MASK GENMASK(1, 0)
#define MMA8452_DATA_CFG_FS_2G 0
#define MMA8452_DATA_CFG_FS_4G 1
#define MMA8452_DATA_CFG_FS_8G 2
#define MMA8452_DATA_CFG_HPF_MASK BIT(4)
#define MMA8452_HP_FILTER_CUTOFF 0x0f #define MMA8452_HP_FILTER_CUTOFF 0x0f
#define MMA8452_HP_FILTER_CUTOFF_SEL_MASK (BIT(0) | BIT(1)) #define MMA8452_HP_FILTER_CUTOFF_SEL_MASK GENMASK(1, 0)
#define MMA8452_TRANSIENT_CFG 0x1d #define MMA8452_TRANSIENT_CFG 0x1d
#define MMA8452_TRANSIENT_CFG_ELE BIT(4)
#define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1)
#define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0) #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0)
#define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1)
#define MMA8452_TRANSIENT_CFG_ELE BIT(4)
#define MMA8452_TRANSIENT_SRC 0x1e #define MMA8452_TRANSIENT_SRC 0x1e
#define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1) #define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1)
#define MMA8452_TRANSIENT_SRC_YTRANSE BIT(3) #define MMA8452_TRANSIENT_SRC_YTRANSE BIT(3)
#define MMA8452_TRANSIENT_SRC_ZTRANSE BIT(5) #define MMA8452_TRANSIENT_SRC_ZTRANSE BIT(5)
#define MMA8452_TRANSIENT_THS 0x1f #define MMA8452_TRANSIENT_THS 0x1f
#define MMA8452_TRANSIENT_THS_MASK 0x7f #define MMA8452_TRANSIENT_THS_MASK GENMASK(6, 0)
#define MMA8452_TRANSIENT_COUNT 0x20 #define MMA8452_TRANSIENT_COUNT 0x20
#define MMA8452_OFF_X 0x2f
#define MMA8452_OFF_Y 0x30
#define MMA8452_OFF_Z 0x31
#define MMA8452_CTRL_REG1 0x2a #define MMA8452_CTRL_REG1 0x2a
#define MMA8452_CTRL_ACTIVE BIT(0)
#define MMA8452_CTRL_DR_MASK GENMASK(5, 3)
#define MMA8452_CTRL_DR_SHIFT 3
#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */
#define MMA8452_CTRL_REG2 0x2b #define MMA8452_CTRL_REG2 0x2b
#define MMA8452_CTRL_REG2_RST BIT(6) #define MMA8452_CTRL_REG2_RST BIT(6)
#define MMA8452_CTRL_REG4 0x2d #define MMA8452_CTRL_REG4 0x2d
#define MMA8452_CTRL_REG5 0x2e #define MMA8452_CTRL_REG5 0x2e
#define MMA8452_OFF_X 0x2f
#define MMA8452_OFF_Y 0x30
#define MMA8452_OFF_Z 0x31
#define MMA8452_MAX_REG 0x31 #define MMA8452_MAX_REG 0x31
#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
#define MMA8452_CTRL_DR_MASK (BIT(5) | BIT(4) | BIT(3))
#define MMA8452_CTRL_DR_SHIFT 3
#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */
#define MMA8452_CTRL_ACTIVE BIT(0)
#define MMA8452_DATA_CFG_FS_MASK (BIT(1) | BIT(0))
#define MMA8452_DATA_CFG_FS_2G 0
#define MMA8452_DATA_CFG_FS_4G 1
#define MMA8452_DATA_CFG_FS_8G 2
#define MMA8452_DATA_CFG_HPF_MASK BIT(4)
#define MMA8452_INT_DRDY BIT(0) #define MMA8452_INT_DRDY BIT(0)
#define MMA8452_INT_TRANS BIT(5) #define MMA8452_INT_TRANS BIT(5)
...@@ -91,30 +87,34 @@ static int mma8452_drdy(struct mma8452_data *data) ...@@ -91,30 +87,34 @@ static int mma8452_drdy(struct mma8452_data *data)
return ret; return ret;
if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY) if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
return 0; return 0;
msleep(20); msleep(20);
} }
dev_err(&data->client->dev, "data not ready\n"); dev_err(&data->client->dev, "data not ready\n");
return -EIO; return -EIO;
} }
static int mma8452_read(struct mma8452_data *data, __be16 buf[3]) static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
{ {
int ret = mma8452_drdy(data); int ret = mma8452_drdy(data);
if (ret < 0) if (ret < 0)
return ret; return ret;
return i2c_smbus_read_i2c_block_data(data->client,
MMA8452_OUT_X, 3 * sizeof(__be16), (u8 *) buf); return i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X,
3 * sizeof(__be16), (u8 *)buf);
} }
static ssize_t mma8452_show_int_plus_micros(char *buf, static ssize_t mma8452_show_int_plus_micros(char *buf, const int (*vals)[2],
const int (*vals)[2], int n) int n)
{ {
size_t len = 0; size_t len = 0;
while (n-- > 0) while (n-- > 0)
len += scnprintf(buf + len, PAGE_SIZE - len, len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
"%d.%06d ", vals[n][0], vals[n][1]); vals[n][0], vals[n][1]);
/* replace trailing space by newline */ /* replace trailing space by newline */
buf[len - 1] = '\n'; buf[len - 1] = '\n';
...@@ -147,7 +147,7 @@ static const int mma8452_samp_freq[8][2] = { ...@@ -147,7 +147,7 @@ static const int mma8452_samp_freq[8][2] = {
* Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048 * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
* The userspace interface uses m/s^2 and we declare micro units * The userspace interface uses m/s^2 and we declare micro units
* So scale factor is given by: * So scale factor is given by:
* g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665 * g * N * 1000000 / 2048 for N = 2, 4, 8 and g = 9.80665
*/ */
static const int mma8452_scales[3][2] = { static const int mma8452_scales[3][2] = {
{0, 9577}, {0, 19154}, {0, 38307} {0, 9577}, {0, 19154}, {0, 38307}
...@@ -178,14 +178,16 @@ static const int mma8452_hp_filter_cutoff[8][4][2] = { ...@@ -178,14 +178,16 @@ static const int mma8452_hp_filter_cutoff[8][4][2] = {
}; };
static ssize_t mma8452_show_samp_freq_avail(struct device *dev, static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr,
char *buf)
{ {
return mma8452_show_int_plus_micros(buf, mma8452_samp_freq, return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
ARRAY_SIZE(mma8452_samp_freq)); ARRAY_SIZE(mma8452_samp_freq));
} }
static ssize_t mma8452_show_scale_avail(struct device *dev, static ssize_t mma8452_show_scale_avail(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr,
char *buf)
{ {
return mma8452_show_int_plus_micros(buf, mma8452_scales, return mma8452_show_int_plus_micros(buf, mma8452_scales,
ARRAY_SIZE(mma8452_scales)); ARRAY_SIZE(mma8452_scales));
...@@ -213,14 +215,15 @@ static int mma8452_get_samp_freq_index(struct mma8452_data *data, ...@@ -213,14 +215,15 @@ static int mma8452_get_samp_freq_index(struct mma8452_data *data,
int val, int val2) int val, int val2)
{ {
return mma8452_get_int_plus_micros_index(mma8452_samp_freq, return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
ARRAY_SIZE(mma8452_samp_freq), val, val2); ARRAY_SIZE(mma8452_samp_freq),
val, val2);
} }
static int mma8452_get_scale_index(struct mma8452_data *data, static int mma8452_get_scale_index(struct mma8452_data *data, int val, int val2)
int val, int val2)
{ {
return mma8452_get_int_plus_micros_index(mma8452_scales, return mma8452_get_int_plus_micros_index(mma8452_scales,
ARRAY_SIZE(mma8452_scales), val, val2); ARRAY_SIZE(mma8452_scales),
val, val2);
} }
static int mma8452_get_hp_filter_index(struct mma8452_data *data, static int mma8452_get_hp_filter_index(struct mma8452_data *data,
...@@ -229,7 +232,7 @@ static int mma8452_get_hp_filter_index(struct mma8452_data *data, ...@@ -229,7 +232,7 @@ static int mma8452_get_hp_filter_index(struct mma8452_data *data,
int i = mma8452_get_odr_index(data); int i = mma8452_get_odr_index(data);
return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i], return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i],
ARRAY_SIZE(mma8452_scales[0]), val, val2); ARRAY_SIZE(mma8452_hp_filter_cutoff[0]), val, val2);
} }
static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz) static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
...@@ -266,25 +269,31 @@ static int mma8452_read_raw(struct iio_dev *indio_dev, ...@@ -266,25 +269,31 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = sign_extend32(
be16_to_cpu(buffer[chan->scan_index]) >> 4, 11); *val = sign_extend32(be16_to_cpu(buffer[chan->scan_index]) >> 4,
11);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK; i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
*val = mma8452_scales[i][0]; *val = mma8452_scales[i][0];
*val2 = mma8452_scales[i][1]; *val2 = mma8452_scales[i][1];
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
i = mma8452_get_odr_index(data); i = mma8452_get_odr_index(data);
*val = mma8452_samp_freq[i][0]; *val = mma8452_samp_freq[i][0];
*val2 = mma8452_samp_freq[i][1]; *val2 = mma8452_samp_freq[i][1];
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
ret = i2c_smbus_read_byte_data(data->client, MMA8452_OFF_X + ret = i2c_smbus_read_byte_data(data->client,
chan->scan_index); MMA8452_OFF_X + chan->scan_index);
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = sign_extend32(ret, 7); *val = sign_extend32(ret, 7);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) { if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) {
...@@ -295,8 +304,10 @@ static int mma8452_read_raw(struct iio_dev *indio_dev, ...@@ -295,8 +304,10 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
*val = 0; *val = 0;
*val2 = 0; *val2 = 0;
} }
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
} }
...@@ -334,6 +345,7 @@ static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val) ...@@ -334,6 +345,7 @@ static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
ret = 0; ret = 0;
fail: fail:
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return ret; return ret;
} }
...@@ -344,12 +356,13 @@ static int mma8452_set_hp_filter_frequency(struct mma8452_data *data, ...@@ -344,12 +356,13 @@ static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
i = mma8452_get_hp_filter_index(data, val, val2); i = mma8452_get_hp_filter_index(data, val, val2);
if (i < 0) if (i < 0)
return -EINVAL; return i;
reg = i2c_smbus_read_byte_data(data->client, reg = i2c_smbus_read_byte_data(data->client,
MMA8452_HP_FILTER_CUTOFF); MMA8452_HP_FILTER_CUTOFF);
if (reg < 0) if (reg < 0)
return reg; return reg;
reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK; reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
reg |= i; reg |= i;
...@@ -370,25 +383,30 @@ static int mma8452_write_raw(struct iio_dev *indio_dev, ...@@ -370,25 +383,30 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
i = mma8452_get_samp_freq_index(data, val, val2); i = mma8452_get_samp_freq_index(data, val, val2);
if (i < 0) if (i < 0)
return -EINVAL; return i;
data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK; data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT; data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
return mma8452_change_config(data, MMA8452_CTRL_REG1, return mma8452_change_config(data, MMA8452_CTRL_REG1,
data->ctrl_reg1); data->ctrl_reg1);
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
i = mma8452_get_scale_index(data, val, val2); i = mma8452_get_scale_index(data, val, val2);
if (i < 0) if (i < 0)
return -EINVAL; return i;
data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK; data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
data->data_cfg |= i; data->data_cfg |= i;
return mma8452_change_config(data, MMA8452_DATA_CFG, return mma8452_change_config(data, MMA8452_DATA_CFG,
data->data_cfg); data->data_cfg);
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
if (val < -128 || val > 127) if (val < -128 || val > 127)
return -EINVAL; return -EINVAL;
return mma8452_change_config(data, MMA8452_OFF_X +
chan->scan_index, val); return mma8452_change_config(data,
MMA8452_OFF_X + chan->scan_index,
val);
case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
if (val == 0 && val2 == 0) { if (val == 0 && val2 == 0) {
...@@ -399,6 +417,7 @@ static int mma8452_write_raw(struct iio_dev *indio_dev, ...@@ -399,6 +417,7 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
return mma8452_change_config(data, MMA8452_DATA_CFG, return mma8452_change_config(data, MMA8452_DATA_CFG,
data->data_cfg); data->data_cfg);
...@@ -425,6 +444,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev, ...@@ -425,6 +444,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
return ret; return ret;
*val = ret & MMA8452_TRANSIENT_THS_MASK; *val = ret & MMA8452_TRANSIENT_THS_MASK;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_EV_INFO_PERIOD: case IIO_EV_INFO_PERIOD:
...@@ -437,6 +457,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev, ...@@ -437,6 +457,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
mma8452_get_odr_index(data)]; mma8452_get_odr_index(data)];
*val = us / USEC_PER_SEC; *val = us / USEC_PER_SEC;
*val2 = us % USEC_PER_SEC; *val2 = us % USEC_PER_SEC;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_EV_INFO_HIGH_PASS_FILTER_3DB: case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
...@@ -453,6 +474,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev, ...@@ -453,6 +474,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
default: default:
...@@ -472,19 +494,22 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev, ...@@ -472,19 +494,22 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
switch (info) { switch (info) {
case IIO_EV_INFO_VALUE: case IIO_EV_INFO_VALUE:
return mma8452_change_config(data, MMA8452_TRANSIENT_THS, if (val < 0 || val > MMA8452_TRANSIENT_THS_MASK)
val & MMA8452_TRANSIENT_THS_MASK); return -EINVAL;
return mma8452_change_config(data, MMA8452_TRANSIENT_THS, val);
case IIO_EV_INFO_PERIOD: case IIO_EV_INFO_PERIOD:
steps = (val * USEC_PER_SEC + val2) / steps = (val * USEC_PER_SEC + val2) /
mma8452_transient_time_step_us[ mma8452_transient_time_step_us[
mma8452_get_odr_index(data)]; mma8452_get_odr_index(data)];
if (steps > 0xff) if (steps < 0 || steps > 0xff)
return -EINVAL; return -EINVAL;
return mma8452_change_config(data, MMA8452_TRANSIENT_COUNT, return mma8452_change_config(data, MMA8452_TRANSIENT_COUNT,
steps); steps);
case IIO_EV_INFO_HIGH_PASS_FILTER_3DB: case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
reg = i2c_smbus_read_byte_data(data->client, reg = i2c_smbus_read_byte_data(data->client,
MMA8452_TRANSIENT_CFG); MMA8452_TRANSIENT_CFG);
...@@ -499,6 +524,7 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev, ...@@ -499,6 +524,7 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg); return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);
default: default:
...@@ -608,7 +634,7 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p) ...@@ -608,7 +634,7 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p)
u8 buffer[16]; /* 3 16-bit channels + padding + ts */ u8 buffer[16]; /* 3 16-bit channels + padding + ts */
int ret; int ret;
ret = mma8452_read(data, (__be16 *) buffer); ret = mma8452_read(data, (__be16 *)buffer);
if (ret < 0) if (ret < 0)
goto done; goto done;
...@@ -617,6 +643,7 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p) ...@@ -617,6 +643,7 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p)
done: done:
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -780,6 +807,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev) ...@@ -780,6 +807,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev)
return ret; return ret;
indio_dev->trig = trig; indio_dev->trig = trig;
return 0; return 0;
} }
...@@ -968,6 +996,7 @@ static const struct of_device_id mma8452_dt_ids[] = { ...@@ -968,6 +996,7 @@ static const struct of_device_id mma8452_dt_ids[] = {
{ .compatible = "fsl,mma8452" }, { .compatible = "fsl,mma8452" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, mma8452_dt_ids);
static struct i2c_driver mma8452_driver = { static struct i2c_driver mma8452_driver = {
.driver = { .driver = {
......
...@@ -333,7 +333,7 @@ int mma9551_write_config_word(struct i2c_client *client, u8 app_id, ...@@ -333,7 +333,7 @@ int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
__be16 v = cpu_to_be16(val); __be16 v = cpu_to_be16(val);
return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg, return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
(u8 *) &v, 2, NULL, 0); (u8 *)&v, 2, NULL, 0);
} }
EXPORT_SYMBOL(mma9551_write_config_word); EXPORT_SYMBOL(mma9551_write_config_word);
...@@ -373,7 +373,7 @@ EXPORT_SYMBOL(mma9551_read_status_word); ...@@ -373,7 +373,7 @@ EXPORT_SYMBOL(mma9551_read_status_word);
* @client: I2C client * @client: I2C client
* @app_id: Application ID * @app_id: Application ID
* @reg: Application register * @reg: Application register
* @len: Length of array to read in bytes * @len: Length of array to read (in words)
* @buf: Array of words to read * @buf: Array of words to read
* *
* Read multiple configuration registers (word-sized registers). * Read multiple configuration registers (word-sized registers).
...@@ -388,20 +388,19 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id, ...@@ -388,20 +388,19 @@ int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
u16 reg, u8 len, u16 *buf) u16 reg, u8 len, u16 *buf)
{ {
int ret, i; int ret, i;
int len_words = len / sizeof(u16);
__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
if (len_words > ARRAY_SIZE(be_buf)) { if (len > ARRAY_SIZE(be_buf)) {
dev_err(&client->dev, "Invalid buffer size %d\n", len); dev_err(&client->dev, "Invalid buffer size %d\n", len);
return -EINVAL; return -EINVAL;
} }
ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
reg, NULL, 0, (u8 *) be_buf, len); reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
if (ret < 0) if (ret < 0)
return ret; return ret;
for (i = 0; i < len_words; i++) for (i = 0; i < len; i++)
buf[i] = be16_to_cpu(be_buf[i]); buf[i] = be16_to_cpu(be_buf[i]);
return 0; return 0;
...@@ -413,7 +412,7 @@ EXPORT_SYMBOL(mma9551_read_config_words); ...@@ -413,7 +412,7 @@ EXPORT_SYMBOL(mma9551_read_config_words);
* @client: I2C client * @client: I2C client
* @app_id: Application ID * @app_id: Application ID
* @reg: Application register * @reg: Application register
* @len: Length of array to read in bytes * @len: Length of array to read (in words)
* @buf: Array of words to read * @buf: Array of words to read
* *
* Read multiple status registers (word-sized registers). * Read multiple status registers (word-sized registers).
...@@ -428,20 +427,19 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id, ...@@ -428,20 +427,19 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
u16 reg, u8 len, u16 *buf) u16 reg, u8 len, u16 *buf)
{ {
int ret, i; int ret, i;
int len_words = len / sizeof(u16);
__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2]; __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
if (len_words > ARRAY_SIZE(be_buf)) { if (len > ARRAY_SIZE(be_buf)) {
dev_err(&client->dev, "Invalid buffer size %d\n", len); dev_err(&client->dev, "Invalid buffer size %d\n", len);
return -EINVAL; return -EINVAL;
} }
ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
reg, NULL, 0, (u8 *) be_buf, len); reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
if (ret < 0) if (ret < 0)
return ret; return ret;
for (i = 0; i < len_words; i++) for (i = 0; i < len; i++)
buf[i] = be16_to_cpu(be_buf[i]); buf[i] = be16_to_cpu(be_buf[i]);
return 0; return 0;
...@@ -453,7 +451,7 @@ EXPORT_SYMBOL(mma9551_read_status_words); ...@@ -453,7 +451,7 @@ EXPORT_SYMBOL(mma9551_read_status_words);
* @client: I2C client * @client: I2C client
* @app_id: Application ID * @app_id: Application ID
* @reg: Application register * @reg: Application register
* @len: Length of array to write in bytes * @len: Length of array to write (in words)
* @buf: Array of words to write * @buf: Array of words to write
* *
* Write multiple configuration registers (word-sized registers). * Write multiple configuration registers (word-sized registers).
...@@ -468,19 +466,18 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id, ...@@ -468,19 +466,18 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
u16 reg, u8 len, u16 *buf) u16 reg, u8 len, u16 *buf)
{ {
int i; int i;
int len_words = len / sizeof(u16);
__be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2]; __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
if (len_words > ARRAY_SIZE(be_buf)) { if (len > ARRAY_SIZE(be_buf)) {
dev_err(&client->dev, "Invalid buffer size %d\n", len); dev_err(&client->dev, "Invalid buffer size %d\n", len);
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < len_words; i++) for (i = 0; i < len; i++)
be_buf[i] = cpu_to_be16(buf[i]); be_buf[i] = cpu_to_be16(buf[i]);
return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
reg, (u8 *) be_buf, len, NULL, 0); reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
} }
EXPORT_SYMBOL(mma9551_write_config_words); EXPORT_SYMBOL(mma9551_write_config_words);
......
...@@ -182,6 +182,10 @@ struct mma9553_conf_regs { ...@@ -182,6 +182,10 @@ struct mma9553_conf_regs {
struct mma9553_data { struct mma9553_data {
struct i2c_client *client; struct i2c_client *client;
/*
* 1. Serialize access to HW (requested by mma9551_core API).
* 2. Serialize sequences that power on/off the device and access HW.
*/
struct mutex mutex; struct mutex mutex;
struct mma9553_conf_regs conf; struct mma9553_conf_regs conf;
struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE]; struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];
...@@ -322,7 +326,8 @@ static int mma9553_read_activity_stepcnt(struct mma9553_data *data, ...@@ -322,7 +326,8 @@ static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
int ret; int ret;
ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER, ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
MMA9553_REG_STATUS, sizeof(u32), buf); MMA9553_REG_STATUS, ARRAY_SIZE(buf),
buf);
if (ret < 0) { if (ret < 0) {
dev_err(&data->client->dev, dev_err(&data->client->dev,
"error reading status and stepcnt\n"); "error reading status and stepcnt\n");
...@@ -342,10 +347,10 @@ static int mma9553_conf_gpio(struct mma9553_data *data) ...@@ -342,10 +347,10 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
struct mma9553_event *ev_step_detect; struct mma9553_event *ev_step_detect;
bool activity_enabled; bool activity_enabled;
activity_enabled = activity_enabled = mma9553_is_any_event_enabled(data, true,
mma9553_is_any_event_enabled(data, true, IIO_ACTIVITY); IIO_ACTIVITY);
ev_step_detect = ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,
mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE); IIO_EV_DIR_NONE);
/* /*
* If both step detector and activity are enabled, use the MRGFL bit. * If both step detector and activity are enabled, use the MRGFL bit.
...@@ -371,9 +376,8 @@ static int mma9553_conf_gpio(struct mma9553_data *data) ...@@ -371,9 +376,8 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
return ret; return ret;
} }
ret = mma9551_gpio_config(data->client, ret = mma9551_gpio_config(data->client, MMA9553_DEFAULT_GPIO_PIN, appid,
MMA9553_DEFAULT_GPIO_PIN, bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
appid, bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
if (ret < 0) if (ret < 0)
return ret; return ret;
data->gpio_bitnum = bitnum; data->gpio_bitnum = bitnum;
...@@ -394,17 +398,16 @@ static int mma9553_init(struct mma9553_data *data) ...@@ -394,17 +398,16 @@ static int mma9553_init(struct mma9553_data *data)
* a device identification command to differentiate the MMA9553L * a device identification command to differentiate the MMA9553L
* from the MMA9550L. * from the MMA9550L.
*/ */
ret = ret = mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
MMA9553_REG_CONF_SLEEPMIN, MMA9553_REG_CONF_SLEEPMIN,
sizeof(data->conf), (u16 *) &data->conf); sizeof(data->conf) / sizeof(u16),
(u16 *)&data->conf);
if (ret < 0) { if (ret < 0) {
dev_err(&data->client->dev, dev_err(&data->client->dev,
"failed to read configuration registers\n"); "failed to read configuration registers\n");
return ret; return ret;
} }
/* Reset GPIO */ /* Reset GPIO */
data->gpio_bitnum = MMA9553_MAX_BITNUM; data->gpio_bitnum = MMA9553_MAX_BITNUM;
ret = mma9553_conf_gpio(data); ret = mma9553_conf_gpio(data);
...@@ -419,18 +422,18 @@ static int mma9553_init(struct mma9553_data *data) ...@@ -419,18 +422,18 @@ static int mma9553_init(struct mma9553_data *data)
data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN; data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;
data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX; data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;
data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD; data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;
data->conf.config = data->conf.config = mma9553_set_bits(data->conf.config, 1,
mma9553_set_bits(data->conf.config, 1, MMA9553_MASK_CONF_CONFIG); MMA9553_MASK_CONF_CONFIG);
/* /*
* Clear the activity debounce counter when the activity level changes, * Clear the activity debounce counter when the activity level changes,
* so that the confidence level applies for any activity level. * so that the confidence level applies for any activity level.
*/ */
data->conf.config = mma9553_set_bits(data->conf.config, 1, data->conf.config = mma9553_set_bits(data->conf.config, 1,
MMA9553_MASK_CONF_ACT_DBCNTM); MMA9553_MASK_CONF_ACT_DBCNTM);
ret = ret = mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
MMA9553_REG_CONF_SLEEPMIN, MMA9553_REG_CONF_SLEEPMIN,
sizeof(data->conf), (u16 *) &data->conf); sizeof(data->conf) / sizeof(u16),
(u16 *)&data->conf);
if (ret < 0) { if (ret < 0) {
dev_err(&data->client->dev, dev_err(&data->client->dev,
"failed to write configuration registers\n"); "failed to write configuration registers\n");
...@@ -719,7 +722,6 @@ static int mma9553_read_event_config(struct iio_dev *indio_dev, ...@@ -719,7 +722,6 @@ static int mma9553_read_event_config(struct iio_dev *indio_dev,
enum iio_event_type type, enum iio_event_type type,
enum iio_event_direction dir) enum iio_event_direction dir)
{ {
struct mma9553_data *data = iio_priv(indio_dev); struct mma9553_data *data = iio_priv(indio_dev);
struct mma9553_event *event; struct mma9553_event *event;
...@@ -1026,22 +1028,22 @@ static irqreturn_t mma9553_event_handler(int irq, void *private) ...@@ -1026,22 +1028,22 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
ev_prev_activity = ev_prev_activity = mma9553_get_event(data, IIO_ACTIVITY,
mma9553_get_event(data, IIO_ACTIVITY, mma9553_activity_to_mod(
mma9553_activity_to_mod(data->activity), data->activity),
IIO_EV_DIR_FALLING); IIO_EV_DIR_FALLING);
ev_activity = ev_activity = mma9553_get_event(data, IIO_ACTIVITY,
mma9553_get_event(data, IIO_ACTIVITY,
mma9553_activity_to_mod(activity), mma9553_activity_to_mod(activity),
IIO_EV_DIR_RISING); IIO_EV_DIR_RISING);
ev_step_detect = ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,
mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE); IIO_EV_DIR_NONE);
if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) { if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {
data->stepcnt = stepcnt; data->stepcnt = stepcnt;
iio_push_event(indio_dev, iio_push_event(indio_dev,
IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
IIO_EV_DIR_NONE, IIO_EV_TYPE_CHANGE, 0, 0, 0), IIO_EV_DIR_NONE,
IIO_EV_TYPE_CHANGE, 0, 0, 0),
data->timestamp); data->timestamp);
} }
...@@ -1053,7 +1055,8 @@ static irqreturn_t mma9553_event_handler(int irq, void *private) ...@@ -1053,7 +1055,8 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
IIO_EVENT_CODE(IIO_ACTIVITY, 0, IIO_EVENT_CODE(IIO_ACTIVITY, 0,
ev_prev_activity->info->mod, ev_prev_activity->info->mod,
IIO_EV_DIR_FALLING, IIO_EV_DIR_FALLING,
IIO_EV_TYPE_THRESH, 0, 0, 0), IIO_EV_TYPE_THRESH, 0, 0,
0),
data->timestamp); data->timestamp);
if (ev_activity && ev_activity->enabled) if (ev_activity && ev_activity->enabled)
...@@ -1061,7 +1064,8 @@ static irqreturn_t mma9553_event_handler(int irq, void *private) ...@@ -1061,7 +1064,8 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
IIO_EVENT_CODE(IIO_ACTIVITY, 0, IIO_EVENT_CODE(IIO_ACTIVITY, 0,
ev_activity->info->mod, ev_activity->info->mod,
IIO_EV_DIR_RISING, IIO_EV_DIR_RISING,
IIO_EV_TYPE_THRESH, 0, 0, 0), IIO_EV_TYPE_THRESH, 0, 0,
0),
data->timestamp); data->timestamp);
} }
mutex_unlock(&data->mutex); mutex_unlock(&data->mutex);
...@@ -1145,7 +1149,7 @@ static int mma9553_probe(struct i2c_client *client, ...@@ -1145,7 +1149,7 @@ static int mma9553_probe(struct i2c_client *client,
if (client->irq < 0) if (client->irq < 0)
client->irq = mma9553_gpio_probe(client); client->irq = mma9553_gpio_probe(client);
if (client->irq >= 0) { if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq, ret = devm_request_threaded_irq(&client->dev, client->irq,
mma9553_irq_handler, mma9553_irq_handler,
mma9553_event_handler, mma9553_event_handler,
...@@ -1156,7 +1160,6 @@ static int mma9553_probe(struct i2c_client *client, ...@@ -1156,7 +1160,6 @@ static int mma9553_probe(struct i2c_client *client,
client->irq); client->irq);
goto out_poweroff; goto out_poweroff;
} }
} }
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define LSM303DLH_ACCEL_DEV_NAME "lsm303dlh_accel" #define LSM303DLH_ACCEL_DEV_NAME "lsm303dlh_accel"
#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel" #define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel"
#define LSM330_ACCEL_DEV_NAME "lsm330_accel" #define LSM330_ACCEL_DEV_NAME "lsm330_accel"
#define LSM303AGR_ACCEL_DEV_NAME "lsm303agr_accel"
/** /**
* struct st_sensors_platform_data - default accel platform data * struct st_sensors_platform_data - default accel platform data
......
...@@ -226,12 +226,14 @@ static const struct iio_chan_spec st_accel_16bit_channels[] = { ...@@ -226,12 +226,14 @@ static const struct iio_chan_spec st_accel_16bit_channels[] = {
static const struct st_sensor_settings st_accel_sensors_settings[] = { static const struct st_sensor_settings st_accel_sensors_settings[] = {
{ {
.wai = ST_ACCEL_1_WAI_EXP, .wai = ST_ACCEL_1_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = LIS3DH_ACCEL_DEV_NAME, [0] = LIS3DH_ACCEL_DEV_NAME,
[1] = LSM303DLHC_ACCEL_DEV_NAME, [1] = LSM303DLHC_ACCEL_DEV_NAME,
[2] = LSM330D_ACCEL_DEV_NAME, [2] = LSM330D_ACCEL_DEV_NAME,
[3] = LSM330DL_ACCEL_DEV_NAME, [3] = LSM330DL_ACCEL_DEV_NAME,
[4] = LSM330DLC_ACCEL_DEV_NAME, [4] = LSM330DLC_ACCEL_DEV_NAME,
[5] = LSM303AGR_ACCEL_DEV_NAME,
}, },
.ch = (struct iio_chan_spec *)st_accel_12bit_channels, .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
.odr = { .odr = {
...@@ -297,6 +299,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { ...@@ -297,6 +299,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
}, },
{ {
.wai = ST_ACCEL_2_WAI_EXP, .wai = ST_ACCEL_2_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = LIS331DLH_ACCEL_DEV_NAME, [0] = LIS331DLH_ACCEL_DEV_NAME,
[1] = LSM303DL_ACCEL_DEV_NAME, [1] = LSM303DL_ACCEL_DEV_NAME,
...@@ -359,6 +362,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { ...@@ -359,6 +362,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
}, },
{ {
.wai = ST_ACCEL_3_WAI_EXP, .wai = ST_ACCEL_3_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = LSM330_ACCEL_DEV_NAME, [0] = LSM330_ACCEL_DEV_NAME,
}, },
...@@ -437,6 +441,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { ...@@ -437,6 +441,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
}, },
{ {
.wai = ST_ACCEL_4_WAI_EXP, .wai = ST_ACCEL_4_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = LIS3LV02DL_ACCEL_DEV_NAME, [0] = LIS3LV02DL_ACCEL_DEV_NAME,
}, },
...@@ -494,6 +499,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { ...@@ -494,6 +499,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
}, },
{ {
.wai = ST_ACCEL_5_WAI_EXP, .wai = ST_ACCEL_5_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = LIS331DL_ACCEL_DEV_NAME, [0] = LIS331DL_ACCEL_DEV_NAME,
}, },
......
...@@ -68,6 +68,10 @@ static const struct of_device_id st_accel_of_match[] = { ...@@ -68,6 +68,10 @@ static const struct of_device_id st_accel_of_match[] = {
.compatible = "st,lsm330-accel", .compatible = "st,lsm330-accel",
.data = LSM330_ACCEL_DEV_NAME, .data = LSM330_ACCEL_DEV_NAME,
}, },
{
.compatible = "st,lsm303agr-accel",
.data = LSM303AGR_ACCEL_DEV_NAME,
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, st_accel_of_match); MODULE_DEVICE_TABLE(of, st_accel_of_match);
...@@ -116,13 +120,13 @@ static const struct i2c_device_id st_accel_id_table[] = { ...@@ -116,13 +120,13 @@ static const struct i2c_device_id st_accel_id_table[] = {
{ LSM303DL_ACCEL_DEV_NAME }, { LSM303DL_ACCEL_DEV_NAME },
{ LSM303DLM_ACCEL_DEV_NAME }, { LSM303DLM_ACCEL_DEV_NAME },
{ LSM330_ACCEL_DEV_NAME }, { LSM330_ACCEL_DEV_NAME },
{ LSM303AGR_ACCEL_DEV_NAME },
{}, {},
}; };
MODULE_DEVICE_TABLE(i2c, st_accel_id_table); MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
static struct i2c_driver st_accel_driver = { static struct i2c_driver st_accel_driver = {
.driver = { .driver = {
.owner = THIS_MODULE,
.name = "st-accel-i2c", .name = "st-accel-i2c",
.of_match_table = of_match_ptr(st_accel_of_match), .of_match_table = of_match_ptr(st_accel_of_match),
}, },
......
...@@ -57,6 +57,7 @@ static const struct spi_device_id st_accel_id_table[] = { ...@@ -57,6 +57,7 @@ static const struct spi_device_id st_accel_id_table[] = {
{ LSM303DL_ACCEL_DEV_NAME }, { LSM303DL_ACCEL_DEV_NAME },
{ LSM303DLM_ACCEL_DEV_NAME }, { LSM303DLM_ACCEL_DEV_NAME },
{ LSM330_ACCEL_DEV_NAME }, { LSM330_ACCEL_DEV_NAME },
{ LSM303AGR_ACCEL_DEV_NAME },
{}, {},
}; };
MODULE_DEVICE_TABLE(spi, st_accel_id_table); MODULE_DEVICE_TABLE(spi, st_accel_id_table);
......
...@@ -11,17 +11,25 @@ ...@@ -11,17 +11,25 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#define STK8312_REG_XOUT 0x00 #define STK8312_REG_XOUT 0x00
#define STK8312_REG_YOUT 0x01 #define STK8312_REG_YOUT 0x01
#define STK8312_REG_ZOUT 0x02 #define STK8312_REG_ZOUT 0x02
#define STK8312_REG_INTSU 0x06
#define STK8312_REG_MODE 0x07 #define STK8312_REG_MODE 0x07
#define STK8312_REG_SR 0x08
#define STK8312_REG_STH 0x13 #define STK8312_REG_STH 0x13
#define STK8312_REG_RESET 0x20 #define STK8312_REG_RESET 0x20
#define STK8312_REG_AFECTRL 0x24 #define STK8312_REG_AFECTRL 0x24
...@@ -29,14 +37,21 @@ ...@@ -29,14 +37,21 @@
#define STK8312_REG_OTPDATA 0x3E #define STK8312_REG_OTPDATA 0x3E
#define STK8312_REG_OTPCTRL 0x3F #define STK8312_REG_OTPCTRL 0x3F
#define STK8312_MODE_ACTIVE 1 #define STK8312_MODE_ACTIVE BIT(0)
#define STK8312_MODE_STANDBY 0 #define STK8312_MODE_STANDBY 0x00
#define STK8312_MODE_MASK 0x01 #define STK8312_MODE_INT_AH_PP 0xC0 /* active-high, push-pull */
#define STK8312_RNG_MASK 0xC0 #define STK8312_DREADY_BIT BIT(4)
#define STK8312_RNG_6G 1
#define STK8312_RNG_SHIFT 6 #define STK8312_RNG_SHIFT 6
#define STK8312_READ_RETRIES 16 #define STK8312_RNG_MASK GENMASK(7, 6)
#define STK8312_SR_MASK GENMASK(2, 0)
#define STK8312_SR_400HZ_IDX 0
#define STK8312_ALL_CHANNEL_MASK GENMASK(2, 0)
#define STK8312_ALL_CHANNEL_SIZE 3
#define STK8312_DRIVER_NAME "stk8312" #define STK8312_DRIVER_NAME "stk8312"
#define STK8312_GPIO "stk8312_gpio"
#define STK8312_IRQ_NAME "stk8312_event"
/* /*
* The accelerometer has two measurement ranges: * The accelerometer has two measurement ranges:
...@@ -53,32 +68,56 @@ static const int stk8312_scale_table[][2] = { ...@@ -53,32 +68,56 @@ static const int stk8312_scale_table[][2] = {
{0, 461600}, {1, 231100} {0, 461600}, {1, 231100}
}; };
#define STK8312_ACCEL_CHANNEL(reg, axis) { \ static const struct {
int val;
int val2;
} stk8312_samp_freq_table[] = {
{400, 0}, {200, 0}, {100, 0}, {50, 0}, {25, 0},
{12, 500000}, {6, 250000}, {3, 125000}
};
#define STK8312_ACCEL_CHANNEL(index, reg, axis) { \
.type = IIO_ACCEL, \ .type = IIO_ACCEL, \
.address = reg, \ .address = reg, \
.modified = 1, \ .modified = 1, \
.channel2 = IIO_MOD_##axis, \ .channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = index, \
.scan_type = { \
.sign = 's', \
.realbits = 8, \
.storagebits = 8, \
.endianness = IIO_CPU, \
}, \
} }
static const struct iio_chan_spec stk8312_channels[] = { static const struct iio_chan_spec stk8312_channels[] = {
STK8312_ACCEL_CHANNEL(STK8312_REG_XOUT, X), STK8312_ACCEL_CHANNEL(0, STK8312_REG_XOUT, X),
STK8312_ACCEL_CHANNEL(STK8312_REG_YOUT, Y), STK8312_ACCEL_CHANNEL(1, STK8312_REG_YOUT, Y),
STK8312_ACCEL_CHANNEL(STK8312_REG_ZOUT, Z), STK8312_ACCEL_CHANNEL(2, STK8312_REG_ZOUT, Z),
IIO_CHAN_SOFT_TIMESTAMP(3),
}; };
struct stk8312_data { struct stk8312_data {
struct i2c_client *client; struct i2c_client *client;
struct mutex lock; struct mutex lock;
int range; u8 range;
u8 sample_rate_idx;
u8 mode; u8 mode;
struct iio_trigger *dready_trig;
bool dready_trigger_on;
s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */
}; };
static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL); static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("3.125 6.25 12.5 25 50 100 200 400");
static struct attribute *stk8312_attributes[] = { static struct attribute *stk8312_attributes[] = {
&iio_const_attr_in_accel_scale_available.dev_attr.attr, &iio_const_attr_in_accel_scale_available.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL, NULL,
}; };
...@@ -105,22 +144,25 @@ static int stk8312_otp_init(struct stk8312_data *data) ...@@ -105,22 +144,25 @@ static int stk8312_otp_init(struct stk8312_data *data)
if (ret < 0) if (ret < 0)
goto exit_err; goto exit_err;
count--; count--;
} while (!(ret & 0x80) && count > 0); } while (!(ret & BIT(7)) && count > 0);
if (count == 0) if (count == 0) {
ret = -ETIMEDOUT;
goto exit_err; goto exit_err;
}
ret = i2c_smbus_read_byte_data(client, STK8312_REG_OTPDATA); ret = i2c_smbus_read_byte_data(client, STK8312_REG_OTPDATA);
if (ret == 0)
ret = -EINVAL;
if (ret < 0) if (ret < 0)
goto exit_err; goto exit_err;
ret = i2c_smbus_write_byte_data(data->client, ret = i2c_smbus_write_byte_data(data->client, STK8312_REG_AFECTRL, ret);
STK8312_REG_AFECTRL, ret);
if (ret < 0) if (ret < 0)
goto exit_err; goto exit_err;
msleep(150); msleep(150);
return ret; return 0;
exit_err: exit_err:
dev_err(&client->dev, "failed to initialize sensor\n"); dev_err(&client->dev, "failed to initialize sensor\n");
...@@ -130,31 +172,19 @@ static int stk8312_otp_init(struct stk8312_data *data) ...@@ -130,31 +172,19 @@ static int stk8312_otp_init(struct stk8312_data *data)
static int stk8312_set_mode(struct stk8312_data *data, u8 mode) static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
{ {
int ret; int ret;
u8 masked_reg;
struct i2c_client *client = data->client; struct i2c_client *client = data->client;
if (mode > 1) if (mode == data->mode)
return -EINVAL;
else if (mode == data->mode)
return 0; return 0;
ret = i2c_smbus_read_byte_data(client, STK8312_REG_MODE); ret = i2c_smbus_write_byte_data(client, STK8312_REG_MODE, mode);
if (ret < 0) {
dev_err(&client->dev, "failed to change sensor mode\n");
return ret;
}
masked_reg = ret & (~STK8312_MODE_MASK);
masked_reg |= mode;
ret = i2c_smbus_write_byte_data(client,
STK8312_REG_MODE, masked_reg);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "failed to change sensor mode\n"); dev_err(&client->dev, "failed to change sensor mode\n");
return ret; return ret;
} }
data->mode = mode; data->mode = mode;
if (mode == STK8312_MODE_ACTIVE) { if (mode & STK8312_MODE_ACTIVE) {
/* Need to run OTP sequence before entering active mode */ /* Need to run OTP sequence before entering active mode */
usleep_range(1000, 5000); usleep_range(1000, 5000);
ret = stk8312_otp_init(data); ret = stk8312_otp_init(data);
...@@ -163,6 +193,92 @@ static int stk8312_set_mode(struct stk8312_data *data, u8 mode) ...@@ -163,6 +193,92 @@ static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
return ret; return ret;
} }
static int stk8312_set_interrupts(struct stk8312_data *data, u8 int_mask)
{
int ret;
u8 mode;
struct i2c_client *client = data->client;
mode = data->mode;
/* We need to go in standby mode to modify registers */
ret = stk8312_set_mode(data, STK8312_MODE_STANDBY);
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(client, STK8312_REG_INTSU, int_mask);
if (ret < 0) {
dev_err(&client->dev, "failed to set interrupts\n");
stk8312_set_mode(data, mode);
return ret;
}
return stk8312_set_mode(data, mode);
}
static int stk8312_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct stk8312_data *data = iio_priv(indio_dev);
int ret;
if (state)
ret = stk8312_set_interrupts(data, STK8312_DREADY_BIT);
else
ret = stk8312_set_interrupts(data, 0x00);
if (ret < 0) {
dev_err(&data->client->dev, "failed to set trigger state\n");
return ret;
}
data->dready_trigger_on = state;
return 0;
}
static const struct iio_trigger_ops stk8312_trigger_ops = {
.set_trigger_state = stk8312_data_rdy_trigger_set_state,
.owner = THIS_MODULE,
};
static int stk8312_set_sample_rate(struct stk8312_data *data, u8 rate)
{
int ret;
u8 masked_reg;
u8 mode;
struct i2c_client *client = data->client;
if (rate == data->sample_rate_idx)
return 0;
mode = data->mode;
/* We need to go in standby mode to modify registers */
ret = stk8312_set_mode(data, STK8312_MODE_STANDBY);
if (ret < 0)
return ret;
ret = i2c_smbus_read_byte_data(client, STK8312_REG_SR);
if (ret < 0)
goto err_activate;
masked_reg = (ret & (~STK8312_SR_MASK)) | rate;
ret = i2c_smbus_write_byte_data(client, STK8312_REG_SR, masked_reg);
if (ret < 0)
goto err_activate;
data->sample_rate_idx = rate;
return stk8312_set_mode(data, mode);
err_activate:
dev_err(&client->dev, "failed to set sampling rate\n");
stk8312_set_mode(data, mode);
return ret;
}
static int stk8312_set_range(struct stk8312_data *data, u8 range) static int stk8312_set_range(struct stk8312_data *data, u8 range)
{ {
int ret; int ret;
...@@ -182,21 +298,25 @@ static int stk8312_set_range(struct stk8312_data *data, u8 range) ...@@ -182,21 +298,25 @@ static int stk8312_set_range(struct stk8312_data *data, u8 range)
return ret; return ret;
ret = i2c_smbus_read_byte_data(client, STK8312_REG_STH); ret = i2c_smbus_read_byte_data(client, STK8312_REG_STH);
if (ret < 0) { if (ret < 0)
dev_err(&client->dev, "failed to change sensor range\n"); goto err_activate;
return ret;
}
masked_reg = ret & (~STK8312_RNG_MASK); masked_reg = ret & (~STK8312_RNG_MASK);
masked_reg |= range << STK8312_RNG_SHIFT; masked_reg |= range << STK8312_RNG_SHIFT;
ret = i2c_smbus_write_byte_data(client, STK8312_REG_STH, masked_reg); ret = i2c_smbus_write_byte_data(client, STK8312_REG_STH, masked_reg);
if (ret < 0) if (ret < 0)
dev_err(&client->dev, "failed to change sensor range\n"); goto err_activate;
else
data->range = range; data->range = range;
return stk8312_set_mode(data, mode); return stk8312_set_mode(data, mode);
err_activate:
dev_err(&client->dev, "failed to change sensor range\n");
stk8312_set_mode(data, mode);
return ret;
} }
static int stk8312_read_accel(struct stk8312_data *data, u8 address) static int stk8312_read_accel(struct stk8312_data *data, u8 address)
...@@ -208,12 +328,10 @@ static int stk8312_read_accel(struct stk8312_data *data, u8 address) ...@@ -208,12 +328,10 @@ static int stk8312_read_accel(struct stk8312_data *data, u8 address)
return -EINVAL; return -EINVAL;
ret = i2c_smbus_read_byte_data(client, address); ret = i2c_smbus_read_byte_data(client, address);
if (ret < 0) { if (ret < 0)
dev_err(&client->dev, "register read failed\n"); dev_err(&client->dev, "register read failed\n");
return ret;
}
return sign_extend32(ret, 7); return ret;
} }
static int stk8312_read_raw(struct iio_dev *indio_dev, static int stk8312_read_raw(struct iio_dev *indio_dev,
...@@ -221,20 +339,40 @@ static int stk8312_read_raw(struct iio_dev *indio_dev, ...@@ -221,20 +339,40 @@ static int stk8312_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask) int *val, int *val2, long mask)
{ {
struct stk8312_data *data = iio_priv(indio_dev); struct stk8312_data *data = iio_priv(indio_dev);
int ret;
if (chan->type != IIO_ACCEL)
return -EINVAL;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
if (iio_buffer_enabled(indio_dev))
return -EBUSY;
mutex_lock(&data->lock); mutex_lock(&data->lock);
*val = stk8312_read_accel(data, chan->address); ret = stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
if (ret < 0) {
mutex_unlock(&data->lock);
return ret;
}
ret = stk8312_read_accel(data, chan->address);
if (ret < 0) {
stk8312_set_mode(data,
data->mode & (~STK8312_MODE_ACTIVE));
mutex_unlock(&data->lock);
return ret;
}
*val = sign_extend32(ret, 7);
ret = stk8312_set_mode(data,
data->mode & (~STK8312_MODE_ACTIVE));
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
if (ret < 0)
return ret;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = stk8312_scale_table[data->range - 1][0]; *val = stk8312_scale_table[data->range - 1][0];
*val2 = stk8312_scale_table[data->range - 1][1]; *val2 = stk8312_scale_table[data->range - 1][1];
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = stk8312_samp_freq_table[data->sample_rate_idx].val;
*val2 = stk8312_samp_freq_table[data->sample_rate_idx].val2;
return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
...@@ -264,6 +402,20 @@ static int stk8312_write_raw(struct iio_dev *indio_dev, ...@@ -264,6 +402,20 @@ static int stk8312_write_raw(struct iio_dev *indio_dev,
ret = stk8312_set_range(data, index); ret = stk8312_set_range(data, index);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
for (i = 0; i < ARRAY_SIZE(stk8312_samp_freq_table); i++)
if (val == stk8312_samp_freq_table[i].val &&
val2 == stk8312_samp_freq_table[i].val2) {
index = i;
break;
}
if (index < 0)
return -EINVAL;
mutex_lock(&data->lock);
ret = stk8312_set_sample_rate(data, index);
mutex_unlock(&data->lock);
return ret; return ret;
} }
...@@ -277,6 +429,105 @@ static const struct iio_info stk8312_info = { ...@@ -277,6 +429,105 @@ static const struct iio_info stk8312_info = {
.attrs = &stk8312_attribute_group, .attrs = &stk8312_attribute_group,
}; };
static irqreturn_t stk8312_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct stk8312_data *data = iio_priv(indio_dev);
int bit, ret, i = 0;
mutex_lock(&data->lock);
/*
* Do a bulk read if all channels are requested,
* from 0x00 (XOUT) to 0x02 (ZOUT)
*/
if (*(indio_dev->active_scan_mask) == STK8312_ALL_CHANNEL_MASK) {
ret = i2c_smbus_read_i2c_block_data(data->client,
STK8312_REG_XOUT,
STK8312_ALL_CHANNEL_SIZE,
data->buffer);
if (ret < STK8312_ALL_CHANNEL_SIZE) {
dev_err(&data->client->dev, "register read failed\n");
mutex_unlock(&data->lock);
goto err;
}
} else {
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = stk8312_read_accel(data, bit);
if (ret < 0) {
mutex_unlock(&data->lock);
goto err;
}
data->buffer[i++] = ret;
}
}
mutex_unlock(&data->lock);
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
pf->timestamp);
err:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static irqreturn_t stk8312_data_rdy_trig_poll(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct stk8312_data *data = iio_priv(indio_dev);
if (data->dready_trigger_on)
iio_trigger_poll(data->dready_trig);
return IRQ_HANDLED;
}
static int stk8312_buffer_preenable(struct iio_dev *indio_dev)
{
struct stk8312_data *data = iio_priv(indio_dev);
return stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
}
static int stk8312_buffer_postdisable(struct iio_dev *indio_dev)
{
struct stk8312_data *data = iio_priv(indio_dev);
return stk8312_set_mode(data, data->mode & (~STK8312_MODE_ACTIVE));
}
static const struct iio_buffer_setup_ops stk8312_buffer_setup_ops = {
.preenable = stk8312_buffer_preenable,
.postenable = iio_triggered_buffer_postenable,
.predisable = iio_triggered_buffer_predisable,
.postdisable = stk8312_buffer_postdisable,
};
static int stk8312_gpio_probe(struct i2c_client *client)
{
struct device *dev;
struct gpio_desc *gpio;
int ret;
if (!client)
return -EINVAL;
dev = &client->dev;
/* data ready gpio interrupt pin */
gpio = devm_gpiod_get_index(dev, STK8312_GPIO, 0, GPIOD_IN);
if (IS_ERR(gpio)) {
dev_err(dev, "acpi gpio get index failed\n");
return PTR_ERR(gpio);
}
ret = gpiod_to_irq(gpio);
dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
return ret;
}
static int stk8312_probe(struct i2c_client *client, static int stk8312_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -308,30 +559,91 @@ static int stk8312_probe(struct i2c_client *client, ...@@ -308,30 +559,91 @@ static int stk8312_probe(struct i2c_client *client,
dev_err(&client->dev, "failed to reset sensor\n"); dev_err(&client->dev, "failed to reset sensor\n");
return ret; return ret;
} }
ret = stk8312_set_range(data, 1); data->sample_rate_idx = STK8312_SR_400HZ_IDX;
ret = stk8312_set_range(data, STK8312_RNG_6G);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = stk8312_set_mode(data, STK8312_MODE_ACTIVE); ret = stk8312_set_mode(data,
STK8312_MODE_INT_AH_PP | STK8312_MODE_ACTIVE);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (client->irq < 0)
client->irq = stk8312_gpio_probe(client);
if (client->irq >= 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
stk8312_data_rdy_trig_poll,
NULL,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT,
STK8312_IRQ_NAME,
indio_dev);
if (ret < 0) {
dev_err(&client->dev, "request irq %d failed\n",
client->irq);
goto err_power_off;
}
data->dready_trig = devm_iio_trigger_alloc(&client->dev,
"%s-dev%d",
indio_dev->name,
indio_dev->id);
if (!data->dready_trig) {
ret = -ENOMEM;
goto err_power_off;
}
data->dready_trig->dev.parent = &client->dev;
data->dready_trig->ops = &stk8312_trigger_ops;
iio_trigger_set_drvdata(data->dready_trig, indio_dev);
ret = iio_trigger_register(data->dready_trig);
if (ret) {
dev_err(&client->dev, "iio trigger register failed\n");
goto err_power_off;
}
}
ret = iio_triggered_buffer_setup(indio_dev,
iio_pollfunc_store_time,
stk8312_trigger_handler,
&stk8312_buffer_setup_ops);
if (ret < 0) {
dev_err(&client->dev, "iio triggered buffer setup failed\n");
goto err_trigger_unregister;
}
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "device_register failed\n"); dev_err(&client->dev, "device_register failed\n");
stk8312_set_mode(data, STK8312_MODE_STANDBY); goto err_buffer_cleanup;
} }
return 0;
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_trigger_unregister:
if (data->dready_trig)
iio_trigger_unregister(data->dready_trig);
err_power_off:
stk8312_set_mode(data, STK8312_MODE_STANDBY);
return ret; return ret;
} }
static int stk8312_remove(struct i2c_client *client) static int stk8312_remove(struct i2c_client *client)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(client); struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct stk8312_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (data->dready_trig)
iio_trigger_unregister(data->dready_trig);
return stk8312_set_mode(iio_priv(indio_dev), STK8312_MODE_STANDBY); return stk8312_set_mode(data, STK8312_MODE_STANDBY);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -341,7 +653,7 @@ static int stk8312_suspend(struct device *dev) ...@@ -341,7 +653,7 @@ static int stk8312_suspend(struct device *dev)
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev))); data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
return stk8312_set_mode(data, STK8312_MODE_STANDBY); return stk8312_set_mode(data, data->mode & (~STK8312_MODE_ACTIVE));
} }
static int stk8312_resume(struct device *dev) static int stk8312_resume(struct device *dev)
...@@ -350,7 +662,7 @@ static int stk8312_resume(struct device *dev) ...@@ -350,7 +662,7 @@ static int stk8312_resume(struct device *dev)
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev))); data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
return stk8312_set_mode(data, STK8312_MODE_ACTIVE); return stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
} }
static SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend, stk8312_resume); static SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend, stk8312_resume);
...@@ -364,6 +676,7 @@ static const struct i2c_device_id stk8312_i2c_id[] = { ...@@ -364,6 +676,7 @@ static const struct i2c_device_id stk8312_i2c_id[] = {
{"STK8312", 0}, {"STK8312", 0},
{} {}
}; };
MODULE_DEVICE_TABLE(i2c, stk8312_i2c_id);
static const struct acpi_device_id stk8312_acpi_id[] = { static const struct acpi_device_id stk8312_acpi_id[] = {
{"STK8312", 0}, {"STK8312", 0},
...@@ -374,7 +687,7 @@ MODULE_DEVICE_TABLE(acpi, stk8312_acpi_id); ...@@ -374,7 +687,7 @@ MODULE_DEVICE_TABLE(acpi, stk8312_acpi_id);
static struct i2c_driver stk8312_driver = { static struct i2c_driver stk8312_driver = {
.driver = { .driver = {
.name = "stk8312", .name = STK8312_DRIVER_NAME,
.pm = STK8312_PM_OPS, .pm = STK8312_PM_OPS,
.acpi_match_table = ACPI_PTR(stk8312_acpi_id), .acpi_match_table = ACPI_PTR(stk8312_acpi_id),
}, },
......
...@@ -11,26 +11,42 @@ ...@@ -11,26 +11,42 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#define STK8BA50_REG_XOUT 0x02 #define STK8BA50_REG_XOUT 0x02
#define STK8BA50_REG_YOUT 0x04 #define STK8BA50_REG_YOUT 0x04
#define STK8BA50_REG_ZOUT 0x06 #define STK8BA50_REG_ZOUT 0x06
#define STK8BA50_REG_RANGE 0x0F #define STK8BA50_REG_RANGE 0x0F
#define STK8BA50_REG_BWSEL 0x10
#define STK8BA50_REG_POWMODE 0x11 #define STK8BA50_REG_POWMODE 0x11
#define STK8BA50_REG_SWRST 0x14 #define STK8BA50_REG_SWRST 0x14
#define STK8BA50_REG_INTEN2 0x17
#define STK8BA50_REG_INTMAP2 0x1A
#define STK8BA50_MODE_NORMAL 0 #define STK8BA50_MODE_NORMAL 0
#define STK8BA50_MODE_SUSPEND 1 #define STK8BA50_MODE_SUSPEND 1
#define STK8BA50_MODE_POWERBIT BIT(7) #define STK8BA50_MODE_POWERBIT BIT(7)
#define STK8BA50_DATA_SHIFT 6 #define STK8BA50_DATA_SHIFT 6
#define STK8BA50_RESET_CMD 0xB6 #define STK8BA50_RESET_CMD 0xB6
#define STK8BA50_SR_1792HZ_IDX 7
#define STK8BA50_DREADY_INT_MASK 0x10
#define STK8BA50_DREADY_INT_MAP 0x81
#define STK8BA50_ALL_CHANNEL_MASK 7
#define STK8BA50_ALL_CHANNEL_SIZE 6
#define STK8BA50_DRIVER_NAME "stk8ba50" #define STK8BA50_DRIVER_NAME "stk8ba50"
#define STK8BA50_GPIO "stk8ba50_gpio"
#define STK8BA50_IRQ_NAME "stk8ba50_event"
#define STK8BA50_SCALE_AVAIL "0.0384 0.0767 0.1534 0.3069" #define STK8BA50_SCALE_AVAIL "0.0384 0.0767 0.1534 0.3069"
...@@ -50,35 +66,76 @@ ...@@ -50,35 +66,76 @@
* *
* Locally, the range is stored as a table index. * Locally, the range is stored as a table index.
*/ */
static const int stk8ba50_scale_table[][2] = { static const struct {
u8 reg_val;
u32 scale_val;
} stk8ba50_scale_table[] = {
{3, 38400}, {5, 76700}, {8, 153400}, {12, 306900} {3, 38400}, {5, 76700}, {8, 153400}, {12, 306900}
}; };
/* Sample rates are stored as { <register value>, <Hz value> } */
static const struct {
u8 reg_val;
u16 samp_freq;
} stk8ba50_samp_freq_table[] = {
{0x08, 14}, {0x09, 25}, {0x0A, 56}, {0x0B, 112},
{0x0C, 224}, {0x0D, 448}, {0x0E, 896}, {0x0F, 1792}
};
/* Used to map scan mask bits to their corresponding channel register. */
static const int stk8ba50_channel_table[] = {
STK8BA50_REG_XOUT,
STK8BA50_REG_YOUT,
STK8BA50_REG_ZOUT
};
struct stk8ba50_data { struct stk8ba50_data {
struct i2c_client *client; struct i2c_client *client;
struct mutex lock; struct mutex lock;
int range; int range;
u8 sample_rate_idx;
struct iio_trigger *dready_trig;
bool dready_trigger_on;
/*
* 3 x 16-bit channels (10-bit data, 6-bit padding) +
* 1 x 16 padding +
* 4 x 16 64-bit timestamp
*/
s16 buffer[8];
}; };
#define STK8BA50_ACCEL_CHANNEL(reg, axis) { \ #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) { \
.type = IIO_ACCEL, \ .type = IIO_ACCEL, \
.address = reg, \ .address = reg, \
.modified = 1, \ .modified = 1, \
.channel2 = IIO_MOD_##axis, \ .channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = index, \
.scan_type = { \
.sign = 's', \
.realbits = 10, \
.storagebits = 16, \
.shift = STK8BA50_DATA_SHIFT, \
.endianness = IIO_CPU, \
}, \
} }
static const struct iio_chan_spec stk8ba50_channels[] = { static const struct iio_chan_spec stk8ba50_channels[] = {
STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_XOUT, X), STK8BA50_ACCEL_CHANNEL(0, STK8BA50_REG_XOUT, X),
STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_YOUT, Y), STK8BA50_ACCEL_CHANNEL(1, STK8BA50_REG_YOUT, Y),
STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_ZOUT, Z), STK8BA50_ACCEL_CHANNEL(2, STK8BA50_REG_ZOUT, Z),
IIO_CHAN_SOFT_TIMESTAMP(3),
}; };
static IIO_CONST_ATTR(in_accel_scale_available, STK8BA50_SCALE_AVAIL); static IIO_CONST_ATTR(in_accel_scale_available, STK8BA50_SCALE_AVAIL);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("14 25 56 112 224 448 896 1792");
static struct attribute *stk8ba50_attributes[] = { static struct attribute *stk8ba50_attributes[] = {
&iio_const_attr_in_accel_scale_available.dev_attr.attr, &iio_const_attr_in_accel_scale_available.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL, NULL,
}; };
...@@ -97,7 +154,61 @@ static int stk8ba50_read_accel(struct stk8ba50_data *data, u8 reg) ...@@ -97,7 +154,61 @@ static int stk8ba50_read_accel(struct stk8ba50_data *data, u8 reg)
return ret; return ret;
} }
return sign_extend32(ret >> STK8BA50_DATA_SHIFT, 9); return ret;
}
static int stk8ba50_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct stk8ba50_data *data = iio_priv(indio_dev);
int ret;
if (state)
ret = i2c_smbus_write_byte_data(data->client,
STK8BA50_REG_INTEN2, STK8BA50_DREADY_INT_MASK);
else
ret = i2c_smbus_write_byte_data(data->client,
STK8BA50_REG_INTEN2, 0x00);
if (ret < 0)
dev_err(&data->client->dev, "failed to set trigger state\n");
else
data->dready_trigger_on = state;
return ret;
}
static const struct iio_trigger_ops stk8ba50_trigger_ops = {
.set_trigger_state = stk8ba50_data_rdy_trigger_set_state,
.owner = THIS_MODULE,
};
static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode)
{
int ret;
u8 masked_reg;
struct i2c_client *client = data->client;
ret = i2c_smbus_read_byte_data(client, STK8BA50_REG_POWMODE);
if (ret < 0)
goto exit_err;
if (mode)
masked_reg = ret | STK8BA50_MODE_POWERBIT;
else
masked_reg = ret & (~STK8BA50_MODE_POWERBIT);
ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE,
masked_reg);
if (ret < 0)
goto exit_err;
return ret;
exit_err:
dev_err(&client->dev, "failed to change sensor mode\n");
return ret;
} }
static int stk8ba50_read_raw(struct iio_dev *indio_dev, static int stk8ba50_read_raw(struct iio_dev *indio_dev,
...@@ -105,17 +216,37 @@ static int stk8ba50_read_raw(struct iio_dev *indio_dev, ...@@ -105,17 +216,37 @@ static int stk8ba50_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask) int *val, int *val2, long mask)
{ {
struct stk8ba50_data *data = iio_priv(indio_dev); struct stk8ba50_data *data = iio_priv(indio_dev);
int ret;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
if (iio_buffer_enabled(indio_dev))
return -EBUSY;
mutex_lock(&data->lock); mutex_lock(&data->lock);
*val = stk8ba50_read_accel(data, chan->address); ret = stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
if (ret < 0) {
mutex_unlock(&data->lock);
return -EINVAL;
}
ret = stk8ba50_read_accel(data, chan->address);
if (ret < 0) {
stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
mutex_unlock(&data->lock);
return -EINVAL;
}
*val = sign_extend32(ret >> STK8BA50_DATA_SHIFT, 9);
stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = 0; *val = 0;
*val2 = stk8ba50_scale_table[data->range][1]; *val2 = stk8ba50_scale_table[data->range].scale_val;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = stk8ba50_samp_freq_table
[data->sample_rate_idx].samp_freq;
*val2 = 0;
return IIO_VAL_INT;
} }
return -EINVAL; return -EINVAL;
...@@ -136,7 +267,7 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev, ...@@ -136,7 +267,7 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev,
return -EINVAL; return -EINVAL;
for (i = 0; i < ARRAY_SIZE(stk8ba50_scale_table); i++) for (i = 0; i < ARRAY_SIZE(stk8ba50_scale_table); i++)
if (val2 == stk8ba50_scale_table[i][1]) { if (val2 == stk8ba50_scale_table[i].scale_val) {
index = i; index = i;
break; break;
} }
...@@ -145,13 +276,32 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev, ...@@ -145,13 +276,32 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev,
ret = i2c_smbus_write_byte_data(data->client, ret = i2c_smbus_write_byte_data(data->client,
STK8BA50_REG_RANGE, STK8BA50_REG_RANGE,
stk8ba50_scale_table[index][0]); stk8ba50_scale_table[index].reg_val);
if (ret < 0) if (ret < 0)
dev_err(&data->client->dev, dev_err(&data->client->dev,
"failed to set measurement range\n"); "failed to set measurement range\n");
else else
data->range = index; data->range = index;
return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
for (i = 0; i < ARRAY_SIZE(stk8ba50_samp_freq_table); i++)
if (val == stk8ba50_samp_freq_table[i].samp_freq) {
index = i;
break;
}
if (index < 0)
return -EINVAL;
ret = i2c_smbus_write_byte_data(data->client,
STK8BA50_REG_BWSEL,
stk8ba50_samp_freq_table[index].reg_val);
if (ret < 0)
dev_err(&data->client->dev,
"failed to set sampling rate\n");
else
data->sample_rate_idx = index;
return ret; return ret;
} }
...@@ -165,30 +315,100 @@ static const struct iio_info stk8ba50_info = { ...@@ -165,30 +315,100 @@ static const struct iio_info stk8ba50_info = {
.attrs = &stk8ba50_attribute_group, .attrs = &stk8ba50_attribute_group,
}; };
static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode) static irqreturn_t stk8ba50_trigger_handler(int irq, void *p)
{ {
int ret; struct iio_poll_func *pf = p;
u8 masked_reg; struct iio_dev *indio_dev = pf->indio_dev;
struct i2c_client *client = data->client; struct stk8ba50_data *data = iio_priv(indio_dev);
int bit, ret, i = 0;
ret = i2c_smbus_read_byte_data(client, STK8BA50_REG_POWMODE); mutex_lock(&data->lock);
/*
* Do a bulk read if all channels are requested,
* from 0x02 (XOUT1) to 0x07 (ZOUT2)
*/
if (*(indio_dev->active_scan_mask) == STK8BA50_ALL_CHANNEL_MASK) {
ret = i2c_smbus_read_i2c_block_data(data->client,
STK8BA50_REG_XOUT,
STK8BA50_ALL_CHANNEL_SIZE,
(u8 *)data->buffer);
if (ret < STK8BA50_ALL_CHANNEL_SIZE) {
dev_err(&data->client->dev, "register read failed\n");
goto err;
}
} else {
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
ret = stk8ba50_read_accel(data,
stk8ba50_channel_table[bit]);
if (ret < 0) if (ret < 0)
goto exit_err; goto err;
if (mode) data->buffer[i++] = ret;
masked_reg = ret | STK8BA50_MODE_POWERBIT; }
else }
masked_reg = ret & (~STK8BA50_MODE_POWERBIT); iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
pf->timestamp);
err:
mutex_unlock(&data->lock);
iio_trigger_notify_done(indio_dev->trig);
ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE, return IRQ_HANDLED;
masked_reg); }
if (ret < 0)
goto exit_err;
return ret; static irqreturn_t stk8ba50_data_rdy_trig_poll(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct stk8ba50_data *data = iio_priv(indio_dev);
if (data->dready_trigger_on)
iio_trigger_poll(data->dready_trig);
return IRQ_HANDLED;
}
static int stk8ba50_buffer_preenable(struct iio_dev *indio_dev)
{
struct stk8ba50_data *data = iio_priv(indio_dev);
return stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
}
static int stk8ba50_buffer_postdisable(struct iio_dev *indio_dev)
{
struct stk8ba50_data *data = iio_priv(indio_dev);
return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
}
static const struct iio_buffer_setup_ops stk8ba50_buffer_setup_ops = {
.preenable = stk8ba50_buffer_preenable,
.postenable = iio_triggered_buffer_postenable,
.predisable = iio_triggered_buffer_predisable,
.postdisable = stk8ba50_buffer_postdisable,
};
static int stk8ba50_gpio_probe(struct i2c_client *client)
{
struct device *dev;
struct gpio_desc *gpio;
int ret;
if (!client)
return -EINVAL;
dev = &client->dev;
/* data ready gpio interrupt pin */
gpio = devm_gpiod_get_index(dev, STK8BA50_GPIO, 0, GPIOD_IN);
if (IS_ERR(gpio)) {
dev_err(dev, "acpi gpio get index failed\n");
return PTR_ERR(gpio);
}
ret = gpiod_to_irq(gpio);
dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
exit_err:
dev_err(&client->dev, "failed to change sensor mode\n");
return ret; return ret;
} }
...@@ -222,28 +442,104 @@ static int stk8ba50_probe(struct i2c_client *client, ...@@ -222,28 +442,104 @@ static int stk8ba50_probe(struct i2c_client *client,
STK8BA50_REG_SWRST, STK8BA50_RESET_CMD); STK8BA50_REG_SWRST, STK8BA50_RESET_CMD);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "failed to reset sensor\n"); dev_err(&client->dev, "failed to reset sensor\n");
return ret; goto err_power_off;
} }
/* The default range is +/-2g */ /* The default range is +/-2g */
data->range = 0; data->range = 0;
/* The default sampling rate is 1792 Hz (maximum) */
data->sample_rate_idx = STK8BA50_SR_1792HZ_IDX;
/* Set up interrupts */
ret = i2c_smbus_write_byte_data(client,
STK8BA50_REG_INTEN2, STK8BA50_DREADY_INT_MASK);
if (ret < 0) {
dev_err(&client->dev, "failed to set up interrupts\n");
goto err_power_off;
}
ret = i2c_smbus_write_byte_data(client,
STK8BA50_REG_INTMAP2, STK8BA50_DREADY_INT_MAP);
if (ret < 0) {
dev_err(&client->dev, "failed to set up interrupts\n");
goto err_power_off;
}
if (client->irq < 0)
client->irq = stk8ba50_gpio_probe(client);
if (client->irq >= 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
stk8ba50_data_rdy_trig_poll,
NULL,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT,
STK8BA50_IRQ_NAME,
indio_dev);
if (ret < 0) {
dev_err(&client->dev, "request irq %d failed\n",
client->irq);
goto err_power_off;
}
data->dready_trig = devm_iio_trigger_alloc(&client->dev,
"%s-dev%d",
indio_dev->name,
indio_dev->id);
if (!data->dready_trig) {
ret = -ENOMEM;
goto err_power_off;
}
data->dready_trig->dev.parent = &client->dev;
data->dready_trig->ops = &stk8ba50_trigger_ops;
iio_trigger_set_drvdata(data->dready_trig, indio_dev);
ret = iio_trigger_register(data->dready_trig);
if (ret) {
dev_err(&client->dev, "iio trigger register failed\n");
goto err_power_off;
}
}
ret = iio_triggered_buffer_setup(indio_dev,
iio_pollfunc_store_time,
stk8ba50_trigger_handler,
&stk8ba50_buffer_setup_ops);
if (ret < 0) {
dev_err(&client->dev, "iio triggered buffer setup failed\n");
goto err_trigger_unregister;
}
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "device_register failed\n"); dev_err(&client->dev, "device_register failed\n");
stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND); goto err_buffer_cleanup;
} }
return ret; return ret;
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_trigger_unregister:
if (data->dready_trig)
iio_trigger_unregister(data->dready_trig);
err_power_off:
stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
return ret;
} }
static int stk8ba50_remove(struct i2c_client *client) static int stk8ba50_remove(struct i2c_client *client)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(client); struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct stk8ba50_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
return stk8ba50_set_power(iio_priv(indio_dev), STK8BA50_MODE_SUSPEND); if (data->dready_trig)
iio_trigger_unregister(data->dready_trig);
return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -276,6 +572,7 @@ static const struct i2c_device_id stk8ba50_i2c_id[] = { ...@@ -276,6 +572,7 @@ static const struct i2c_device_id stk8ba50_i2c_id[] = {
{"stk8ba50", 0}, {"stk8ba50", 0},
{} {}
}; };
MODULE_DEVICE_TABLE(i2c, stk8ba50_i2c_id);
static const struct acpi_device_id stk8ba50_acpi_id[] = { static const struct acpi_device_id stk8ba50_acpi_id[] = {
{"STK8BA50", 0}, {"STK8BA50", 0},
......
...@@ -20,6 +20,9 @@ config AD7266 ...@@ -20,6 +20,9 @@ config AD7266
Say yes here to build support for Analog Devices AD7265 and AD7266 Say yes here to build support for Analog Devices AD7265 and AD7266
ADCs. ADCs.
To compile this driver as a module, choose M here: the module will be
called ad7266.
config AD7291 config AD7291
tristate "Analog Devices AD7291 ADC driver" tristate "Analog Devices AD7291 ADC driver"
depends on I2C depends on I2C
...@@ -52,8 +55,6 @@ config AD7476 ...@@ -52,8 +55,6 @@ config AD7476
AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC). AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ad7476. module will be called ad7476.
...@@ -63,8 +64,7 @@ config AD7791 ...@@ -63,8 +64,7 @@ config AD7791
select AD_SIGMA_DELTA select AD_SIGMA_DELTA
help help
Say yes here to build support for Analog Devices AD7787, AD7788, AD7789, Say yes here to build support for Analog Devices AD7787, AD7788, AD7789,
AD7790 and AD7791 SPI analog to digital converters (ADC). If unsure, say AD7790 and AD7791 SPI analog to digital converters (ADC).
N (but it is safe to say "Y").
To compile this driver as a module, choose M here: the module will be To compile this driver as a module, choose M here: the module will be
called ad7791. called ad7791.
...@@ -76,7 +76,6 @@ config AD7793 ...@@ -76,7 +76,6 @@ config AD7793
help help
Say yes here to build support for Analog Devices AD7785, AD7792, AD7793, Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
AD7794 and AD7795 SPI analog to digital converters (ADC). AD7794 and AD7795 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called AD7793. module will be called AD7793.
...@@ -89,7 +88,6 @@ config AD7887 ...@@ -89,7 +88,6 @@ config AD7887
help help
Say yes here to build support for Analog Devices Say yes here to build support for Analog Devices
AD7887 SPI analog to digital converter (ADC). AD7887 SPI analog to digital converter (ADC).
If unsure, say N (but it's safe to say "Y").
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 ad7887. module will be called ad7887.
...@@ -117,6 +115,9 @@ config AD799X ...@@ -117,6 +115,9 @@ config AD799X
i2c analog to digital converters (ADC). Provides direct access i2c analog to digital converters (ADC). Provides direct access
via sysfs. via sysfs.
To compile this driver as a module, choose M here: the module will be
called ad799x.
config AT91_ADC config AT91_ADC
tristate "Atmel AT91 ADC" tristate "Atmel AT91 ADC"
depends on ARCH_AT91 depends on ARCH_AT91
...@@ -127,6 +128,9 @@ config AT91_ADC ...@@ -127,6 +128,9 @@ config AT91_ADC
help help
Say yes here to build support for Atmel AT91 ADC. Say yes here to build support for Atmel AT91 ADC.
To compile this driver as a module, choose M here: the module will be
called at91_adc.
config AXP288_ADC config AXP288_ADC
tristate "X-Powers AXP288 ADC driver" tristate "X-Powers AXP288 ADC driver"
depends on MFD_AXP20X depends on MFD_AXP20X
...@@ -135,6 +139,9 @@ config AXP288_ADC ...@@ -135,6 +139,9 @@ config AXP288_ADC
device. Depending on platform configuration, this general purpose ADC can device. Depending on platform configuration, this general purpose ADC can
be used for sampling sensors such as thermal resistors. be used for sampling sensors such as thermal resistors.
To compile this driver as a module, choose M here: the module will be
called axp288_adc.
config BERLIN2_ADC config BERLIN2_ADC
tristate "Marvell Berlin2 ADC driver" tristate "Marvell Berlin2 ADC driver"
depends on ARCH_BERLIN depends on ARCH_BERLIN
...@@ -151,6 +158,9 @@ config DA9150_GPADC ...@@ -151,6 +158,9 @@ config DA9150_GPADC
This driver can also be built as a module. If chosen, the module name This driver can also be built as a module. If chosen, the module name
will be da9150-gpadc. will be da9150-gpadc.
To compile this driver as a module, choose M here: the module will be
called berlin2-adc.
config CC10001_ADC config CC10001_ADC
tristate "Cosmic Circuits 10001 ADC driver" tristate "Cosmic Circuits 10001 ADC driver"
depends on HAS_IOMEM && HAVE_CLK && REGULATOR depends on HAS_IOMEM && HAVE_CLK && REGULATOR
...@@ -170,12 +180,18 @@ config EXYNOS_ADC ...@@ -170,12 +180,18 @@ config EXYNOS_ADC
of SoCs for drivers such as the touchscreen and hwmon to use to share of SoCs for drivers such as the touchscreen and hwmon to use to share
this resource. this resource.
To compile this driver as a module, choose M here: the module will be
called exynos_adc.
config LP8788_ADC config LP8788_ADC
tristate "LP8788 ADC driver" tristate "LP8788 ADC driver"
depends on MFD_LP8788 depends on MFD_LP8788
help help
Say yes here to build support for TI LP8788 ADC. Say yes here to build support for TI LP8788 ADC.
To compile this driver as a module, choose M here: the module will be
called lp8788_adc.
config MAX1027 config MAX1027
tristate "Maxim max1027 ADC driver" tristate "Maxim max1027 ADC driver"
depends on SPI depends on SPI
...@@ -185,6 +201,9 @@ config MAX1027 ...@@ -185,6 +201,9 @@ config MAX1027
Say yes here to build support for Maxim SPI ADC models Say yes here to build support for Maxim SPI ADC models
max1027, max1029 and max1031. max1027, max1029 and max1031.
To compile this driver as a module, choose M here: the module will be
called max1027.
config MAX1363 config MAX1363
tristate "Maxim max1363 ADC driver" tristate "Maxim max1363 ADC driver"
depends on I2C depends on I2C
...@@ -201,13 +220,16 @@ config MAX1363 ...@@ -201,13 +220,16 @@ config MAX1363
max11646, max11647) Provides direct access via sysfs and buffered max11646, max11647) Provides direct access via sysfs and buffered
data via the iio dev interface. data via the iio dev interface.
To compile this driver as a module, choose M here: the module will be
called max1363.
config MCP320X config MCP320X
tristate "Microchip Technology MCP3x01/02/04/08" tristate "Microchip Technology MCP3x01/02/04/08"
depends on SPI depends on SPI
help help
Say yes here to build support for Microchip Technology's Say yes here to build support for Microchip Technology's
MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204 or MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204,
MCP3208 analog to digital converter. MCP3208 or MCP3301 analog to digital converter.
This driver can also be built as a module. If so, the module will be This driver can also be built as a module. If so, the module will be
called mcp320x. called mcp320x.
...@@ -309,6 +331,9 @@ config TI_AM335X_ADC ...@@ -309,6 +331,9 @@ config TI_AM335X_ADC
Say yes here to build support for Texas Instruments ADC Say yes here to build support for Texas Instruments ADC
driver which is also a MFD client. driver which is also a MFD client.
To compile this driver as a module, choose M here: the module will be
called ti_am335x_adc.
config TWL4030_MADC config TWL4030_MADC
tristate "TWL4030 MADC (Monitoring A/D Converter)" tristate "TWL4030 MADC (Monitoring A/D Converter)"
depends on TWL4030_CORE depends on TWL4030_CORE
...@@ -350,6 +375,9 @@ config VIPERBOARD_ADC ...@@ -350,6 +375,9 @@ config VIPERBOARD_ADC
Say yes here to access the ADC part of the Nano River Say yes here to access the ADC part of the Nano River
Technologies Viperboard. Technologies Viperboard.
To compile this driver as a module, choose M here: the module will be
called viperboard_adc.
config XILINX_XADC config XILINX_XADC
tristate "Xilinx XADC driver" tristate "Xilinx XADC driver"
depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define BERLIN2_SM_CTRL 0x14 #define BERLIN2_SM_CTRL 0x14
#define BERLIN2_SM_CTRL_SM_SOC_INT BIT(1) #define BERLIN2_SM_CTRL_SM_SOC_INT BIT(1)
#define BERLIN2_SM_CTRL_SOC_SM_INT BIT(2) #define BERLIN2_SM_CTRL_SOC_SM_INT BIT(2)
#define BERLIN2_SM_CTRL_ADC_SEL(x) (BIT(x) << 5) /* 0-15 */ #define BERLIN2_SM_CTRL_ADC_SEL(x) ((x) << 5) /* 0-15 */
#define BERLIN2_SM_CTRL_ADC_SEL_MASK (0xf << 5) #define BERLIN2_SM_CTRL_ADC_SEL_MASK (0xf << 5)
#define BERLIN2_SM_CTRL_ADC_POWER BIT(9) #define BERLIN2_SM_CTRL_ADC_POWER BIT(9)
#define BERLIN2_SM_CTRL_ADC_CLKSEL_DIV2 (0x0 << 10) #define BERLIN2_SM_CTRL_ADC_CLKSEL_DIV2 (0x0 << 10)
...@@ -53,14 +53,14 @@ ...@@ -53,14 +53,14 @@
#define BERLIN2_SM_ADC_MASK 0x3ff #define BERLIN2_SM_ADC_MASK 0x3ff
#define BERLIN2_SM_ADC_STATUS 0x1c #define BERLIN2_SM_ADC_STATUS 0x1c
#define BERLIN2_SM_ADC_STATUS_DATA_RDY(x) BIT(x) /* 0-15 */ #define BERLIN2_SM_ADC_STATUS_DATA_RDY(x) BIT(x) /* 0-15 */
#define BERLIN2_SM_ADC_STATUS_DATA_RDY_MASK 0xf #define BERLIN2_SM_ADC_STATUS_DATA_RDY_MASK GENMASK(15, 0)
#define BERLIN2_SM_ADC_STATUS_INT_EN(x) (BIT(x) << 16) /* 0-15 */ #define BERLIN2_SM_ADC_STATUS_INT_EN(x) (BIT(x) << 16) /* 0-15 */
#define BERLIN2_SM_ADC_STATUS_INT_EN_MASK (0xf << 16) #define BERLIN2_SM_ADC_STATUS_INT_EN_MASK GENMASK(31, 16)
#define BERLIN2_SM_TSEN_STATUS 0x24 #define BERLIN2_SM_TSEN_STATUS 0x24
#define BERLIN2_SM_TSEN_STATUS_DATA_RDY BIT(0) #define BERLIN2_SM_TSEN_STATUS_DATA_RDY BIT(0)
#define BERLIN2_SM_TSEN_STATUS_INT_EN BIT(1) #define BERLIN2_SM_TSEN_STATUS_INT_EN BIT(1)
#define BERLIN2_SM_TSEN_DATA 0x28 #define BERLIN2_SM_TSEN_DATA 0x28
#define BERLIN2_SM_TSEN_MASK 0xfff #define BERLIN2_SM_TSEN_MASK GENMASK(9, 0)
#define BERLIN2_SM_TSEN_CTRL 0x74 #define BERLIN2_SM_TSEN_CTRL 0x74
#define BERLIN2_SM_TSEN_CTRL_START BIT(8) #define BERLIN2_SM_TSEN_CTRL_START BIT(8)
#define BERLIN2_SM_TSEN_CTRL_SETTLING_4 (0x0 << 21) /* 4 us */ #define BERLIN2_SM_TSEN_CTRL_SETTLING_4 (0x0 << 21) /* 4 us */
...@@ -86,7 +86,7 @@ struct berlin2_adc_priv { ...@@ -86,7 +86,7 @@ struct berlin2_adc_priv {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
} }
static struct iio_chan_spec berlin2_adc_channels[] = { static const struct iio_chan_spec berlin2_adc_channels[] = {
BERLIN2_ADC_CHANNEL(0, IIO_VOLTAGE), /* external input */ BERLIN2_ADC_CHANNEL(0, IIO_VOLTAGE), /* external input */
BERLIN2_ADC_CHANNEL(1, IIO_VOLTAGE), /* external input */ BERLIN2_ADC_CHANNEL(1, IIO_VOLTAGE), /* external input */
BERLIN2_ADC_CHANNEL(2, IIO_VOLTAGE), /* external input */ BERLIN2_ADC_CHANNEL(2, IIO_VOLTAGE), /* external input */
...@@ -103,7 +103,6 @@ static struct iio_chan_spec berlin2_adc_channels[] = { ...@@ -103,7 +103,6 @@ static struct iio_chan_spec berlin2_adc_channels[] = {
BERLIN2_ADC_CHANNEL(7, IIO_VOLTAGE), /* reserved */ BERLIN2_ADC_CHANNEL(7, IIO_VOLTAGE), /* reserved */
IIO_CHAN_SOFT_TIMESTAMP(8), /* timestamp */ IIO_CHAN_SOFT_TIMESTAMP(8), /* timestamp */
}; };
#define BERLIN2_N_CHANNELS ARRAY_SIZE(berlin2_adc_channels)
static int berlin2_adc_read(struct iio_dev *indio_dev, int channel) static int berlin2_adc_read(struct iio_dev *indio_dev, int channel)
{ {
...@@ -221,7 +220,7 @@ static int berlin2_adc_read_raw(struct iio_dev *indio_dev, ...@@ -221,7 +220,7 @@ static int berlin2_adc_read_raw(struct iio_dev *indio_dev,
return temp; return temp;
if (temp > 2047) if (temp > 2047)
temp = -(4096 - temp); temp -= 4096;
/* Convert to milli Celsius */ /* Convert to milli Celsius */
*val = ((temp * 100000) / 264 - 270000); *val = ((temp * 100000) / 264 - 270000);
...@@ -286,8 +285,7 @@ static int berlin2_adc_probe(struct platform_device *pdev) ...@@ -286,8 +285,7 @@ static int berlin2_adc_probe(struct platform_device *pdev)
int irq, tsen_irq; int irq, tsen_irq;
int ret; int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
sizeof(struct berlin2_adc_priv));
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
...@@ -301,11 +299,11 @@ static int berlin2_adc_probe(struct platform_device *pdev) ...@@ -301,11 +299,11 @@ static int berlin2_adc_probe(struct platform_device *pdev)
irq = platform_get_irq_byname(pdev, "adc"); irq = platform_get_irq_byname(pdev, "adc");
if (irq < 0) if (irq < 0)
return -ENODEV; return irq;
tsen_irq = platform_get_irq_byname(pdev, "tsen"); tsen_irq = platform_get_irq_byname(pdev, "tsen");
if (tsen_irq < 0) if (tsen_irq < 0)
return -ENODEV; return tsen_irq;
ret = devm_request_irq(&pdev->dev, irq, berlin2_adc_irq, 0, ret = devm_request_irq(&pdev->dev, irq, berlin2_adc_irq, 0,
pdev->dev.driver->name, indio_dev); pdev->dev.driver->name, indio_dev);
...@@ -325,8 +323,8 @@ static int berlin2_adc_probe(struct platform_device *pdev) ...@@ -325,8 +323,8 @@ static int berlin2_adc_probe(struct platform_device *pdev)
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &berlin2_adc_info; indio_dev->info = &berlin2_adc_info;
indio_dev->num_channels = BERLIN2_N_CHANNELS;
indio_dev->channels = berlin2_adc_channels; indio_dev->channels = berlin2_adc_channels;
indio_dev->num_channels = ARRAY_SIZE(berlin2_adc_channels);
/* Power up the ADC */ /* Power up the ADC */
regmap_update_bits(priv->regmap, BERLIN2_SM_CTRL, regmap_update_bits(priv->regmap, BERLIN2_SM_CTRL,
......
...@@ -62,6 +62,7 @@ struct cc10001_adc_device { ...@@ -62,6 +62,7 @@ struct cc10001_adc_device {
struct regulator *reg; struct regulator *reg;
u16 *buf; u16 *buf;
bool shared;
struct mutex lock; struct mutex lock;
unsigned int start_delay_ns; unsigned int start_delay_ns;
unsigned int eoc_delay_ns; unsigned int eoc_delay_ns;
...@@ -153,6 +154,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) ...@@ -153,6 +154,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
mutex_lock(&adc_dev->lock); mutex_lock(&adc_dev->lock);
if (!adc_dev->shared)
cc10001_adc_power_up(adc_dev); cc10001_adc_power_up(adc_dev);
/* Calculate delay step for eoc and sampled data */ /* Calculate delay step for eoc and sampled data */
...@@ -177,6 +179,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) ...@@ -177,6 +179,7 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
} }
done: done:
if (!adc_dev->shared)
cc10001_adc_power_down(adc_dev); cc10001_adc_power_down(adc_dev);
mutex_unlock(&adc_dev->lock); mutex_unlock(&adc_dev->lock);
...@@ -196,6 +199,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, ...@@ -196,6 +199,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
unsigned int delay_ns; unsigned int delay_ns;
u16 val; u16 val;
if (!adc_dev->shared)
cc10001_adc_power_up(adc_dev); cc10001_adc_power_up(adc_dev);
/* Calculate delay step for eoc and sampled data */ /* Calculate delay step for eoc and sampled data */
...@@ -205,6 +209,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, ...@@ -205,6 +209,7 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
if (!adc_dev->shared)
cc10001_adc_power_down(adc_dev); cc10001_adc_power_down(adc_dev);
return val; return val;
...@@ -322,8 +327,10 @@ static int cc10001_adc_probe(struct platform_device *pdev) ...@@ -322,8 +327,10 @@ static int cc10001_adc_probe(struct platform_device *pdev)
adc_dev = iio_priv(indio_dev); adc_dev = iio_priv(indio_dev);
channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) {
adc_dev->shared = true;
channel_map &= ~ret; channel_map &= ~ret;
}
adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
if (IS_ERR(adc_dev->reg)) if (IS_ERR(adc_dev->reg))
...@@ -368,6 +375,14 @@ static int cc10001_adc_probe(struct platform_device *pdev) ...@@ -368,6 +375,14 @@ static int cc10001_adc_probe(struct platform_device *pdev)
adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate; adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
/*
* There is only one register to power-up/power-down the AUX ADC.
* If the ADC is shared among multiple CPUs, always power it up here.
* If the ADC is used only by the MIPS, power-up/power-down at runtime.
*/
if (adc_dev->shared)
cc10001_adc_power_up(adc_dev);
/* Setup the ADC channels available on the device */ /* Setup the ADC channels available on the device */
ret = cc10001_adc_channel_init(indio_dev, channel_map); ret = cc10001_adc_channel_init(indio_dev, channel_map);
if (ret < 0) if (ret < 0)
...@@ -402,6 +417,7 @@ static int cc10001_adc_remove(struct platform_device *pdev) ...@@ -402,6 +417,7 @@ static int cc10001_adc_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
cc10001_adc_power_down(adc_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev); iio_triggered_buffer_cleanup(indio_dev);
clk_disable_unprepare(adc_dev->adc_clk); clk_disable_unprepare(adc_dev->adc_clk);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
* http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf mcp3201 * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf mcp3201
* http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202 * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202
* http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08 * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08
* http://ww1.microchip.com/downloads/en/DeviceDoc/21700E.pdf mcp3301
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -47,6 +48,7 @@ enum { ...@@ -47,6 +48,7 @@ enum {
mcp3202, mcp3202,
mcp3204, mcp3204,
mcp3208, mcp3208,
mcp3301,
}; };
struct mcp320x_chip_info { struct mcp320x_chip_info {
...@@ -76,6 +78,7 @@ static int mcp320x_channel_to_tx_data(int device_index, ...@@ -76,6 +78,7 @@ static int mcp320x_channel_to_tx_data(int device_index,
switch (device_index) { switch (device_index) {
case mcp3001: case mcp3001:
case mcp3201: case mcp3201:
case mcp3301:
return 0; return 0;
case mcp3002: case mcp3002:
case mcp3202: case mcp3202:
...@@ -102,7 +105,7 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, ...@@ -102,7 +105,7 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
adc->tx_buf = mcp320x_channel_to_tx_data(device_index, adc->tx_buf = mcp320x_channel_to_tx_data(device_index,
channel, differential); channel, differential);
if (device_index != mcp3001 && device_index != mcp3201) { if (device_index != mcp3001 && device_index != mcp3201 && device_index != mcp3301) {
ret = spi_sync(adc->spi, &adc->msg); ret = spi_sync(adc->spi, &adc->msg);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -125,6 +128,8 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, ...@@ -125,6 +128,8 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
case mcp3204: case mcp3204:
case mcp3208: case mcp3208:
return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
case mcp3301:
return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12);
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -274,6 +279,11 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = { ...@@ -274,6 +279,11 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = {
.num_channels = ARRAY_SIZE(mcp3208_channels), .num_channels = ARRAY_SIZE(mcp3208_channels),
.resolution = 12 .resolution = 12
}, },
[mcp3301] = {
.channels = mcp3201_channels,
.num_channels = ARRAY_SIZE(mcp3201_channels),
.resolution = 13
},
}; };
static int mcp320x_probe(struct spi_device *spi) static int mcp320x_probe(struct spi_device *spi)
...@@ -368,6 +378,9 @@ static const struct of_device_id mcp320x_dt_ids[] = { ...@@ -368,6 +378,9 @@ static const struct of_device_id mcp320x_dt_ids[] = {
}, { }, {
.compatible = "mcp3208", .compatible = "mcp3208",
.data = &mcp320x_chip_infos[mcp3208], .data = &mcp320x_chip_infos[mcp3208],
}, {
.compatible = "mcp3301",
.data = &mcp320x_chip_infos[mcp3301],
}, { }, {
} }
}; };
...@@ -383,6 +396,7 @@ static const struct spi_device_id mcp320x_id[] = { ...@@ -383,6 +396,7 @@ static const struct spi_device_id mcp320x_id[] = {
{ "mcp3202", mcp3202 }, { "mcp3202", mcp3202 },
{ "mcp3204", mcp3204 }, { "mcp3204", mcp3204 },
{ "mcp3208", mcp3208 }, { "mcp3208", mcp3208 },
{ "mcp3301", mcp3301 },
{ } { }
}; };
MODULE_DEVICE_TABLE(spi, mcp320x_id); MODULE_DEVICE_TABLE(spi, mcp320x_id);
......
...@@ -404,7 +404,6 @@ MODULE_DEVICE_TABLE(of, mcp3422_of_match); ...@@ -404,7 +404,6 @@ MODULE_DEVICE_TABLE(of, mcp3422_of_match);
static struct i2c_driver mcp3422_driver = { static struct i2c_driver mcp3422_driver = {
.driver = { .driver = {
.name = "mcp3422", .name = "mcp3422",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mcp3422_of_match), .of_match_table = of_match_ptr(mcp3422_of_match),
}, },
.probe = mcp3422_probe, .probe = mcp3422_probe,
......
...@@ -140,7 +140,6 @@ MODULE_DEVICE_TABLE(of, adc081c_of_match); ...@@ -140,7 +140,6 @@ MODULE_DEVICE_TABLE(of, adc081c_of_match);
static struct i2c_driver adc081c_driver = { static struct i2c_driver adc081c_driver = {
.driver = { .driver = {
.name = "adc081c", .name = "adc081c",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(adc081c_of_match), .of_match_table = of_match_ptr(adc081c_of_match),
}, },
.probe = adc081c_probe, .probe = adc081c_probe,
......
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
#define VF610_ADC_CLK_DIV8 0x60 #define VF610_ADC_CLK_DIV8 0x60
#define VF610_ADC_CLK_MASK 0x60 #define VF610_ADC_CLK_MASK 0x60
#define VF610_ADC_ADLSMP_LONG 0x10 #define VF610_ADC_ADLSMP_LONG 0x10
#define VF610_ADC_ADSTS_SHORT 0x100
#define VF610_ADC_ADSTS_NORMAL 0x200
#define VF610_ADC_ADSTS_LONG 0x300
#define VF610_ADC_ADSTS_MASK 0x300 #define VF610_ADC_ADSTS_MASK 0x300
#define VF610_ADC_ADLPC_EN 0x80 #define VF610_ADC_ADLPC_EN 0x80
#define VF610_ADC_ADHSC_EN 0x400 #define VF610_ADC_ADHSC_EN 0x400
...@@ -98,6 +101,8 @@ ...@@ -98,6 +101,8 @@
#define VF610_ADC_CALF 0x2 #define VF610_ADC_CALF 0x2
#define VF610_ADC_TIMEOUT msecs_to_jiffies(100) #define VF610_ADC_TIMEOUT msecs_to_jiffies(100)
#define DEFAULT_SAMPLE_TIME 1000
enum clk_sel { enum clk_sel {
VF610_ADCIOC_BUSCLK_SET, VF610_ADCIOC_BUSCLK_SET,
VF610_ADCIOC_ALTCLK_SET, VF610_ADCIOC_ALTCLK_SET,
...@@ -124,6 +129,17 @@ enum conversion_mode_sel { ...@@ -124,6 +129,17 @@ enum conversion_mode_sel {
VF610_ADC_CONV_LOW_POWER, VF610_ADC_CONV_LOW_POWER,
}; };
enum lst_adder_sel {
VF610_ADCK_CYCLES_3,
VF610_ADCK_CYCLES_5,
VF610_ADCK_CYCLES_7,
VF610_ADCK_CYCLES_9,
VF610_ADCK_CYCLES_13,
VF610_ADCK_CYCLES_17,
VF610_ADCK_CYCLES_21,
VF610_ADCK_CYCLES_25,
};
struct vf610_adc_feature { struct vf610_adc_feature {
enum clk_sel clk_sel; enum clk_sel clk_sel;
enum vol_ref vol_ref; enum vol_ref vol_ref;
...@@ -132,6 +148,8 @@ struct vf610_adc_feature { ...@@ -132,6 +148,8 @@ struct vf610_adc_feature {
int clk_div; int clk_div;
int sample_rate; int sample_rate;
int res_mode; int res_mode;
u32 lst_adder_index;
u32 default_sample_time;
bool calibration; bool calibration;
bool ovwren; bool ovwren;
...@@ -155,11 +173,13 @@ struct vf610_adc { ...@@ -155,11 +173,13 @@ struct vf610_adc {
}; };
static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
static const u32 vf610_lst_adder[] = { 3, 5, 7, 9, 13, 17, 21, 25 };
static inline void vf610_adc_calculate_rates(struct vf610_adc *info) static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
{ {
struct vf610_adc_feature *adc_feature = &info->adc_feature; struct vf610_adc_feature *adc_feature = &info->adc_feature;
unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk); unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
u32 adck_period, lst_addr_min;
int divisor, i; int divisor, i;
adck_rate = info->max_adck_rate[adc_feature->conv_mode]; adck_rate = info->max_adck_rate[adc_feature->conv_mode];
...@@ -173,6 +193,19 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info) ...@@ -173,6 +193,19 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
adc_feature->clk_div = 8; adc_feature->clk_div = 8;
} }
/*
* Determine the long sample time adder value to be used based
* on the default minimum sample time provided.
*/
adck_period = NSEC_PER_SEC / adck_rate;
lst_addr_min = adc_feature->default_sample_time / adck_period;
for (i = 0; i < ARRAY_SIZE(vf610_lst_adder); i++) {
if (vf610_lst_adder[i] > lst_addr_min) {
adc_feature->lst_adder_index = i;
break;
}
}
/* /*
* Calculate ADC sample frequencies * Calculate ADC sample frequencies
* Sample time unit is ADCK cycles. ADCK clk source is ipg clock, * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
...@@ -182,12 +215,13 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info) ...@@ -182,12 +215,13 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
* SFCAdder: fixed to 6 ADCK cycles * SFCAdder: fixed to 6 ADCK cycles
* AverageNum: 1, 4, 8, 16, 32 samples for hardware average. * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
* BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
* LSTAdder(Long Sample Time): fixed to 3 ADCK cycles * LSTAdder(Long Sample Time): 3, 5, 7, 9, 13, 17, 21, 25 ADCK cycles
*/ */
adck_rate = ipg_rate / info->adc_feature.clk_div; adck_rate = ipg_rate / info->adc_feature.clk_div;
for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++) for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
info->sample_freq_avail[i] = info->sample_freq_avail[i] =
adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3)); adck_rate / (6 + vf610_hw_avgs[i] *
(25 + vf610_lst_adder[adc_feature->lst_adder_index]));
} }
static inline void vf610_adc_cfg_init(struct vf610_adc *info) static inline void vf610_adc_cfg_init(struct vf610_adc *info)
...@@ -347,8 +381,40 @@ static void vf610_adc_sample_set(struct vf610_adc *info) ...@@ -347,8 +381,40 @@ static void vf610_adc_sample_set(struct vf610_adc *info)
break; break;
} }
/* Use the short sample mode */ /*
cfg_data &= ~(VF610_ADC_ADLSMP_LONG | VF610_ADC_ADSTS_MASK); * Set ADLSMP and ADSTS based on the Long Sample Time Adder value
* determined.
*/
switch (adc_feature->lst_adder_index) {
case VF610_ADCK_CYCLES_3:
break;
case VF610_ADCK_CYCLES_5:
cfg_data |= VF610_ADC_ADSTS_SHORT;
break;
case VF610_ADCK_CYCLES_7:
cfg_data |= VF610_ADC_ADSTS_NORMAL;
break;
case VF610_ADCK_CYCLES_9:
cfg_data |= VF610_ADC_ADSTS_LONG;
break;
case VF610_ADCK_CYCLES_13:
cfg_data |= VF610_ADC_ADLSMP_LONG;
break;
case VF610_ADCK_CYCLES_17:
cfg_data |= VF610_ADC_ADLSMP_LONG;
cfg_data |= VF610_ADC_ADSTS_SHORT;
break;
case VF610_ADCK_CYCLES_21:
cfg_data |= VF610_ADC_ADLSMP_LONG;
cfg_data |= VF610_ADC_ADSTS_NORMAL;
break;
case VF610_ADCK_CYCLES_25:
cfg_data |= VF610_ADC_ADLSMP_LONG;
cfg_data |= VF610_ADC_ADSTS_NORMAL;
break;
default:
dev_err(info->dev, "error in sample time select\n");
}
/* update hardware average selection */ /* update hardware average selection */
cfg_data &= ~VF610_ADC_AVGS_MASK; cfg_data &= ~VF610_ADC_AVGS_MASK;
...@@ -713,6 +779,11 @@ static int vf610_adc_probe(struct platform_device *pdev) ...@@ -713,6 +779,11 @@ static int vf610_adc_probe(struct platform_device *pdev)
of_property_read_u32_array(pdev->dev.of_node, "fsl,adck-max-frequency", of_property_read_u32_array(pdev->dev.of_node, "fsl,adck-max-frequency",
info->max_adck_rate, 3); info->max_adck_rate, 3);
ret = of_property_read_u32(pdev->dev.of_node, "min-sample-time",
&info->adc_feature.default_sample_time);
if (ret)
info->adc_feature.default_sample_time = DEFAULT_SAMPLE_TIME;
platform_set_drvdata(pdev, indio_dev); platform_set_drvdata(pdev, indio_dev);
init_completion(&info->completion); init_completion(&info->completion);
......
...@@ -700,7 +700,6 @@ static struct spi_driver ssp_driver = { ...@@ -700,7 +700,6 @@ static struct spi_driver ssp_driver = {
.remove = ssp_remove, .remove = ssp_remove,
.driver = { .driver = {
.pm = &ssp_pm_ops, .pm = &ssp_pm_ops,
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(ssp_of_match), .of_match_table = of_match_ptr(ssp_of_match),
.name = "sensorhub" .name = "sensorhub"
......
...@@ -126,6 +126,9 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) ...@@ -126,6 +126,9 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
int err, i = 0; int err, i = 0;
struct st_sensor_data *sdata = iio_priv(indio_dev); struct st_sensor_data *sdata = iio_priv(indio_dev);
if (sdata->sensor_settings->fs.addr == 0)
return 0;
err = st_sensors_match_fs(sdata->sensor_settings, fs, &i); err = st_sensors_match_fs(sdata->sensor_settings, fs, &i);
if (err < 0) if (err < 0)
goto st_accel_set_fullscale_error; goto st_accel_set_fullscale_error;
...@@ -479,46 +482,43 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev, ...@@ -479,46 +482,43 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
int num_sensors_list, int num_sensors_list,
const struct st_sensor_settings *sensor_settings) const struct st_sensor_settings *sensor_settings)
{ {
u8 wai;
int i, n, err; int i, n, err;
u8 wai;
struct st_sensor_data *sdata = iio_priv(indio_dev); struct st_sensor_data *sdata = iio_priv(indio_dev);
err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
ST_SENSORS_DEFAULT_WAI_ADDRESS, &wai);
if (err < 0) {
dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
goto read_wai_error;
}
for (i = 0; i < num_sensors_list; i++) { for (i = 0; i < num_sensors_list; i++) {
if (sensor_settings[i].wai == wai) for (n = 0; n < ST_SENSORS_MAX_4WAI; n++) {
if (strcmp(indio_dev->name,
sensor_settings[i].sensors_supported[n]) == 0) {
break; break;
} }
if (i == num_sensors_list) }
goto device_not_supported; if (n < ST_SENSORS_MAX_4WAI)
for (n = 0; n < ARRAY_SIZE(sensor_settings[i].sensors_supported); n++) {
if (strcmp(indio_dev->name,
&sensor_settings[i].sensors_supported[n][0]) == 0)
break; break;
} }
if (n == ARRAY_SIZE(sensor_settings[i].sensors_supported)) { if (i == num_sensors_list) {
dev_err(&indio_dev->dev, "device name \"%s\" and WhoAmI (0x%02x) mismatch", dev_err(&indio_dev->dev, "device name %s not recognized.\n",
indio_dev->name);
return -ENODEV;
}
err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
sensor_settings[i].wai_addr, &wai);
if (err < 0) {
dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
return err;
}
if (sensor_settings[i].wai != wai) {
dev_err(&indio_dev->dev, "%s: WhoAmI mismatch (0x%x).\n",
indio_dev->name, wai); indio_dev->name, wai);
goto sensor_name_mismatch; return -EINVAL;
} }
sdata->sensor_settings = sdata->sensor_settings =
(struct st_sensor_settings *)&sensor_settings[i]; (struct st_sensor_settings *)&sensor_settings[i];
return i; return i;
device_not_supported:
dev_err(&indio_dev->dev, "device not supported: WhoAmI (0x%x).\n", wai);
sensor_name_mismatch:
err = -ENODEV;
read_wai_error:
return err;
} }
EXPORT_SYMBOL(st_sensors_check_device_support); EXPORT_SYMBOL(st_sensors_check_device_support);
......
...@@ -630,7 +630,6 @@ MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids); ...@@ -630,7 +630,6 @@ MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);
static struct i2c_driver ad5064_i2c_driver = { static struct i2c_driver ad5064_i2c_driver = {
.driver = { .driver = {
.name = "ad5064", .name = "ad5064",
.owner = THIS_MODULE,
}, },
.probe = ad5064_i2c_probe, .probe = ad5064_i2c_probe,
.remove = ad5064_i2c_remove, .remove = ad5064_i2c_remove,
......
...@@ -593,7 +593,6 @@ MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids); ...@@ -593,7 +593,6 @@ MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
static struct i2c_driver ad5380_i2c_driver = { static struct i2c_driver ad5380_i2c_driver = {
.driver = { .driver = {
.name = "ad5380", .name = "ad5380",
.owner = THIS_MODULE,
}, },
.probe = ad5380_i2c_probe, .probe = ad5380_i2c_probe,
.remove = ad5380_i2c_remove, .remove = ad5380_i2c_remove,
......
...@@ -569,7 +569,6 @@ MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids); ...@@ -569,7 +569,6 @@ MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids);
static struct i2c_driver ad5446_i2c_driver = { static struct i2c_driver ad5446_i2c_driver = {
.driver = { .driver = {
.name = "ad5446", .name = "ad5446",
.owner = THIS_MODULE,
}, },
.probe = ad5446_i2c_probe, .probe = ad5446_i2c_probe,
.remove = ad5446_i2c_remove, .remove = ad5446_i2c_remove,
......
...@@ -392,7 +392,6 @@ static struct i2c_driver max5821_driver = { ...@@ -392,7 +392,6 @@ static struct i2c_driver max5821_driver = {
.driver = { .driver = {
.name = "max5821", .name = "max5821",
.pm = MAX5821_PM_OPS, .pm = MAX5821_PM_OPS,
.owner = THIS_MODULE,
}, },
.probe = max5821_probe, .probe = max5821_probe,
.remove = max5821_remove, .remove = max5821_remove,
......
...@@ -72,7 +72,6 @@ static int adf4350_sync_config(struct adf4350_state *st) ...@@ -72,7 +72,6 @@ static int adf4350_sync_config(struct adf4350_state *st)
for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) { for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) {
if ((st->regs_hw[i] != st->regs[i]) || if ((st->regs_hw[i] != st->regs[i]) ||
((i == ADF4350_REG0) && doublebuf)) { ((i == ADF4350_REG0) && doublebuf)) {
switch (i) { switch (i) {
case ADF4350_REG1: case ADF4350_REG1:
case ADF4350_REG4: case ADF4350_REG4:
......
...@@ -53,7 +53,8 @@ config ADXRS450 ...@@ -53,7 +53,8 @@ config ADXRS450
config BMG160 config BMG160
tristate "BOSCH BMG160 Gyro Sensor" tristate "BOSCH BMG160 Gyro Sensor"
depends on I2C depends on I2C
select IIO_TRIGGERED_BUFFER if IIO_BUFFER select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help help
Say yes here to build support for Bosch BMG160 Tri-axis Gyro Sensor Say yes here to build support for Bosch BMG160 Tri-axis Gyro Sensor
driver. This driver also supports BMI055 gyroscope. driver. This driver also supports BMI055 gyroscope.
......
...@@ -473,6 +473,7 @@ enum adis16136_id { ...@@ -473,6 +473,7 @@ enum adis16136_id {
ID_ADIS16133, ID_ADIS16133,
ID_ADIS16135, ID_ADIS16135,
ID_ADIS16136, ID_ADIS16136,
ID_ADIS16137,
}; };
static const struct adis16136_chip_info adis16136_chip_info[] = { static const struct adis16136_chip_info adis16136_chip_info[] = {
...@@ -488,6 +489,10 @@ static const struct adis16136_chip_info adis16136_chip_info[] = { ...@@ -488,6 +489,10 @@ static const struct adis16136_chip_info adis16136_chip_info[] = {
.precision = IIO_DEGREE_TO_RAD(450), .precision = IIO_DEGREE_TO_RAD(450),
.fullscale = 24623, .fullscale = 24623,
}, },
[ID_ADIS16137] = {
.precision = IIO_DEGREE_TO_RAD(1000),
.fullscale = 24609,
},
}; };
static int adis16136_probe(struct spi_device *spi) static int adis16136_probe(struct spi_device *spi)
...@@ -557,6 +562,7 @@ static const struct spi_device_id adis16136_ids[] = { ...@@ -557,6 +562,7 @@ static const struct spi_device_id adis16136_ids[] = {
{ "adis16133", ID_ADIS16133 }, { "adis16133", ID_ADIS16133 },
{ "adis16135", ID_ADIS16135 }, { "adis16135", ID_ADIS16135 },
{ "adis16136", ID_ADIS16136 }, { "adis16136", ID_ADIS16136 },
{ "adis16137", ID_ADIS16137 },
{ } { }
}; };
MODULE_DEVICE_TABLE(spi, adis16136_ids); MODULE_DEVICE_TABLE(spi, adis16136_ids);
......
...@@ -101,19 +101,24 @@ ...@@ -101,19 +101,24 @@
#define ADIS16260_SCAN_TEMP 3 #define ADIS16260_SCAN_TEMP 3
#define ADIS16260_SCAN_ANGL 4 #define ADIS16260_SCAN_ANGL 4
/* Power down the device */ struct adis16260_chip_info {
static int adis16260_stop_device(struct iio_dev *indio_dev) unsigned int gyro_max_val;
{ unsigned int gyro_max_scale;
struct adis *adis = iio_priv(indio_dev); const struct iio_chan_spec *channels;
int ret; unsigned int num_channels;
u16 val = ADIS16260_SLP_CNT_POWER_OFF; };
ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val); struct adis16260 {
if (ret) const struct adis16260_chip_info *info;
dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
return ret; struct adis adis;
} };
enum adis16260_type {
ADIS16251,
ADIS16260,
ADIS16266,
};
static const struct iio_chan_spec adis16260_channels[] = { static const struct iio_chan_spec adis16260_channels[] = {
ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
...@@ -131,6 +136,55 @@ static const struct iio_chan_spec adis16260_channels[] = { ...@@ -131,6 +136,55 @@ static const struct iio_chan_spec adis16260_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(5), IIO_CHAN_SOFT_TIMESTAMP(5),
}; };
static const struct iio_chan_spec adis16266_channels[] = {
ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_CALIBSCALE),
BIT(IIO_CHAN_INFO_SAMP_FREQ), 14),
ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP,
BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY,
BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC,
BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
IIO_CHAN_SOFT_TIMESTAMP(4),
};
static const struct adis16260_chip_info adis16260_chip_info_table[] = {
[ADIS16251] = {
.gyro_max_scale = 80,
.gyro_max_val = IIO_RAD_TO_DEGREE(4368),
.channels = adis16260_channels,
.num_channels = ARRAY_SIZE(adis16260_channels),
},
[ADIS16260] = {
.gyro_max_scale = 320,
.gyro_max_val = IIO_RAD_TO_DEGREE(4368),
.channels = adis16260_channels,
.num_channels = ARRAY_SIZE(adis16260_channels),
},
[ADIS16266] = {
.gyro_max_scale = 14000,
.gyro_max_val = IIO_RAD_TO_DEGREE(3357),
.channels = adis16266_channels,
.num_channels = ARRAY_SIZE(adis16266_channels),
},
};
/* Power down the device */
static int adis16260_stop_device(struct iio_dev *indio_dev)
{
struct adis16260 *adis16260 = iio_priv(indio_dev);
int ret;
u16 val = ADIS16260_SLP_CNT_POWER_OFF;
ret = adis_write_reg_16(&adis16260->adis, ADIS16260_SLP_CNT, val);
if (ret)
dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
return ret;
}
static const u8 adis16260_addresses[][2] = { static const u8 adis16260_addresses[][2] = {
[ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE }, [ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
}; };
...@@ -140,7 +194,9 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, ...@@ -140,7 +194,9 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, int *val, int *val2,
long mask) long mask)
{ {
struct adis *adis = iio_priv(indio_dev); struct adis16260 *adis16260 = iio_priv(indio_dev);
const struct adis16260_chip_info *info = adis16260->info;
struct adis *adis = &adis16260->adis;
int ret; int ret;
u8 addr; u8 addr;
s16 val16; s16 val16;
...@@ -152,15 +208,9 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, ...@@ -152,15 +208,9 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
switch (chan->type) { switch (chan->type) {
case IIO_ANGL_VEL: case IIO_ANGL_VEL:
*val = 0; *val = info->gyro_max_scale;
if (spi_get_device_id(adis->spi)->driver_data) { *val2 = info->gyro_max_val;
/* 0.01832 degree / sec */ return IIO_VAL_FRACTIONAL;
*val2 = IIO_DEGREE_TO_RAD(18320);
} else {
/* 0.07326 degree / sec */
*val2 = IIO_DEGREE_TO_RAD(73260);
}
return IIO_VAL_INT_PLUS_MICRO;
case IIO_INCLI: case IIO_INCLI:
*val = 0; *val = 0;
*val2 = IIO_DEGREE_TO_RAD(36630); *val2 = IIO_DEGREE_TO_RAD(36630);
...@@ -224,7 +274,8 @@ static int adis16260_write_raw(struct iio_dev *indio_dev, ...@@ -224,7 +274,8 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
int val2, int val2,
long mask) long mask)
{ {
struct adis *adis = iio_priv(indio_dev); struct adis16260 *adis16260 = iio_priv(indio_dev);
struct adis *adis = &adis16260->adis;
int ret; int ret;
u8 addr; u8 addr;
u8 t; u8 t;
...@@ -305,35 +356,42 @@ static const struct adis_data adis16260_data = { ...@@ -305,35 +356,42 @@ static const struct adis_data adis16260_data = {
static int adis16260_probe(struct spi_device *spi) static int adis16260_probe(struct spi_device *spi)
{ {
const struct spi_device_id *id;
struct adis16260 *adis16260;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
struct adis *adis;
int ret; int ret;
id = spi_get_device_id(spi);
if (!id)
return -ENODEV;
/* setup the industrialio driver allocated elements */ /* setup the industrialio driver allocated elements */
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis)); indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16260));
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
adis = iio_priv(indio_dev); adis16260 = iio_priv(indio_dev);
/* this is only used for removal purposes */ /* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev); spi_set_drvdata(spi, indio_dev);
indio_dev->name = spi_get_device_id(spi)->name; adis16260->info = &adis16260_chip_info_table[id->driver_data];
indio_dev->name = id->name;
indio_dev->dev.parent = &spi->dev; indio_dev->dev.parent = &spi->dev;
indio_dev->info = &adis16260_info; indio_dev->info = &adis16260_info;
indio_dev->channels = adis16260_channels; indio_dev->channels = adis16260->info->channels;
indio_dev->num_channels = ARRAY_SIZE(adis16260_channels); indio_dev->num_channels = adis16260->info->num_channels;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
ret = adis_init(adis, indio_dev, spi, &adis16260_data); ret = adis_init(&adis16260->adis, indio_dev, spi, &adis16260_data);
if (ret) if (ret)
return ret; return ret;
ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL); ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL);
if (ret) if (ret)
return ret; return ret;
/* Get the device into a sane initial state */ /* Get the device into a sane initial state */
ret = adis_initial_startup(adis); ret = adis_initial_startup(&adis16260->adis);
if (ret) if (ret)
goto error_cleanup_buffer_trigger; goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
...@@ -343,18 +401,18 @@ static int adis16260_probe(struct spi_device *spi) ...@@ -343,18 +401,18 @@ static int adis16260_probe(struct spi_device *spi)
return 0; return 0;
error_cleanup_buffer_trigger: error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(adis, indio_dev); adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev);
return ret; return ret;
} }
static int adis16260_remove(struct spi_device *spi) static int adis16260_remove(struct spi_device *spi)
{ {
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adis *adis = iio_priv(indio_dev); struct adis16260 *adis16260 = iio_priv(indio_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
adis16260_stop_device(indio_dev); adis16260_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(adis, indio_dev); adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev);
return 0; return 0;
} }
...@@ -364,11 +422,12 @@ static int adis16260_remove(struct spi_device *spi) ...@@ -364,11 +422,12 @@ static int adis16260_remove(struct spi_device *spi)
* support for the on chip filtering. * support for the on chip filtering.
*/ */
static const struct spi_device_id adis16260_id[] = { static const struct spi_device_id adis16260_id[] = {
{"adis16260", 0}, {"adis16260", ADIS16260},
{"adis16265", 0}, {"adis16265", ADIS16260},
{"adis16250", 0}, {"adis16266", ADIS16266},
{"adis16255", 0}, {"adis16250", ADIS16260},
{"adis16251", 1}, {"adis16255", ADIS16260},
{"adis16251", ADIS16251},
{} {}
}; };
MODULE_DEVICE_TABLE(spi, adis16260_id); MODULE_DEVICE_TABLE(spi, adis16260_id);
......
...@@ -379,7 +379,6 @@ MODULE_DEVICE_TABLE(i2c, itg3200_id); ...@@ -379,7 +379,6 @@ MODULE_DEVICE_TABLE(i2c, itg3200_id);
static struct i2c_driver itg3200_driver = { static struct i2c_driver itg3200_driver = {
.driver = { .driver = {
.owner = THIS_MODULE,
.name = "itg3200", .name = "itg3200",
.pm = &itg3200_pm_ops, .pm = &itg3200_pm_ops,
}, },
......
...@@ -131,6 +131,7 @@ static const struct iio_chan_spec st_gyro_16bit_channels[] = { ...@@ -131,6 +131,7 @@ static const struct iio_chan_spec st_gyro_16bit_channels[] = {
static const struct st_sensor_settings st_gyro_sensors_settings[] = { static const struct st_sensor_settings st_gyro_sensors_settings[] = {
{ {
.wai = ST_GYRO_1_WAI_EXP, .wai = ST_GYRO_1_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = L3G4200D_GYRO_DEV_NAME, [0] = L3G4200D_GYRO_DEV_NAME,
[1] = LSM330DL_GYRO_DEV_NAME, [1] = LSM330DL_GYRO_DEV_NAME,
...@@ -190,6 +191,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = { ...@@ -190,6 +191,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
}, },
{ {
.wai = ST_GYRO_2_WAI_EXP, .wai = ST_GYRO_2_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = L3GD20_GYRO_DEV_NAME, [0] = L3GD20_GYRO_DEV_NAME,
[1] = LSM330D_GYRO_DEV_NAME, [1] = LSM330D_GYRO_DEV_NAME,
...@@ -252,6 +254,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = { ...@@ -252,6 +254,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
}, },
{ {
.wai = ST_GYRO_3_WAI_EXP, .wai = ST_GYRO_3_WAI_EXP,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = { .sensors_supported = {
[0] = L3GD20_GYRO_DEV_NAME, [0] = L3GD20_GYRO_DEV_NAME,
}, },
......
...@@ -99,7 +99,6 @@ MODULE_DEVICE_TABLE(i2c, st_gyro_id_table); ...@@ -99,7 +99,6 @@ MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
static struct i2c_driver st_gyro_driver = { static struct i2c_driver st_gyro_driver = {
.driver = { .driver = {
.owner = THIS_MODULE,
.name = "st-gyro-i2c", .name = "st-gyro-i2c",
.of_match_table = of_match_ptr(st_gyro_of_match), .of_match_table = of_match_ptr(st_gyro_of_match),
}, },
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/timekeeping.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
...@@ -46,7 +47,8 @@ ...@@ -46,7 +47,8 @@
* Note that when reading the sensor actually 84 edges are detected, but * Note that when reading the sensor actually 84 edges are detected, but
* since the last edge is not significant, we only store 83: * since the last edge is not significant, we only store 83:
*/ */
#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1) #define DHT11_EDGES_PER_READ (2 * DHT11_BITS_PER_READ + \
DHT11_EDGES_PREAMBLE + 1)
/* Data transmission timing (nano seconds) */ /* Data transmission timing (nano seconds) */
#define DHT11_START_TRANSMISSION 18 /* ms */ #define DHT11_START_TRANSMISSION 18 /* ms */
...@@ -62,6 +64,7 @@ struct dht11 { ...@@ -62,6 +64,7 @@ struct dht11 {
int irq; int irq;
struct completion completion; struct completion completion;
/* The iio sysfs interface doesn't prevent concurrent reads: */
struct mutex lock; struct mutex lock;
s64 timestamp; s64 timestamp;
...@@ -87,32 +90,20 @@ static unsigned char dht11_decode_byte(int *timing, int threshold) ...@@ -87,32 +90,20 @@ static unsigned char dht11_decode_byte(int *timing, int threshold)
return ret; return ret;
} }
static int dht11_decode(struct dht11 *dht11, int offset) static int dht11_decode(struct dht11 *dht11, int offset, int timeres)
{ {
int i, t, timing[DHT11_BITS_PER_READ], threshold, int i, t, timing[DHT11_BITS_PER_READ], threshold;
timeres = DHT11_SENSOR_RESPONSE;
unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum; unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum;
/* Calculate timestamp resolution */
for (i = 1; i < dht11->num_edges; ++i) {
t = dht11->edges[i].ts - dht11->edges[i-1].ts;
if (t > 0 && t < timeres)
timeres = t;
}
if (2*timeres > DHT11_DATA_BIT_HIGH) {
pr_err("dht11: timeresolution %d too bad for decoding\n",
timeres);
return -EIO;
}
threshold = DHT11_DATA_BIT_HIGH / timeres; threshold = DHT11_DATA_BIT_HIGH / timeres;
if (DHT11_DATA_BIT_LOW/timeres + 1 >= threshold) if (DHT11_DATA_BIT_LOW / timeres + 1 >= threshold)
pr_err("dht11: WARNING: decoding ambiguous\n"); pr_err("dht11: WARNING: decoding ambiguous\n");
/* scale down with timeres and check validity */ /* scale down with timeres and check validity */
for (i = 0; i < DHT11_BITS_PER_READ; ++i) { for (i = 0; i < DHT11_BITS_PER_READ; ++i) {
t = dht11->edges[offset + 2*i + 2].ts - t = dht11->edges[offset + 2 * i + 2].ts -
dht11->edges[offset + 2*i + 1].ts; dht11->edges[offset + 2 * i + 1].ts;
if (!dht11->edges[offset + 2*i + 1].value) if (!dht11->edges[offset + 2 * i + 1].value)
return -EIO; /* lost synchronisation */ return -EIO; /* lost synchronisation */
timing[i] = t / timeres; timing[i] = t / timeres;
} }
...@@ -126,7 +117,7 @@ static int dht11_decode(struct dht11 *dht11, int offset) ...@@ -126,7 +117,7 @@ static int dht11_decode(struct dht11 *dht11, int offset)
if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum) if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum)
return -EIO; return -EIO;
dht11->timestamp = iio_get_time_ns(); dht11->timestamp = ktime_get_real_ns();
if (hum_int < 20) { /* DHT22 */ if (hum_int < 20) { /* DHT22 */
dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) * dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) *
((temp_int & 0x80) ? -100 : 100); ((temp_int & 0x80) ? -100 : 100);
...@@ -154,7 +145,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data) ...@@ -154,7 +145,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)
/* TODO: Consider making the handler safe for IRQ sharing */ /* TODO: Consider making the handler safe for IRQ sharing */
if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
dht11->edges[dht11->num_edges].ts = iio_get_time_ns(); dht11->edges[dht11->num_edges].ts = ktime_get_real_ns();
dht11->edges[dht11->num_edges++].value = dht11->edges[dht11->num_edges++].value =
gpio_get_value(dht11->gpio); gpio_get_value(dht11->gpio);
...@@ -170,10 +161,22 @@ static int dht11_read_raw(struct iio_dev *iio_dev, ...@@ -170,10 +161,22 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
int *val, int *val2, long m) int *val, int *val2, long m)
{ {
struct dht11 *dht11 = iio_priv(iio_dev); struct dht11 *dht11 = iio_priv(iio_dev);
int ret; int ret, timeres;
mutex_lock(&dht11->lock); mutex_lock(&dht11->lock);
if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) { if (dht11->timestamp + DHT11_DATA_VALID_TIME < ktime_get_real_ns()) {
timeres = ktime_get_resolution_ns();
if (DHT11_DATA_BIT_HIGH < 2 * timeres) {
dev_err(dht11->dev, "timeresolution %dns too low\n",
timeres);
/* In theory a better clock could become available
* at some point ... and there is no error code
* that really fits better.
*/
ret = -EAGAIN;
goto err;
}
reinit_completion(&dht11->completion); reinit_completion(&dht11->completion);
dht11->num_edges = 0; dht11->num_edges = 0;
...@@ -208,7 +211,8 @@ static int dht11_read_raw(struct iio_dev *iio_dev, ...@@ -208,7 +211,8 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
ret = dht11_decode(dht11, ret = dht11_decode(dht11,
dht11->num_edges == DHT11_EDGES_PER_READ ? dht11->num_edges == DHT11_EDGES_PER_READ ?
DHT11_EDGES_PREAMBLE : DHT11_EDGES_PREAMBLE :
DHT11_EDGES_PREAMBLE - 2); DHT11_EDGES_PREAMBLE - 2,
timeres);
if (ret) if (ret)
goto err; goto err;
} }
...@@ -261,9 +265,10 @@ static int dht11_probe(struct platform_device *pdev) ...@@ -261,9 +265,10 @@ static int dht11_probe(struct platform_device *pdev)
dht11 = iio_priv(iio); dht11 = iio_priv(iio);
dht11->dev = dev; dht11->dev = dev;
dht11->gpio = ret = of_get_gpio(node, 0); ret = of_get_gpio(node, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
dht11->gpio = ret;
ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name); ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name);
if (ret) if (ret)
return ret; return ret;
...@@ -274,7 +279,7 @@ static int dht11_probe(struct platform_device *pdev) ...@@ -274,7 +279,7 @@ static int dht11_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1; dht11->timestamp = ktime_get_real_ns() - DHT11_DATA_VALID_TIME - 1;
dht11->num_edges = -1; dht11->num_edges = -1;
platform_set_drvdata(pdev, iio); platform_set_drvdata(pdev, iio);
......
...@@ -177,7 +177,6 @@ MODULE_DEVICE_TABLE(i2c, si7005_id); ...@@ -177,7 +177,6 @@ MODULE_DEVICE_TABLE(i2c, si7005_id);
static struct i2c_driver si7005_driver = { static struct i2c_driver si7005_driver = {
.driver = { .driver = {
.name = "si7005", .name = "si7005",
.owner = THIS_MODULE,
}, },
.probe = si7005_probe, .probe = si7005_probe,
.id_table = si7005_id, .id_table = si7005_id,
......
...@@ -139,7 +139,9 @@ enum adis16400_chip_variant { ...@@ -139,7 +139,9 @@ enum adis16400_chip_variant {
ADIS16360, ADIS16360,
ADIS16362, ADIS16362,
ADIS16364, ADIS16364,
ADIS16367,
ADIS16400, ADIS16400,
ADIS16445,
ADIS16448, ADIS16448,
}; };
...@@ -622,6 +624,17 @@ static const struct iio_chan_spec adis16400_channels[] = { ...@@ -622,6 +624,17 @@ static const struct iio_chan_spec adis16400_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
}; };
static const struct iio_chan_spec adis16445_channels[] = {
ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 16),
ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 16),
ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 16),
ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 16),
ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 16),
ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 16),
ADIS16400_TEMP_CHAN(ADIS16448_TEMP_OUT, 12),
IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
};
static const struct iio_chan_spec adis16448_channels[] = { static const struct iio_chan_spec adis16448_channels[] = {
ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 16), ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 16),
ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 16), ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 16),
...@@ -696,7 +709,8 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -696,7 +709,8 @@ static struct adis16400_chip_info adis16400_chips[] = {
[ADIS16300] = { [ADIS16300] = {
.channels = adis16300_channels, .channels = adis16300_channels,
.num_channels = ARRAY_SIZE(adis16300_channels), .num_channels = ARRAY_SIZE(adis16300_channels),
.flags = ADIS16400_HAS_SLOW_MODE, .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
.accel_scale_micro = 5884, .accel_scale_micro = 5884,
.temp_scale_nano = 140000000, /* 0.14 C */ .temp_scale_nano = 140000000, /* 0.14 C */
...@@ -763,6 +777,18 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -763,6 +777,18 @@ static struct adis16400_chip_info adis16400_chips[] = {
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
}, },
[ADIS16367] = {
.channels = adis16350_channels,
.num_channels = ARRAY_SIZE(adis16350_channels),
.flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
ADIS16400_HAS_SERIAL_NUMBER,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(2000), /* 0.2 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
.temp_scale_nano = 136000000, /* 0.136 C */
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
},
[ADIS16400] = { [ADIS16400] = {
.channels = adis16400_channels, .channels = adis16400_channels,
.num_channels = ARRAY_SIZE(adis16400_channels), .num_channels = ARRAY_SIZE(adis16400_channels),
...@@ -774,13 +800,26 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -774,13 +800,26 @@ static struct adis16400_chip_info adis16400_chips[] = {
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
}, },
[ADIS16445] = {
.channels = adis16445_channels,
.num_channels = ARRAY_SIZE(adis16445_channels),
.flags = ADIS16400_HAS_PROD_ID |
ADIS16400_HAS_SERIAL_NUMBER |
ADIS16400_BURST_DIAG_STAT,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(250), /* 1/4000 g */
.temp_scale_nano = 73860000, /* 0.07386 C */
.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
.set_freq = adis16334_set_freq,
.get_freq = adis16334_get_freq,
},
[ADIS16448] = { [ADIS16448] = {
.channels = adis16448_channels, .channels = adis16448_channels,
.num_channels = ARRAY_SIZE(adis16448_channels), .num_channels = ARRAY_SIZE(adis16448_channels),
.flags = ADIS16400_HAS_PROD_ID | .flags = ADIS16400_HAS_PROD_ID |
ADIS16400_HAS_SERIAL_NUMBER | ADIS16400_HAS_SERIAL_NUMBER |
ADIS16400_BURST_DIAG_STAT, ADIS16400_BURST_DIAG_STAT,
.gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */ .gyro_scale_micro = IIO_DEGREE_TO_RAD(40000), /* 0.04 deg/s */
.accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */ .accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */
.temp_scale_nano = 73860000, /* 0.07386 C */ .temp_scale_nano = 73860000, /* 0.07386 C */
.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
...@@ -926,6 +965,7 @@ static int adis16400_remove(struct spi_device *spi) ...@@ -926,6 +965,7 @@ static int adis16400_remove(struct spi_device *spi)
static const struct spi_device_id adis16400_id[] = { static const struct spi_device_id adis16400_id[] = {
{"adis16300", ADIS16300}, {"adis16300", ADIS16300},
{"adis16305", ADIS16300},
{"adis16334", ADIS16334}, {"adis16334", ADIS16334},
{"adis16350", ADIS16350}, {"adis16350", ADIS16350},
{"adis16354", ADIS16350}, {"adis16354", ADIS16350},
...@@ -934,8 +974,10 @@ static const struct spi_device_id adis16400_id[] = { ...@@ -934,8 +974,10 @@ static const struct spi_device_id adis16400_id[] = {
{"adis16362", ADIS16362}, {"adis16362", ADIS16362},
{"adis16364", ADIS16364}, {"adis16364", ADIS16364},
{"adis16365", ADIS16360}, {"adis16365", ADIS16360},
{"adis16367", ADIS16367},
{"adis16400", ADIS16400}, {"adis16400", ADIS16400},
{"adis16405", ADIS16400}, {"adis16405", ADIS16400},
{"adis16445", ADIS16445},
{"adis16448", ADIS16448}, {"adis16448", ADIS16448},
{} {}
}; };
......
...@@ -110,6 +110,10 @@ ...@@ -110,6 +110,10 @@
struct adis16480_chip_info { struct adis16480_chip_info {
unsigned int num_channels; unsigned int num_channels;
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
unsigned int gyro_max_val;
unsigned int gyro_max_scale;
unsigned int accel_max_val;
unsigned int accel_max_scale;
}; };
struct adis16480 { struct adis16480 {
...@@ -497,19 +501,21 @@ static int adis16480_set_filter_freq(struct iio_dev *indio_dev, ...@@ -497,19 +501,21 @@ static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
static int adis16480_read_raw(struct iio_dev *indio_dev, static int adis16480_read_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *val, int *val2, long info) const struct iio_chan_spec *chan, int *val, int *val2, long info)
{ {
struct adis16480 *st = iio_priv(indio_dev);
switch (info) { switch (info) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
return adis_single_conversion(indio_dev, chan, 0, val); return adis_single_conversion(indio_dev, chan, 0, val);
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
switch (chan->type) { switch (chan->type) {
case IIO_ANGL_VEL: case IIO_ANGL_VEL:
*val = 0; *val = st->chip_info->gyro_max_scale;
*val2 = IIO_DEGREE_TO_RAD(20000); /* 0.02 degree/sec */ *val2 = st->chip_info->gyro_max_val;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_FRACTIONAL;
case IIO_ACCEL: case IIO_ACCEL:
*val = 0; *val = st->chip_info->accel_max_scale;
*val2 = IIO_G_TO_M_S_2(800); /* 0.8 mg */ *val2 = st->chip_info->accel_max_val;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_FRACTIONAL;
case IIO_MAGN: case IIO_MAGN:
*val = 0; *val = 0;
*val2 = 100; /* 0.0001 gauss */ *val2 = 100; /* 0.0001 gauss */
...@@ -674,18 +680,39 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { ...@@ -674,18 +680,39 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
[ADIS16375] = { [ADIS16375] = {
.channels = adis16485_channels, .channels = adis16485_channels,
.num_channels = ARRAY_SIZE(adis16485_channels), .num_channels = ARRAY_SIZE(adis16485_channels),
/*
* storing the value in rad/degree and the scale in degree
* gives us the result in rad and better precession than
* storing the scale directly in rad.
*/
.gyro_max_val = IIO_RAD_TO_DEGREE(22887),
.gyro_max_scale = 300,
.accel_max_val = IIO_M_S_2_TO_G(21973),
.accel_max_scale = 18,
}, },
[ADIS16480] = { [ADIS16480] = {
.channels = adis16480_channels, .channels = adis16480_channels,
.num_channels = ARRAY_SIZE(adis16480_channels), .num_channels = ARRAY_SIZE(adis16480_channels),
.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
.gyro_max_scale = 450,
.accel_max_val = IIO_M_S_2_TO_G(12500),
.accel_max_scale = 5,
}, },
[ADIS16485] = { [ADIS16485] = {
.channels = adis16485_channels, .channels = adis16485_channels,
.num_channels = ARRAY_SIZE(adis16485_channels), .num_channels = ARRAY_SIZE(adis16485_channels),
.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
.gyro_max_scale = 450,
.accel_max_val = IIO_M_S_2_TO_G(20000),
.accel_max_scale = 5,
}, },
[ADIS16488] = { [ADIS16488] = {
.channels = adis16480_channels, .channels = adis16480_channels,
.num_channels = ARRAY_SIZE(adis16480_channels), .num_channels = ARRAY_SIZE(adis16480_channels),
.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
.gyro_max_scale = 450,
.accel_max_val = IIO_M_S_2_TO_G(22500),
.accel_max_scale = 18,
}, },
}; };
......
...@@ -690,6 +690,10 @@ static const struct iio_chan_spec inv_mpu_channels[] = { ...@@ -690,6 +690,10 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
/* constant IIO attribute */ /* constant IIO attribute */
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500"); static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
static IIO_CONST_ATTR(in_anglvel_scale_available,
"0.000133090 0.000266181 0.000532362 0.001064724");
static IIO_CONST_ATTR(in_accel_scale_available,
"0.000598 0.001196 0.002392 0.004785");
static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show, static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
inv_mpu6050_fifo_rate_store); inv_mpu6050_fifo_rate_store);
static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL, static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
...@@ -702,6 +706,8 @@ static struct attribute *inv_attributes[] = { ...@@ -702,6 +706,8 @@ static struct attribute *inv_attributes[] = {
&iio_dev_attr_in_accel_matrix.dev_attr.attr, &iio_dev_attr_in_accel_matrix.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_const_attr_in_accel_scale_available.dev_attr.attr,
&iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
NULL, NULL,
}; };
...@@ -921,7 +927,6 @@ static struct i2c_driver inv_mpu_driver = { ...@@ -921,7 +927,6 @@ static struct i2c_driver inv_mpu_driver = {
.remove = inv_mpu_remove, .remove = inv_mpu_remove,
.id_table = inv_mpu_id, .id_table = inv_mpu_id,
.driver = { .driver = {
.owner = THIS_MODULE,
.name = "inv-mpu6050", .name = "inv-mpu6050",
.pm = INV_MPU6050_PMOPS, .pm = INV_MPU6050_PMOPS,
.acpi_match_table = ACPI_PTR(inv_acpi_match), .acpi_match_table = ACPI_PTR(inv_acpi_match),
......
...@@ -1363,7 +1363,7 @@ static int kmx61_probe(struct i2c_client *client, ...@@ -1363,7 +1363,7 @@ static int kmx61_probe(struct i2c_client *client,
if (client->irq < 0) if (client->irq < 0)
client->irq = kmx61_gpio_probe(client, data); client->irq = kmx61_gpio_probe(client, data);
if (client->irq >= 0) { if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev, client->irq, ret = devm_request_threaded_irq(&client->dev, client->irq,
kmx61_data_rdy_trig_poll, kmx61_data_rdy_trig_poll,
kmx61_event_handler, kmx61_event_handler,
...@@ -1445,10 +1445,10 @@ static int kmx61_probe(struct i2c_client *client, ...@@ -1445,10 +1445,10 @@ static int kmx61_probe(struct i2c_client *client,
err_iio_unregister_acc: err_iio_unregister_acc:
iio_device_unregister(data->acc_indio_dev); iio_device_unregister(data->acc_indio_dev);
err_buffer_cleanup_mag: err_buffer_cleanup_mag:
if (client->irq >= 0) if (client->irq > 0)
iio_triggered_buffer_cleanup(data->mag_indio_dev); iio_triggered_buffer_cleanup(data->mag_indio_dev);
err_buffer_cleanup_acc: err_buffer_cleanup_acc:
if (client->irq >= 0) if (client->irq > 0)
iio_triggered_buffer_cleanup(data->acc_indio_dev); iio_triggered_buffer_cleanup(data->acc_indio_dev);
err_trigger_unregister_motion: err_trigger_unregister_motion:
iio_trigger_unregister(data->motion_trig); iio_trigger_unregister(data->motion_trig);
...@@ -1472,7 +1472,7 @@ static int kmx61_remove(struct i2c_client *client) ...@@ -1472,7 +1472,7 @@ static int kmx61_remove(struct i2c_client *client)
iio_device_unregister(data->acc_indio_dev); iio_device_unregister(data->acc_indio_dev);
iio_device_unregister(data->mag_indio_dev); iio_device_unregister(data->mag_indio_dev);
if (client->irq >= 0) { if (client->irq > 0) {
iio_triggered_buffer_cleanup(data->acc_indio_dev); iio_triggered_buffer_cleanup(data->acc_indio_dev);
iio_triggered_buffer_cleanup(data->mag_indio_dev); iio_triggered_buffer_cleanup(data->mag_indio_dev);
iio_trigger_unregister(data->acc_dready_trig); iio_trigger_unregister(data->acc_dready_trig);
......
...@@ -71,8 +71,9 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf, ...@@ -71,8 +71,9 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
if (avail >= to_wait) { if (avail >= to_wait) {
/* force a flush for non-blocking reads */ /* force a flush for non-blocking reads */
if (!to_wait && !avail && to_flush) if (!to_wait && avail < to_flush)
iio_buffer_flush_hwfifo(indio_dev, buf, to_flush); iio_buffer_flush_hwfifo(indio_dev, buf,
to_flush - avail);
return true; return true;
} }
...@@ -90,9 +91,16 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf, ...@@ -90,9 +91,16 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
/** /**
* iio_buffer_read_first_n_outer() - chrdev read for buffer access * iio_buffer_read_first_n_outer() - chrdev read for buffer access
* @filp: File structure pointer for the char device
* @buf: Destination buffer for iio buffer read
* @n: First n bytes to read
* @f_ps: Long offset provided by the user as a seek position
* *
* This function relies on all buffer implementations having an * This function relies on all buffer implementations having an
* iio_buffer as their first element. * iio_buffer as their first element.
*
* Return: negative values corresponding to error codes or ret != 0
* for ending the reading activity
**/ **/
ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
size_t n, loff_t *f_ps) size_t n, loff_t *f_ps)
...@@ -100,8 +108,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, ...@@ -100,8 +108,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
struct iio_dev *indio_dev = filp->private_data; struct iio_dev *indio_dev = filp->private_data;
struct iio_buffer *rb = indio_dev->buffer; struct iio_buffer *rb = indio_dev->buffer;
size_t datum_size; size_t datum_size;
size_t to_wait = 0; size_t to_wait;
size_t to_read;
int ret; int ret;
if (!indio_dev->info) if (!indio_dev->info)
...@@ -119,14 +126,14 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, ...@@ -119,14 +126,14 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
if (!datum_size) if (!datum_size)
return 0; return 0;
to_read = min_t(size_t, n / datum_size, rb->watermark); if (filp->f_flags & O_NONBLOCK)
to_wait = 0;
if (!(filp->f_flags & O_NONBLOCK)) else
to_wait = to_read; to_wait = min_t(size_t, n / datum_size, rb->watermark);
do { do {
ret = wait_event_interruptible(rb->pollq, ret = wait_event_interruptible(rb->pollq,
iio_buffer_ready(indio_dev, rb, to_wait, to_read)); iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size));
if (ret) if (ret)
return ret; return ret;
...@@ -143,6 +150,12 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, ...@@ -143,6 +150,12 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
/** /**
* iio_buffer_poll() - poll the buffer to find out if it has data * iio_buffer_poll() - poll the buffer to find out if it has data
* @filp: File structure pointer for device access
* @wait: Poll table structure pointer for which the driver adds
* a wait queue
*
* Return: (POLLIN | POLLRDNORM) if data is available for reading
* or 0 for other cases
*/ */
unsigned int iio_buffer_poll(struct file *filp, unsigned int iio_buffer_poll(struct file *filp,
struct poll_table_struct *wait) struct poll_table_struct *wait)
...@@ -151,7 +164,7 @@ unsigned int iio_buffer_poll(struct file *filp, ...@@ -151,7 +164,7 @@ unsigned int iio_buffer_poll(struct file *filp,
struct iio_buffer *rb = indio_dev->buffer; struct iio_buffer *rb = indio_dev->buffer;
if (!indio_dev->info) if (!indio_dev->info)
return -ENODEV; return 0;
poll_wait(filp, &rb->pollq, wait); poll_wait(filp, &rb->pollq, wait);
if (iio_buffer_ready(indio_dev, rb, rb->watermark, 0)) if (iio_buffer_ready(indio_dev, rb, rb->watermark, 0))
...@@ -1136,7 +1149,7 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, ...@@ -1136,7 +1149,7 @@ int iio_scan_mask_query(struct iio_dev *indio_dev,
EXPORT_SYMBOL_GPL(iio_scan_mask_query); EXPORT_SYMBOL_GPL(iio_scan_mask_query);
/** /**
* struct iio_demux_table() - table describing demux memcpy ops * struct iio_demux_table - table describing demux memcpy ops
* @from: index to copy from * @from: index to copy from
* @to: index to copy to * @to: index to copy to
* @length: how many bytes to copy * @length: how many bytes to copy
......
...@@ -81,6 +81,14 @@ static const char * const iio_modifier_names[] = { ...@@ -81,6 +81,14 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_X] = "x", [IIO_MOD_X] = "x",
[IIO_MOD_Y] = "y", [IIO_MOD_Y] = "y",
[IIO_MOD_Z] = "z", [IIO_MOD_Z] = "z",
[IIO_MOD_X_AND_Y] = "x&y",
[IIO_MOD_X_AND_Z] = "x&z",
[IIO_MOD_Y_AND_Z] = "y&z",
[IIO_MOD_X_AND_Y_AND_Z] = "x&y&z",
[IIO_MOD_X_OR_Y] = "x|y",
[IIO_MOD_X_OR_Z] = "x|z",
[IIO_MOD_Y_OR_Z] = "y|z",
[IIO_MOD_X_OR_Y_OR_Z] = "x|y|z",
[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
[IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_BOTH] = "both",
...@@ -398,10 +406,16 @@ EXPORT_SYMBOL_GPL(iio_enum_write); ...@@ -398,10 +406,16 @@ EXPORT_SYMBOL_GPL(iio_enum_write);
/** /**
* iio_format_value() - Formats a IIO value into its string representation * iio_format_value() - Formats a IIO value into its string representation
* @buf: The buffer to which the formated value gets written * @buf: The buffer to which the formatted value gets written
* @type: One of the IIO_VAL_... constants. This decides how the val and val2 * @type: One of the IIO_VAL_... constants. This decides how the val
* parameters are formatted. * and val2 parameters are formatted.
* @vals: pointer to the values, exact meaning depends on the type parameter. * @size: Number of IIO value entries contained in vals
* @vals: Pointer to the values, exact meaning depends on the
* type parameter.
*
* Return: 0 by default, a negative number on failure or the
* total number of characters written for a type that belongs
* to the IIO_VAL_... constant.
*/ */
ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals) ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals)
{ {
...@@ -1088,6 +1102,11 @@ EXPORT_SYMBOL_GPL(devm_iio_device_free); ...@@ -1088,6 +1102,11 @@ EXPORT_SYMBOL_GPL(devm_iio_device_free);
/** /**
* iio_chrdev_open() - chrdev file open for buffer access and ioctls * iio_chrdev_open() - chrdev file open for buffer access and ioctls
* @inode: Inode structure for identifying the device in the file system
* @filp: File structure for iio device used to keep and later access
* private data
*
* Return: 0 on success or -EBUSY if the device is already opened
**/ **/
static int iio_chrdev_open(struct inode *inode, struct file *filp) static int iio_chrdev_open(struct inode *inode, struct file *filp)
{ {
...@@ -1106,7 +1125,11 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) ...@@ -1106,7 +1125,11 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
/** /**
* iio_chrdev_release() - chrdev file close buffer access and ioctls * iio_chrdev_release() - chrdev file close buffer access and ioctls
**/ * @inode: Inode structure pointer for the char device
* @filp: File structure pointer for the char device
*
* Return: 0 for successful release
*/
static int iio_chrdev_release(struct inode *inode, struct file *filp) static int iio_chrdev_release(struct inode *inode, struct file *filp)
{ {
struct iio_dev *indio_dev = container_of(inode->i_cdev, struct iio_dev *indio_dev = container_of(inode->i_cdev,
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
* @dev_attr_list: list of event interface sysfs attribute * @dev_attr_list: list of event interface sysfs attribute
* @flags: file operations related flags including busy flag. * @flags: file operations related flags including busy flag.
* @group: event interface sysfs attribute group * @group: event interface sysfs attribute group
* @read_lock: lock to protect kfifo read operations
*/ */
struct iio_event_interface { struct iio_event_interface {
wait_queue_head_t wait; wait_queue_head_t wait;
...@@ -75,6 +76,11 @@ EXPORT_SYMBOL(iio_push_event); ...@@ -75,6 +76,11 @@ EXPORT_SYMBOL(iio_push_event);
/** /**
* iio_event_poll() - poll the event queue to find out if it has data * iio_event_poll() - poll the event queue to find out if it has data
* @filep: File structure pointer to identify the device
* @wait: Poll table pointer to add the wait queue on
*
* Return: (POLLIN | POLLRDNORM) if data is available for reading
* or a negative error code on failure
*/ */
static unsigned int iio_event_poll(struct file *filep, static unsigned int iio_event_poll(struct file *filep,
struct poll_table_struct *wait) struct poll_table_struct *wait)
...@@ -84,7 +90,7 @@ static unsigned int iio_event_poll(struct file *filep, ...@@ -84,7 +90,7 @@ static unsigned int iio_event_poll(struct file *filep,
unsigned int events = 0; unsigned int events = 0;
if (!indio_dev->info) if (!indio_dev->info)
return -ENODEV; return events;
poll_wait(filep, &ev_int->wait, wait); poll_wait(filep, &ev_int->wait, wait);
......
...@@ -40,7 +40,14 @@ static DEFINE_MUTEX(iio_trigger_list_lock); ...@@ -40,7 +40,14 @@ static DEFINE_MUTEX(iio_trigger_list_lock);
/** /**
* iio_trigger_read_name() - retrieve useful identifying name * iio_trigger_read_name() - retrieve useful identifying name
**/ * @dev: device associated with the iio_trigger
* @attr: pointer to the device_attribute structure that is
* being processed
* @buf: buffer to print the name into
*
* Return: a negative number on failure or the number of written
* characters on success.
*/
static ssize_t iio_trigger_read_name(struct device *dev, static ssize_t iio_trigger_read_name(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
...@@ -288,10 +295,17 @@ EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc); ...@@ -288,10 +295,17 @@ EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc);
/** /**
* iio_trigger_read_current() - trigger consumer sysfs query current trigger * iio_trigger_read_current() - trigger consumer sysfs query current trigger
* @dev: device associated with an industrial I/O device
* @attr: pointer to the device_attribute structure that
* is being processed
* @buf: buffer where the current trigger name will be printed into
* *
* For trigger consumers the current_trigger interface allows the trigger * For trigger consumers the current_trigger interface allows the trigger
* used by the device to be queried. * used by the device to be queried.
**/ *
* Return: a negative number on failure, the number of characters written
* on success or 0 if no trigger is available
*/
static ssize_t iio_trigger_read_current(struct device *dev, static ssize_t iio_trigger_read_current(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
...@@ -305,11 +319,18 @@ static ssize_t iio_trigger_read_current(struct device *dev, ...@@ -305,11 +319,18 @@ static ssize_t iio_trigger_read_current(struct device *dev,
/** /**
* iio_trigger_write_current() - trigger consumer sysfs set current trigger * iio_trigger_write_current() - trigger consumer sysfs set current trigger
* @dev: device associated with an industrial I/O device
* @attr: device attribute that is being processed
* @buf: string buffer that holds the name of the trigger
* @len: length of the trigger name held by buf
* *
* For trigger consumers the current_trigger interface allows the trigger * For trigger consumers the current_trigger interface allows the trigger
* used for this device to be specified at run time based on the trigger's * used for this device to be specified at run time based on the trigger's
* name. * name.
**/ *
* Return: negative error code on failure or length of the buffer
* on success
*/
static ssize_t iio_trigger_write_current(struct device *dev, static ssize_t iio_trigger_write_current(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, const char *buf,
......
...@@ -24,8 +24,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { ...@@ -24,8 +24,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
/** /**
* iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc * iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc
* @indio_dev: IIO device structure * @indio_dev: IIO device structure
* @pollfunc_bh: Function which will be used as pollfunc bottom half * @h: Function which will be used as pollfunc top half
* @pollfunc_th: Function which will be used as pollfunc top half * @thread: Function which will be used as pollfunc bottom half
* @setup_ops: Buffer setup functions to use for this device. * @setup_ops: Buffer setup functions to use for this device.
* If NULL the default setup functions for triggered * If NULL the default setup functions for triggered
* buffers will be used. * buffers will be used.
...@@ -42,8 +42,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { ...@@ -42,8 +42,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
* iio_triggered_buffer_cleanup(). * iio_triggered_buffer_cleanup().
*/ */
int iio_triggered_buffer_setup(struct iio_dev *indio_dev, int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
irqreturn_t (*pollfunc_bh)(int irq, void *p), irqreturn_t (*h)(int irq, void *p),
irqreturn_t (*pollfunc_th)(int irq, void *p), irqreturn_t (*thread)(int irq, void *p),
const struct iio_buffer_setup_ops *setup_ops) const struct iio_buffer_setup_ops *setup_ops)
{ {
struct iio_buffer *buffer; struct iio_buffer *buffer;
...@@ -57,8 +57,8 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev, ...@@ -57,8 +57,8 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
iio_device_attach_buffer(indio_dev, buffer); iio_device_attach_buffer(indio_dev, buffer);
indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh, indio_dev->pollfunc = iio_alloc_pollfunc(h,
pollfunc_th, thread,
IRQF_ONESHOT, IRQF_ONESHOT,
indio_dev, indio_dev,
"%s_consumer%d", "%s_consumer%d",
......
...@@ -86,7 +86,7 @@ config CM3323 ...@@ -86,7 +86,7 @@ config CM3323
depends on I2C depends on I2C
tristate "Capella CM3323 color light sensor" tristate "Capella CM3323 color light sensor"
help help
Say Y here if you want to build a driver for Capela CM3323 Say Y here if you want to build a driver for Capella CM3323
color sensor. color sensor.
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
...@@ -168,6 +168,17 @@ config JSA1212 ...@@ -168,6 +168,17 @@ config JSA1212
To compile this driver as a module, choose M here: To compile this driver as a module, choose M here:
the module will be called jsa1212. the module will be called jsa1212.
config RPR0521
tristate "ROHM RPR0521 ALS and proximity sensor driver"
depends on I2C
select REGMAP_I2C
help
Say Y here if you want to build support for ROHM's RPR0521
ambient light and proximity sensor device.
To compile this driver as a module, choose M here:
the module will be called rpr0521.
config SENSORS_LM3533 config SENSORS_LM3533
tristate "LM3533 ambient light sensor" tristate "LM3533 ambient light sensor"
depends on MFD_LM3533 depends on MFD_LM3533
...@@ -199,6 +210,27 @@ config LTR501 ...@@ -199,6 +210,27 @@ 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 OPT3001
tristate "Texas Instruments OPT3001 Light Sensor"
depends on I2C
help
If you say Y or M here, you get support for Texas Instruments
OPT3001 Ambient Light Sensor.
If built as a dynamically linked module, it will be called
opt3001.
config PA12203001
tristate "TXC PA12203001 light and proximity sensor"
depends on I2C
select REGMAP_I2C
help
If you say yes here you get support for the TXC PA12203001
ambient light and proximity sensor.
This driver can also be built as a module. If so, the module
will be called pa12203001.
config STK3310 config STK3310
tristate "STK3310 ALS and proximity sensor" tristate "STK3310 ALS and proximity sensor"
depends on I2C depends on I2C
......
...@@ -19,6 +19,9 @@ obj-$(CONFIG_ISL29125) += isl29125.o ...@@ -19,6 +19,9 @@ 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_OPT3001) += opt3001.o
obj-$(CONFIG_PA12203001) += pa12203001.o
obj-$(CONFIG_RPR0521) += rpr0521.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
obj-$(CONFIG_STK3310) += stk3310.o obj-$(CONFIG_STK3310) += stk3310.o
obj-$(CONFIG_TCS3414) += tcs3414.o obj-$(CONFIG_TCS3414) += tcs3414.o
......
...@@ -65,20 +65,20 @@ static const struct iio_chan_spec acpi_als_channels[] = { ...@@ -65,20 +65,20 @@ static const struct iio_chan_spec acpi_als_channels[] = {
* to acpi_als_channels[], the evt_buffer below will grow * to acpi_als_channels[], the evt_buffer below will grow
* automatically. * automatically.
*/ */
#define EVT_NR_SOURCES ARRAY_SIZE(acpi_als_channels) #define ACPI_ALS_EVT_NR_SOURCES ARRAY_SIZE(acpi_als_channels)
#define EVT_BUFFER_SIZE \ #define ACPI_ALS_EVT_BUFFER_SIZE \
(sizeof(s64) + (EVT_NR_SOURCES * sizeof(s32))) (sizeof(s64) + (ACPI_ALS_EVT_NR_SOURCES * sizeof(s32)))
struct acpi_als { struct acpi_als {
struct acpi_device *device; struct acpi_device *device;
struct mutex lock; struct mutex lock;
s32 evt_buffer[EVT_BUFFER_SIZE]; s32 evt_buffer[ACPI_ALS_EVT_BUFFER_SIZE];
}; };
/* /*
* All types of properties the ACPI0008 block can report. The ALI, ALC, ALT * All types of properties the ACPI0008 block can report. The ALI, ALC, ALT
* and ALP can all be handled by als_read_value() below, while the ALR is * and ALP can all be handled by acpi_als_read_value() below, while the ALR is
* special. * special.
* *
* The _ALR property returns tables that can be used to fine-tune the values * The _ALR property returns tables that can be used to fine-tune the values
...@@ -93,7 +93,7 @@ struct acpi_als { ...@@ -93,7 +93,7 @@ struct acpi_als {
#define ACPI_ALS_POLLING "_ALP" #define ACPI_ALS_POLLING "_ALP"
#define ACPI_ALS_TABLES "_ALR" #define ACPI_ALS_TABLES "_ALR"
static int als_read_value(struct acpi_als *als, char *prop, s32 *val) static int acpi_als_read_value(struct acpi_als *als, char *prop, s32 *val)
{ {
unsigned long long temp_val; unsigned long long temp_val;
acpi_status status; acpi_status status;
...@@ -122,11 +122,11 @@ static void acpi_als_notify(struct acpi_device *device, u32 event) ...@@ -122,11 +122,11 @@ static void acpi_als_notify(struct acpi_device *device, u32 event)
mutex_lock(&als->lock); mutex_lock(&als->lock);
memset(buffer, 0, EVT_BUFFER_SIZE); memset(buffer, 0, ACPI_ALS_EVT_BUFFER_SIZE);
switch (event) { switch (event) {
case ACPI_ALS_NOTIFY_ILLUMINANCE: case ACPI_ALS_NOTIFY_ILLUMINANCE:
ret = als_read_value(als, ACPI_ALS_ILLUMINANCE, &val); ret = acpi_als_read_value(als, ACPI_ALS_ILLUMINANCE, &val);
if (ret < 0) if (ret < 0)
goto out; goto out;
*buffer++ = val; *buffer++ = val;
...@@ -159,7 +159,7 @@ static int acpi_als_read_raw(struct iio_dev *indio_dev, ...@@ -159,7 +159,7 @@ static int acpi_als_read_raw(struct iio_dev *indio_dev,
if (chan->type != IIO_LIGHT) if (chan->type != IIO_LIGHT)
return -EINVAL; return -EINVAL;
ret = als_read_value(als, ACPI_ALS_ILLUMINANCE, &temp_val); ret = acpi_als_read_value(als, ACPI_ALS_ILLUMINANCE, &temp_val);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -515,7 +515,6 @@ MODULE_DEVICE_TABLE(i2c, apds9300_id); ...@@ -515,7 +515,6 @@ MODULE_DEVICE_TABLE(i2c, apds9300_id);
static struct i2c_driver apds9300_driver = { static struct i2c_driver apds9300_driver = {
.driver = { .driver = {
.name = APDS9300_DRV_NAME, .name = APDS9300_DRV_NAME,
.owner = THIS_MODULE,
.pm = APDS9300_PM_OPS, .pm = APDS9300_PM_OPS,
}, },
.probe = apds9300_probe, .probe = apds9300_probe,
......
...@@ -319,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, bh1750_id); ...@@ -319,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, bh1750_id);
static struct i2c_driver bh1750_driver = { static struct i2c_driver bh1750_driver = {
.driver = { .driver = {
.name = "bh1750", .name = "bh1750",
.owner = THIS_MODULE,
.pm = BH1750_PM_OPS, .pm = BH1750_PM_OPS,
}, },
.probe = bh1750_probe, .probe = bh1750_probe,
......
...@@ -353,12 +353,12 @@ static const struct of_device_id cm32181_of_match[] = { ...@@ -353,12 +353,12 @@ static const struct of_device_id cm32181_of_match[] = {
{ .compatible = "capella,cm32181" }, { .compatible = "capella,cm32181" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, cm32181_of_match);
static struct i2c_driver cm32181_driver = { static struct i2c_driver cm32181_driver = {
.driver = { .driver = {
.name = "cm32181", .name = "cm32181",
.of_match_table = of_match_ptr(cm32181_of_match), .of_match_table = of_match_ptr(cm32181_of_match),
.owner = THIS_MODULE,
}, },
.id_table = cm32181_id, .id_table = cm32181_id,
.probe = cm32181_probe, .probe = cm32181_probe,
......
...@@ -417,11 +417,11 @@ static const struct of_device_id cm3232_of_match[] = { ...@@ -417,11 +417,11 @@ static const struct of_device_id cm3232_of_match[] = {
{.compatible = "capella,cm3232"}, {.compatible = "capella,cm3232"},
{} {}
}; };
MODULE_DEVICE_TABLE(of, cm3232_of_match);
static struct i2c_driver cm3232_driver = { static struct i2c_driver cm3232_driver = {
.driver = { .driver = {
.name = "cm3232", .name = "cm3232",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(cm3232_of_match), .of_match_table = of_match_ptr(cm3232_of_match),
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.pm = &cm3232_pm_ops, .pm = &cm3232_pm_ops,
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define CM3323_CONF_SD_BIT BIT(0) /* sensor disable */ #define CM3323_CONF_SD_BIT BIT(0) /* sensor disable */
#define CM3323_CONF_AF_BIT BIT(1) /* auto/manual force mode */ #define CM3323_CONF_AF_BIT BIT(1) /* auto/manual force mode */
#define CM3323_CONF_IT_MASK (BIT(4) | BIT(5) | BIT(6)) #define CM3323_CONF_IT_MASK GENMASK(6, 4)
#define CM3323_CONF_IT_SHIFT 4 #define CM3323_CONF_IT_SHIFT 4
#define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28" #define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28"
...@@ -133,9 +133,11 @@ static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2) ...@@ -133,9 +133,11 @@ static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2)
return ret; return ret;
data->reg_conf = reg_conf; data->reg_conf = reg_conf;
return 0; return 0;
} }
} }
return -EINVAL; return -EINVAL;
} }
...@@ -148,6 +150,7 @@ static int cm3323_get_it_bits(struct cm3323_data *data) ...@@ -148,6 +150,7 @@ static int cm3323_get_it_bits(struct cm3323_data *data)
if (bits >= ARRAY_SIZE(cm3323_int_time)) if (bits >= ARRAY_SIZE(cm3323_int_time))
return -EINVAL; return -EINVAL;
return bits; return bits;
} }
...@@ -155,7 +158,7 @@ static int cm3323_read_raw(struct iio_dev *indio_dev, ...@@ -155,7 +158,7 @@ static int cm3323_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, struct iio_chan_spec const *chan, int *val,
int *val2, long mask) int *val2, long mask)
{ {
int i, ret; int ret;
struct cm3323_data *data = iio_priv(indio_dev); struct cm3323_data *data = iio_priv(indio_dev);
switch (mask) { switch (mask) {
...@@ -172,14 +175,14 @@ static int cm3323_read_raw(struct iio_dev *indio_dev, ...@@ -172,14 +175,14 @@ static int cm3323_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_INT_TIME: case IIO_CHAN_INFO_INT_TIME:
mutex_lock(&data->mutex); mutex_lock(&data->mutex);
i = cm3323_get_it_bits(data); ret = cm3323_get_it_bits(data);
if (i < 0) { if (ret < 0) {
mutex_unlock(&data->mutex); mutex_unlock(&data->mutex);
return -EINVAL; return ret;
} }
*val = cm3323_int_time[i].val; *val = cm3323_int_time[ret].val;
*val2 = cm3323_int_time[i].val2; *val2 = cm3323_int_time[ret].val2;
mutex_unlock(&data->mutex); mutex_unlock(&data->mutex);
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
...@@ -243,11 +246,13 @@ static int cm3323_probe(struct i2c_client *client, ...@@ -243,11 +246,13 @@ static int cm3323_probe(struct i2c_client *client,
dev_err(&client->dev, "cm3323 chip init failed\n"); dev_err(&client->dev, "cm3323 chip init failed\n");
return ret; return ret;
} }
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "failed to register iio dev\n"); dev_err(&client->dev, "failed to register iio dev\n");
goto err_init; goto err_init;
} }
return 0; return 0;
err_init: err_init:
cm3323_disable(indio_dev); cm3323_disable(indio_dev);
......
...@@ -731,12 +731,12 @@ static const struct of_device_id cm36651_of_match[] = { ...@@ -731,12 +731,12 @@ static const struct of_device_id cm36651_of_match[] = {
{ .compatible = "capella,cm36651" }, { .compatible = "capella,cm36651" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, cm36651_of_match);
static struct i2c_driver cm36651_driver = { static struct i2c_driver cm36651_driver = {
.driver = { .driver = {
.name = "cm36651", .name = "cm36651",
.of_match_table = cm36651_of_match, .of_match_table = cm36651_of_match,
.owner = THIS_MODULE,
}, },
.probe = cm36651_probe, .probe = cm36651_probe,
.remove = cm36651_remove, .remove = cm36651_remove,
......
...@@ -1634,13 +1634,13 @@ static const struct of_device_id gp2ap020a00f_of_match[] = { ...@@ -1634,13 +1634,13 @@ static const struct of_device_id gp2ap020a00f_of_match[] = {
{ .compatible = "sharp,gp2ap020a00f" }, { .compatible = "sharp,gp2ap020a00f" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match);
#endif #endif
static struct i2c_driver gp2ap020a00f_driver = { static struct i2c_driver gp2ap020a00f_driver = {
.driver = { .driver = {
.name = GP2A_I2C_NAME, .name = GP2A_I2C_NAME,
.of_match_table = of_match_ptr(gp2ap020a00f_of_match), .of_match_table = of_match_ptr(gp2ap020a00f_of_match),
.owner = THIS_MODULE,
}, },
.probe = gp2ap020a00f_probe, .probe = gp2ap020a00f_probe,
.remove = gp2ap020a00f_remove, .remove = gp2ap020a00f_remove,
......
...@@ -284,8 +284,7 @@ static int hid_prox_probe(struct platform_device *pdev) ...@@ -284,8 +284,7 @@ static int hid_prox_probe(struct platform_device *pdev)
goto error_free_dev_mem; goto error_free_dev_mem;
} }
indio_dev->num_channels = indio_dev->num_channels = ARRAY_SIZE(prox_channels);
ARRAY_SIZE(prox_channels);
indio_dev->dev.parent = &pdev->dev; indio_dev->dev.parent = &pdev->dev;
indio_dev->info = &prox_info; indio_dev->info = &prox_info;
indio_dev->name = name; indio_dev->name = name;
......
...@@ -197,9 +197,21 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p) ...@@ -197,9 +197,21 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static IIO_CONST_ATTR(scale_available, "0.005722 0.152590");
static struct attribute *isl29125_attributes[] = {
&iio_const_attr_scale_available.dev_attr.attr,
NULL
};
static const struct attribute_group isl29125_attribute_group = {
.attrs = isl29125_attributes,
};
static const struct iio_info isl29125_info = { static const struct iio_info isl29125_info = {
.read_raw = isl29125_read_raw, .read_raw = isl29125_read_raw,
.write_raw = isl29125_write_raw, .write_raw = isl29125_write_raw,
.attrs = &isl29125_attribute_group,
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
}; };
...@@ -334,7 +346,6 @@ static struct i2c_driver isl29125_driver = { ...@@ -334,7 +346,6 @@ static struct i2c_driver isl29125_driver = {
.driver = { .driver = {
.name = ISL29125_DRV_NAME, .name = ISL29125_DRV_NAME,
.pm = &isl29125_pm_ops, .pm = &isl29125_pm_ops,
.owner = THIS_MODULE,
}, },
.probe = isl29125_probe, .probe = isl29125_probe,
.remove = isl29125_remove, .remove = isl29125_remove,
......
...@@ -457,7 +457,6 @@ static struct i2c_driver jsa1212_driver = { ...@@ -457,7 +457,6 @@ static struct i2c_driver jsa1212_driver = {
.driver = { .driver = {
.name = JSA1212_DRIVER_NAME, .name = JSA1212_DRIVER_NAME,
.pm = JSA1212_PM_OPS, .pm = JSA1212_PM_OPS,
.owner = THIS_MODULE,
.acpi_match_table = ACPI_PTR(jsa1212_acpi_match), .acpi_match_table = ACPI_PTR(jsa1212_acpi_match),
}, },
.probe = jsa1212_probe, .probe = jsa1212_probe,
......
...@@ -1551,7 +1551,6 @@ static struct i2c_driver ltr501_driver = { ...@@ -1551,7 +1551,6 @@ static struct i2c_driver ltr501_driver = {
.name = LTR501_DRV_NAME, .name = LTR501_DRV_NAME,
.pm = &ltr501_pm_ops, .pm = &ltr501_pm_ops,
.acpi_match_table = ACPI_PTR(ltr_acpi_match), .acpi_match_table = ACPI_PTR(ltr_acpi_match),
.owner = THIS_MODULE,
}, },
.probe = ltr501_probe, .probe = ltr501_probe,
.remove = ltr501_remove, .remove = ltr501_remove,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -676,6 +676,7 @@ static const struct i2c_device_id stk3310_i2c_id[] = { ...@@ -676,6 +676,7 @@ static const struct i2c_device_id stk3310_i2c_id[] = {
{"STK3311", 0}, {"STK3311", 0},
{} {}
}; };
MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id);
static const struct acpi_device_id stk3310_acpi_id[] = { static const struct acpi_device_id stk3310_acpi_id[] = {
{"STK3310", 0}, {"STK3310", 0},
......
...@@ -392,7 +392,6 @@ static struct i2c_driver tcs3414_driver = { ...@@ -392,7 +392,6 @@ static struct i2c_driver tcs3414_driver = {
.driver = { .driver = {
.name = TCS3414_DRV_NAME, .name = TCS3414_DRV_NAME,
.pm = &tcs3414_pm_ops, .pm = &tcs3414_pm_ops,
.owner = THIS_MODULE,
}, },
.probe = tcs3414_probe, .probe = tcs3414_probe,
.remove = tcs3414_remove, .remove = tcs3414_remove,
......
...@@ -366,7 +366,6 @@ static struct i2c_driver tcs3472_driver = { ...@@ -366,7 +366,6 @@ static struct i2c_driver tcs3472_driver = {
.driver = { .driver = {
.name = TCS3472_DRV_NAME, .name = TCS3472_DRV_NAME,
.pm = &tcs3472_pm_ops, .pm = &tcs3472_pm_ops,
.owner = THIS_MODULE,
}, },
.probe = tcs3472_probe, .probe = tcs3472_probe,
.remove = tcs3472_remove, .remove = tcs3472_remove,
......
...@@ -247,7 +247,6 @@ static struct i2c_driver tsl4531_driver = { ...@@ -247,7 +247,6 @@ static struct i2c_driver tsl4531_driver = {
.driver = { .driver = {
.name = TSL4531_DRV_NAME, .name = TSL4531_DRV_NAME,
.pm = TSL4531_PM_OPS, .pm = TSL4531_PM_OPS,
.owner = THIS_MODULE,
}, },
.probe = tsl4531_probe, .probe = tsl4531_probe,
.remove = tsl4531_remove, .remove = tsl4531_remove,
......
...@@ -185,7 +185,6 @@ static int vcnl4000_probe(struct i2c_client *client, ...@@ -185,7 +185,6 @@ static int vcnl4000_probe(struct i2c_client *client,
static struct i2c_driver vcnl4000_driver = { static struct i2c_driver vcnl4000_driver = {
.driver = { .driver = {
.name = VCNL4000_DRV_NAME, .name = VCNL4000_DRV_NAME,
.owner = THIS_MODULE,
}, },
.probe = vcnl4000_probe, .probe = vcnl4000_probe,
.id_table = vcnl4000_id, .id_table = vcnl4000_id,
......
此差异已折叠。
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define LSM303DLHC_MAGN_DEV_NAME "lsm303dlhc_magn" #define LSM303DLHC_MAGN_DEV_NAME "lsm303dlhc_magn"
#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn" #define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
#define LIS3MDL_MAGN_DEV_NAME "lis3mdl" #define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
#define LSM303AGR_MAGN_DEV_NAME "lsm303agr_magn"
int st_magn_common_probe(struct iio_dev *indio_dev); int st_magn_common_probe(struct iio_dev *indio_dev);
void st_magn_common_remove(struct iio_dev *indio_dev); void st_magn_common_remove(struct iio_dev *indio_dev);
...@@ -25,6 +26,8 @@ void st_magn_common_remove(struct iio_dev *indio_dev); ...@@ -25,6 +26,8 @@ void st_magn_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER #ifdef CONFIG_IIO_BUFFER
int st_magn_allocate_ring(struct iio_dev *indio_dev); int st_magn_allocate_ring(struct iio_dev *indio_dev);
void st_magn_deallocate_ring(struct iio_dev *indio_dev); void st_magn_deallocate_ring(struct iio_dev *indio_dev);
int st_magn_trig_set_state(struct iio_trigger *trig, bool state);
#define ST_MAGN_TRIGGER_SET_STATE (&st_magn_trig_set_state)
#else /* CONFIG_IIO_BUFFER */ #else /* CONFIG_IIO_BUFFER */
static inline int st_magn_probe_trigger(struct iio_dev *indio_dev, int irq) static inline int st_magn_probe_trigger(struct iio_dev *indio_dev, int irq)
{ {
......
...@@ -51,6 +51,7 @@ static const struct spi_device_id st_magn_id_table[] = { ...@@ -51,6 +51,7 @@ static const struct spi_device_id st_magn_id_table[] = {
{ LSM303DLHC_MAGN_DEV_NAME }, { LSM303DLHC_MAGN_DEV_NAME },
{ LSM303DLM_MAGN_DEV_NAME }, { LSM303DLM_MAGN_DEV_NAME },
{ LIS3MDL_MAGN_DEV_NAME }, { LIS3MDL_MAGN_DEV_NAME },
{ LSM303AGR_MAGN_DEV_NAME },
{}, {},
}; };
MODULE_DEVICE_TABLE(spi, st_magn_id_table); MODULE_DEVICE_TABLE(spi, st_magn_id_table);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册