Merge tag 'iio-for-4.3a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2015 19:32:09 +0000 (12:32 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2015 19:32:09 +0000 (12:32 -0700)
Jonathan writes:

First round of new drivers, cleanups and functionality for IIO in the 4.3 cycle.

Core and tools new stuff
* Allow explicit flush of hardware fifo by using an non blocking read.
  This is needed to support some of the Android requirements for HW fifo
  devices - also makes sense generally and clarifies a corner of the ABI.
* Add some missing modifier names.  Mostly these exist for weird and
  wonderful event types, but should still be present in the name array.
* Update iio_event_monitor to cope with new channel types.
* generic_buffer gains support for single byte scan elements (no idea
  how this never got implemented before!)

New device support
* ROHM rpr0521 light and proximity sensor driver.
* bmc150 gains bmc156 support.
* ms5611 gains ms5607 temperature and pressure sensor support.

Driver functionality
* inv-mpu - add scale_available attributes to aid userspace in
  configuring these devices.
* isl29125 - add scale_available attributes.
* stk8ba50 - sampling frequency control, triggered buffer support.
* stk8312 - sampling frequency control, triggered buffer support.
cc10001 - ensure ADC powered up at probe time if shared by non linux
  running CPUs.
* bmc150-magn - decouple the buffer and trigger allowing other triggers
  to be used to drive this device's sampling.
Documentation
* Add some previously missed *scale_available attributes to the ABI docs.

Cleanups
* Clarify some crazy naming in iio_triggered_buffer_setup that seems to
  have somehow ended up backwards (dates back a long way).  Avoid the top
  half and bottom half naming entirely given we are how dealing with a
  handler and a thread in all cases.
* Tools cleanup including coding style, variable naming improvements, also
  a new sanity check on a full event having been read.
* stk8ba50 - replace the scale table with a struct for clarity. Also suspend
  the sensor if an error occurs in init.
* hid-sensor-prox - drop uneeded line break.
* mma9551 - use size in words for word read / write avoiding accidental
  sending of an odd number of bytes.
* mma9553 - fix code alignment and document the use of a mutex.
* light/Kconfig - typo fix in commment.
* cm3323 - don't eat an error value, replace an unneeded local variable with
  a generic local variable with the same use, add some blank lines for clarity.
* pressure/Kconfig - typo in Measurement Specialties name.
* bmc150-accel - actually use a mask definition rather than repeating the
  value inline, code style cleanup.
* adc/Kconfig - general help description cleanup.
* ssp_sensors - drop redundant spi driver bus initialization (done in the
  spi core)
* tmp006 - use genmask rather than hand generated masks.
* ms5611 - drop IIO_CHAN_INFO_SCALE as this driver provides a processed
  output and as such the read only scale adds nothing useful.
* kxcjk-1013, adf4350, dummy - drop unwanted blank lines.
* Drop all owner assignments from i2c_drivers and this is done in the
  i2c core.

68 files changed:
Documentation/ABI/testing/sysfs-bus-iio
drivers/iio/accel/bma180.c
drivers/iio/accel/bmc150-accel.c
drivers/iio/accel/kxcjk-1013.c
drivers/iio/accel/mma9551_core.c
drivers/iio/accel/mma9551_core.h
drivers/iio/accel/mma9553.c
drivers/iio/accel/st_accel_i2c.c
drivers/iio/accel/stk8312.c
drivers/iio/accel/stk8ba50.c
drivers/iio/adc/Kconfig
drivers/iio/adc/cc10001_adc.c
drivers/iio/adc/mcp3422.c
drivers/iio/adc/ti-adc081c.c
drivers/iio/common/ssp_sensors/ssp_dev.c
drivers/iio/dac/ad5064.c
drivers/iio/dac/ad5380.c
drivers/iio/dac/ad5446.c
drivers/iio/dac/max5821.c
drivers/iio/frequency/adf4350.c
drivers/iio/gyro/itg3200_core.c
drivers/iio/gyro/st_gyro_i2c.c
drivers/iio/humidity/si7005.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-triggered-buffer.c
drivers/iio/light/Kconfig
drivers/iio/light/Makefile
drivers/iio/light/apds9300.c
drivers/iio/light/bh1750.c
drivers/iio/light/cm32181.c
drivers/iio/light/cm3232.c
drivers/iio/light/cm3323.c
drivers/iio/light/cm36651.c
drivers/iio/light/gp2ap020a00f.c
drivers/iio/light/hid-sensor-prox.c
drivers/iio/light/isl29125.c
drivers/iio/light/jsa1212.c
drivers/iio/light/ltr501.c
drivers/iio/light/rpr0521.c [new file with mode: 0644]
drivers/iio/light/tcs3414.c
drivers/iio/light/tcs3472.c
drivers/iio/light/tsl4531.c
drivers/iio/light/vcnl4000.c
drivers/iio/magnetometer/bmc150_magn.c
drivers/iio/magnetometer/st_magn_i2c.c
drivers/iio/pressure/Kconfig
drivers/iio/pressure/ms5611.h
drivers/iio/pressure/ms5611_core.c
drivers/iio/pressure/ms5611_i2c.c
drivers/iio/pressure/ms5611_spi.c
drivers/iio/pressure/st_pressure_i2c.c
drivers/iio/temperature/mlx90614.c
drivers/iio/temperature/tmp006.c
drivers/staging/iio/addac/adt7316-i2c.c
drivers/staging/iio/iio_dummy_evgen.c
drivers/staging/iio/iio_simple_dummy.c
drivers/staging/iio/iio_simple_dummy.h
drivers/staging/iio/iio_simple_dummy_buffer.c
drivers/staging/iio/light/isl29018.c
drivers/staging/iio/light/isl29028.c
include/linux/iio/triggered_buffer.h
tools/iio/generic_buffer.c
tools/iio/iio_event_monitor.c
tools/iio/iio_utils.c
tools/iio/iio_utils.h
tools/iio/lsiio.c

index bbed111c31b4ed7658e61ac6b7140284c3035dc6..666a341b01b808f1960b1270596cfc68b21b42e1 100644 (file)
@@ -413,6 +413,11 @@ Description:
                to compute the calories burnt by the user.
 
 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_voltage-voltage_scale_available
 What:          /sys/.../iio:deviceX/out_voltageX_scale_available
index 75c6d2103e07adad3b11919687e81f8dd7a8fca3..f04b88406995175bc5159a8f300295e33ec3df80 100644 (file)
@@ -846,7 +846,6 @@ MODULE_DEVICE_TABLE(i2c, bma180_ids);
 static struct i2c_driver bma180_driver = {
        .driver = {
                .name   = "bma180",
-               .owner  = THIS_MODULE,
                .pm     = BMA180_PM_OPS,
        },
        .probe          = bma180_probe,
index 4e70f51c237089f54ebee9882df499551d56b1e3..47c6013ab37622b0d8c7ae9b0b32549aab98660c 100644 (file)
@@ -241,7 +241,6 @@ static const struct {
                                       {500000, BMC150_ACCEL_SLEEP_500_MS},
                                       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
 
-
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
                                 enum bmc150_power_modes mode,
                                 int dur_us)
@@ -259,8 +258,9 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
                                dur_val =
                                bmc150_accel_sleep_value_table[i].reg_value;
                }
-       } else
+       } else {
                dur_val = 0;
+       }
 
        if (dur_val < 0)
                return -EINVAL;
@@ -288,7 +288,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
 
        for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
                if (bmc150_accel_samp_freq_table[i].val == val &&
-                               bmc150_accel_samp_freq_table[i].val2 == val2) {
+                   bmc150_accel_samp_freq_table[i].val2 == val2) {
                        ret = i2c_smbus_write_byte_data(
                                data->client,
                                BMC150_ACCEL_REG_PMU_BW,
@@ -351,8 +351,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 
        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");
+               dev_err(&data->client->dev, "Error: Reading chip id\n");
                return ret;
        }
 
@@ -376,8 +375,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
                                        BMC150_ACCEL_REG_PMU_RANGE,
                                        BMC150_ACCEL_DEF_RANGE_4G);
        if (ret < 0) {
-               dev_err(&data->client->dev,
-                                       "Error writing reg_pmu_range\n");
+               dev_err(&data->client->dev, "Error writing reg_pmu_range\n");
                return ret;
        }
 
@@ -437,12 +435,13 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
 {
        int ret;
 
-       if (on)
+       if (on) {
                ret = pm_runtime_get_sync(&data->client->dev);
-       else {
+       else {
                pm_runtime_mark_last_busy(&data->client->dev);
                ret = pm_runtime_put_autosuspend(&data->client->dev);
        }
+
        if (ret < 0) {
                dev_err(&data->client->dev,
                        "Failed: bmc150_accel_set_power_state for %d\n", on);
@@ -514,13 +513,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
-        * in reverse order. This will happen here anyway as our
-        * resume operation uses sync mode runtime pm calls, the
-        * suspend operation will be delayed by autosuspend delay
-        * So the disable operation will still happen in reverse of
-        * enable operation. When runtime pm is disabled the mode
-        * is always on so sequence doesn't matter
+        * We will expect the enable and disable to do operation in reverse
+        * order. This will happen here anyway, as our resume operation uses
+        * sync mode runtime pm calls. The suspend operation will be delayed
+        * by autosuspend delay.
+        * So the disable operation will still happen in reverse order of
+        * enable operation. When runtime pm is disabled the mode is always on,
+        * so sequence doesn't matter.
         */
        ret = bmc150_accel_set_power_state(data, state);
        if (ret < 0)
@@ -574,7 +573,6 @@ out_fix_power_state:
        return ret;
 }
 
-
 static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 {
        int ret, i;
@@ -674,8 +672,9 @@ static int bmc150_accel_read_raw(struct iio_dev *indio_dev,
                if (chan->type == IIO_TEMP) {
                        *val = BMC150_ACCEL_TEMP_CENTER_VAL;
                        return IIO_VAL_INT;
-               } else
+               } else {
                        return -EINVAL;
+               }
        case IIO_CHAN_INFO_SCALE:
                *val = 0;
                switch (chan->type) {
@@ -776,7 +775,7 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev,
 
        switch (info) {
        case IIO_EV_INFO_VALUE:
-               data->slope_thres = val & 0xFF;
+               data->slope_thres = val & BMC150_ACCEL_SLOPE_THRES_MASK;
                break;
        case IIO_EV_INFO_PERIOD:
                data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK;
@@ -793,7 +792,6 @@ static int bmc150_accel_read_event_config(struct iio_dev *indio_dev,
                                          enum iio_event_type type,
                                          enum iio_event_direction dir)
 {
-
        struct bmc150_accel_data *data = iio_priv(indio_dev);
 
        return data->ev_enable_state;
@@ -827,7 +825,7 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev,
 }
 
 static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev,
-                                  struct iio_trigger *trig)
+                                        struct iio_trigger *trig)
 {
        struct bmc150_accel_data *data = iio_priv(indio_dev);
        int i;
@@ -963,6 +961,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
        u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
        int64_t tstamp;
        uint64_t sample_period;
+
        ret = i2c_smbus_read_byte_data(data->client,
                                       BMC150_ACCEL_REG_FIFO_STATUS);
        if (ret < 0) {
@@ -1255,7 +1254,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
 }
 
 static int bmc150_accel_trigger_set_state(struct iio_trigger *trig,
-                                                  bool state)
+                                         bool state)
 {
        struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig);
        struct bmc150_accel_data *data = t->data;
@@ -1314,26 +1313,32 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
                dir = IIO_EV_DIR_RISING;
 
        if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
-               iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
-                                                       0,
-                                                       IIO_MOD_X,
-                                                       IIO_EV_TYPE_ROC,
-                                                       dir),
-                                                       data->timestamp);
+               iio_push_event(indio_dev,
+                              IIO_MOD_EVENT_CODE(IIO_ACCEL,
+                                                 0,
+                                                 IIO_MOD_X,
+                                                 IIO_EV_TYPE_ROC,
+                                                 dir),
+                              data->timestamp);
+
        if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
-               iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
-                                                       0,
-                                                       IIO_MOD_Y,
-                                                       IIO_EV_TYPE_ROC,
-                                                       dir),
-                                                       data->timestamp);
+               iio_push_event(indio_dev,
+                              IIO_MOD_EVENT_CODE(IIO_ACCEL,
+                                                 0,
+                                                 IIO_MOD_Y,
+                                                 IIO_EV_TYPE_ROC,
+                                                 dir),
+                              data->timestamp);
+
        if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
-               iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
-                                                       0,
-                                                       IIO_MOD_Z,
-                                                       IIO_EV_TYPE_ROC,
-                                                       dir),
-                                                       data->timestamp);
+               iio_push_event(indio_dev,
+                              IIO_MOD_EVENT_CODE(IIO_ACCEL,
+                                                 0,
+                                                 IIO_MOD_Z,
+                                                 IIO_EV_TYPE_ROC,
+                                                 dir),
+                              data->timestamp);
+
        return ret;
 }
 
@@ -1365,7 +1370,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
                                        BMC150_ACCEL_INT_MODE_LATCH_INT |
                                        BMC150_ACCEL_INT_MODE_LATCH_RESET);
                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;
        } else {
                ret = IRQ_NONE;
@@ -1412,13 +1419,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
        if (!id)
                return NULL;
 
-       *data = (int) id->driver_data;
+       *data = (int)id->driver_data;
 
        return dev_name(dev);
 }
 
 static int bmc150_accel_gpio_probe(struct i2c_client *client,
-                                       struct bmc150_accel_data *data)
+                                  struct bmc150_accel_data *data)
 {
        struct device *dev;
        struct gpio_desc *gpio;
index 0d9bd35ff2586bfe4c5d8c776e7196d62a85c474..8128579bff795956b6a688d4b93a848d018657bc 100644 (file)
@@ -658,10 +658,8 @@ static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val)
        int ret, i;
        enum kxcjk1013_mode store_mode;
 
-
        for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) {
                if (KXCJK1013_scale_table[i].scale == val) {
-
                        ret = kxcjk1013_get_mode(data, &store_mode);
                        if (ret < 0)
                                return ret;
@@ -820,7 +818,6 @@ static int kxcjk1013_read_event_config(struct iio_dev *indio_dev,
                                          enum iio_event_type type,
                                          enum iio_event_direction dir)
 {
-
        struct kxcjk1013_data *data = iio_priv(indio_dev);
 
        return data->ev_enable_state;
index 2fd2a995686b273dae815f2bdb344c6a10284ea0..c34c5ce8123b0938f14c255a21c636dc09e4c513 100644 (file)
@@ -297,7 +297,7 @@ EXPORT_SYMBOL(mma9551_read_status_byte);
  * Returns: 0 on success, negative value on failure.
  */
 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
-                           u16 reg, u16 *val)
+                            u16 reg, u16 *val)
 {
        int ret;
        __be16 v;
@@ -328,12 +328,12 @@ EXPORT_SYMBOL(mma9551_read_config_word);
  * Returns: 0 on success, negative value on failure.
  */
 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
-                            u16 reg, u16 val)
+                             u16 reg, u16 val)
 {
        __be16 v = cpu_to_be16(val);
 
        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);
 
@@ -373,7 +373,7 @@ EXPORT_SYMBOL(mma9551_read_status_word);
  * @client:    I2C client
  * @app_id:    Application ID
  * @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
  *
  * Read multiple configuration registers (word-sized registers).
@@ -385,23 +385,22 @@ EXPORT_SYMBOL(mma9551_read_status_word);
  * Returns: 0 on success, negative value on failure.
  */
 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 len_words = len / sizeof(u16);
        __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);
                return -EINVAL;
        }
 
        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)
                return ret;
 
-       for (i = 0; i < len_words; i++)
+       for (i = 0; i < len; i++)
                buf[i] = be16_to_cpu(be_buf[i]);
 
        return 0;
@@ -413,7 +412,7 @@ EXPORT_SYMBOL(mma9551_read_config_words);
  * @client:    I2C client
  * @app_id:    Application ID
  * @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
  *
  * Read multiple status registers (word-sized registers).
@@ -428,20 +427,19 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
                              u16 reg, u8 len, u16 *buf)
 {
        int ret, i;
-       int len_words = len / sizeof(u16);
        __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);
                return -EINVAL;
        }
 
        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)
                return ret;
 
-       for (i = 0; i < len_words; i++)
+       for (i = 0; i < len; i++)
                buf[i] = be16_to_cpu(be_buf[i]);
 
        return 0;
@@ -453,7 +451,7 @@ EXPORT_SYMBOL(mma9551_read_status_words);
  * @client:    I2C client
  * @app_id:    Application ID
  * @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
  *
  * Write multiple configuration registers (word-sized registers).
@@ -468,19 +466,18 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
                               u16 reg, u8 len, u16 *buf)
 {
        int i;
-       int len_words = len / sizeof(u16);
        __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);
                return -EINVAL;
        }
 
-       for (i = 0; i < len_words; i++)
+       for (i = 0; i < len; i++)
                be_buf[i] = cpu_to_be16(buf[i]);
 
        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);
 
index 79939e40805a00ead1b15809653d5e9d24756edc..5e88e6454dfd927c7d49e0307614a1a85c4ec3d3 100644 (file)
@@ -53,13 +53,13 @@ int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
 int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
                             u16 reg, u8 *val);
 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
-                           u16 reg, u16 *val);
+                            u16 reg, u16 *val);
 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
-                            u16 reg, u16 val);
+                             u16 reg, u16 val);
 int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
                             u16 reg, u16 *val);
 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 mma9551_read_status_words(struct i2c_client *client, u8 app_id,
                              u16 reg, u8 len, u16 *buf);
 int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
index 8bfc61824fb2378ab8554777bc1d0842c2bdb7a0..a605280637e933ccacd0d07917b8054904634bba 100644 (file)
@@ -182,6 +182,10 @@ struct mma9553_conf_regs {
 
 struct mma9553_data {
        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 mma9553_conf_regs conf;
        struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];
@@ -322,7 +326,8 @@ static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
        int ret;
 
        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) {
                dev_err(&data->client->dev,
                        "error reading status and stepcnt\n");
@@ -342,10 +347,10 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
        struct mma9553_event *ev_step_detect;
        bool activity_enabled;
 
-       activity_enabled =
-           mma9553_is_any_event_enabled(data, true, IIO_ACTIVITY);
-       ev_step_detect =
-           mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
+       activity_enabled = mma9553_is_any_event_enabled(data, true,
+                                                       IIO_ACTIVITY);
+       ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,
+                                          IIO_EV_DIR_NONE);
 
        /*
         * 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)
                        return ret;
        }
 
-       ret = mma9551_gpio_config(data->client,
-                                 MMA9553_DEFAULT_GPIO_PIN,
-                                 appid, bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
+       ret = mma9551_gpio_config(data->client, MMA9553_DEFAULT_GPIO_PIN, appid,
+                                 bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
        if (ret < 0)
                return ret;
        data->gpio_bitnum = bitnum;
@@ -394,17 +398,16 @@ static int mma9553_init(struct mma9553_data *data)
         * a device identification command to differentiate the MMA9553L
         * from the MMA9550L.
         */
-       ret =
-           mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
-                                     MMA9553_REG_CONF_SLEEPMIN,
-                                     sizeof(data->conf), (u16 *) &data->conf);
+       ret = mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
+                                       MMA9553_REG_CONF_SLEEPMIN,
+                                       sizeof(data->conf) / sizeof(u16),
+                                       (u16 *)&data->conf);
        if (ret < 0) {
                dev_err(&data->client->dev,
                        "failed to read configuration registers\n");
                return ret;
        }
 
-
        /* Reset GPIO */
        data->gpio_bitnum = MMA9553_MAX_BITNUM;
        ret = mma9553_conf_gpio(data);
@@ -419,18 +422,18 @@ static int mma9553_init(struct mma9553_data *data)
        data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;
        data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;
        data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;
-       data->conf.config =
-           mma9553_set_bits(data->conf.config, 1, MMA9553_MASK_CONF_CONFIG);
+       data->conf.config = mma9553_set_bits(data->conf.config, 1,
+                                            MMA9553_MASK_CONF_CONFIG);
        /*
         * Clear the activity debounce counter when the activity level changes,
         * so that the confidence level applies for any activity level.
         */
        data->conf.config = mma9553_set_bits(data->conf.config, 1,
                                             MMA9553_MASK_CONF_ACT_DBCNTM);
-       ret =
-           mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
-                                      MMA9553_REG_CONF_SLEEPMIN,
-                                      sizeof(data->conf), (u16 *) &data->conf);
+       ret = mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
+                                        MMA9553_REG_CONF_SLEEPMIN,
+                                        sizeof(data->conf) / sizeof(u16),
+                                        (u16 *)&data->conf);
        if (ret < 0) {
                dev_err(&data->client->dev,
                        "failed to write configuration registers\n");
@@ -567,7 +570,7 @@ static int mma9553_read_raw(struct iio_dev *indio_dev,
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_CALIBHEIGHT:
                tmp = mma9553_get_bits(data->conf.height_weight,
-                                       MMA9553_MASK_CONF_HEIGHT);
+                                      MMA9553_MASK_CONF_HEIGHT);
                *val = tmp / 100;       /* cm to m */
                *val2 = (tmp % 100) * 10000;
                return IIO_VAL_INT_PLUS_MICRO;
@@ -719,7 +722,6 @@ static int mma9553_read_event_config(struct iio_dev *indio_dev,
                                     enum iio_event_type type,
                                     enum iio_event_direction dir)
 {
-
        struct mma9553_data *data = iio_priv(indio_dev);
        struct mma9553_event *event;
 
@@ -1026,22 +1028,22 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
                return IRQ_HANDLED;
        }
 
-       ev_prev_activity =
-           mma9553_get_event(data, IIO_ACTIVITY,
-                             mma9553_activity_to_mod(data->activity),
-                             IIO_EV_DIR_FALLING);
-       ev_activity =
-           mma9553_get_event(data, IIO_ACTIVITY,
-                             mma9553_activity_to_mod(activity),
-                             IIO_EV_DIR_RISING);
-       ev_step_detect =
-           mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
+       ev_prev_activity = mma9553_get_event(data, IIO_ACTIVITY,
+                                            mma9553_activity_to_mod(
+                                            data->activity),
+                                            IIO_EV_DIR_FALLING);
+       ev_activity = mma9553_get_event(data, IIO_ACTIVITY,
+                                       mma9553_activity_to_mod(activity),
+                                       IIO_EV_DIR_RISING);
+       ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,
+                                          IIO_EV_DIR_NONE);
 
        if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {
                data->stepcnt = stepcnt;
                iio_push_event(indio_dev,
                               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);
        }
 
@@ -1051,17 +1053,19 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
                if (ev_prev_activity && ev_prev_activity->enabled)
                        iio_push_event(indio_dev,
                                       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
-                                      ev_prev_activity->info->mod,
-                                      IIO_EV_DIR_FALLING,
-                                      IIO_EV_TYPE_THRESH, 0, 0, 0),
+                                                   ev_prev_activity->info->mod,
+                                                   IIO_EV_DIR_FALLING,
+                                                   IIO_EV_TYPE_THRESH, 0, 0,
+                                                   0),
                                       data->timestamp);
 
                if (ev_activity && ev_activity->enabled)
                        iio_push_event(indio_dev,
                                       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
-                                      ev_activity->info->mod,
-                                      IIO_EV_DIR_RISING,
-                                      IIO_EV_TYPE_THRESH, 0, 0, 0),
+                                                     ev_activity->info->mod,
+                                                     IIO_EV_DIR_RISING,
+                                                     IIO_EV_TYPE_THRESH, 0, 0,
+                                                     0),
                                       data->timestamp);
        }
        mutex_unlock(&data->mutex);
@@ -1156,7 +1160,6 @@ static int mma9553_probe(struct i2c_client *client,
                                client->irq);
                        goto out_poweroff;
                }
-
        }
 
        ret = iio_device_register(indio_dev);
index d4ad72ca4a3de258ef1772492fae50901d6f34a8..a2f1c20319eb3a6f852b459a17059d29d1ebaa3d 100644 (file)
@@ -122,7 +122,6 @@ MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
 
 static struct i2c_driver st_accel_driver = {
        .driver = {
-               .owner = THIS_MODULE,
                .name = "st-accel-i2c",
                .of_match_table = of_match_ptr(st_accel_of_match),
        },
index d211d9f3975b823e3026cfec2b4871c2ca924bd3..c2bd1444d6daffafcdd5cede819247bec9d76e64 100644 (file)
  */
 
 #include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/iio.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_YOUT               0x01
 #define STK8312_REG_ZOUT               0x02
+#define STK8312_REG_INTSU              0x06
 #define STK8312_REG_MODE               0x07
+#define STK8312_REG_SR                 0x08
 #define STK8312_REG_STH                        0x13
 #define STK8312_REG_RESET              0x20
 #define STK8312_REG_AFECTRL            0x24
 #define STK8312_REG_OTPDATA            0x3E
 #define STK8312_REG_OTPCTRL            0x3F
 
-#define STK8312_MODE_ACTIVE            1
-#define STK8312_MODE_STANDBY           0
-#define STK8312_MODE_MASK              0x01
+#define STK8312_MODE_ACTIVE            0x01
+#define STK8312_MODE_STANDBY           0x00
+#define STK8312_DREADY_BIT             0x10
+#define STK8312_INT_MODE               0xC0
 #define STK8312_RNG_MASK               0xC0
+#define STK8312_SR_MASK                        0x07
+#define STK8312_SR_400HZ_IDX           0
 #define STK8312_RNG_SHIFT              6
 #define STK8312_READ_RETRIES           16
+#define STK8312_ALL_CHANNEL_MASK       7
+#define STK8312_ALL_CHANNEL_SIZE       3
 
 #define STK8312_DRIVER_NAME            "stk8312"
+#define STK8312_GPIO                   "stk8312_gpio"
+#define STK8312_IRQ_NAME               "stk8312_event"
 
 /*
  * The accelerometer has two measurement ranges:
@@ -53,32 +68,56 @@ static const int stk8312_scale_table[][2] = {
        {0, 461600}, {1, 231100}
 };
 
-#define STK8312_ACCEL_CHANNEL(reg, axis) {                     \
-       .type = IIO_ACCEL,                                      \
-       .address = reg,                                         \
-       .modified = 1,                                          \
-       .channel2 = IIO_MOD_##axis,                             \
-       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
-       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+static const struct {
+       u16 val;
+       u32 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,                                              \
+       .address = reg,                                                 \
+       .modified = 1,                                                  \
+       .channel2 = IIO_MOD_##axis,                                     \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
+       .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[] = {
-       STK8312_ACCEL_CHANNEL(STK8312_REG_XOUT, X),
-       STK8312_ACCEL_CHANNEL(STK8312_REG_YOUT, Y),
-       STK8312_ACCEL_CHANNEL(STK8312_REG_ZOUT, Z),
+       STK8312_ACCEL_CHANNEL(0, STK8312_REG_XOUT, X),
+       STK8312_ACCEL_CHANNEL(1, STK8312_REG_YOUT, Y),
+       STK8312_ACCEL_CHANNEL(2, STK8312_REG_ZOUT, Z),
+       IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 
 struct stk8312_data {
        struct i2c_client *client;
        struct mutex lock;
        int range;
+       u8 sample_rate_idx;
        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_SAMP_FREQ_AVAIL("3.125 6.25 12.5 25 50 100 200 400");
+
 static struct attribute *stk8312_attributes[] = {
        &iio_const_attr_in_accel_scale_available.dev_attr.attr,
+       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        NULL,
 };
 
@@ -130,31 +169,19 @@ exit_err:
 static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
 {
        int ret;
-       u8 masked_reg;
        struct i2c_client *client = data->client;
 
-       if (mode > 1)
-               return -EINVAL;
-       else if (mode == data->mode)
+       if (mode == data->mode)
                return 0;
 
-       ret = i2c_smbus_read_byte_data(client, STK8312_REG_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);
+       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;
        }
 
        data->mode = mode;
-       if (mode == STK8312_MODE_ACTIVE) {
+       if (mode & STK8312_MODE_ACTIVE) {
                /* Need to run OTP sequence before entering active mode */
                usleep_range(1000, 5000);
                ret = stk8312_otp_init(data);
@@ -163,6 +190,85 @@ static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
        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");
+
+       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 ret;
+}
+
+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, int 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) {
+               dev_err(&client->dev, "failed to set sampling rate\n");
+               return ret;
+       }
+
+       masked_reg = (ret & (~STK8312_SR_MASK)) | rate;
+
+       ret = i2c_smbus_write_byte_data(client, STK8312_REG_SR, masked_reg);
+       if (ret < 0)
+               dev_err(&client->dev, "failed to set sampling rate\n");
+       else
+               data->sample_rate_idx = rate;
+
+       return stk8312_set_mode(data, mode);
+}
+
 static int stk8312_set_range(struct stk8312_data *data, u8 range)
 {
        int ret;
@@ -208,12 +314,10 @@ static int stk8312_read_accel(struct stk8312_data *data, u8 address)
                return -EINVAL;
 
        ret = i2c_smbus_read_byte_data(client, address);
-       if (ret < 0) {
+       if (ret < 0)
                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,
@@ -221,20 +325,37 @@ static int stk8312_read_raw(struct iio_dev *indio_dev,
                            int *val, int *val2, long mask)
 {
        struct stk8312_data *data = iio_priv(indio_dev);
-
-       if (chan->type != IIO_ACCEL)
-               return -EINVAL;
+       int ret;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
+               if (iio_buffer_enabled(indio_dev))
+                       return -EBUSY;
                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 -EINVAL;
+               }
+               ret = stk8312_read_accel(data, chan->address);
+               if (ret < 0) {
+                       stk8312_set_mode(data,
+                                        data->mode & (~STK8312_MODE_ACTIVE));
+                       mutex_unlock(&data->lock);
+                       return -EINVAL;
+               }
+               *val = sign_extend32(ret, 7);
+               stk8312_set_mode(data, data->mode & (~STK8312_MODE_ACTIVE));
                mutex_unlock(&data->lock);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
                *val = stk8312_scale_table[data->range - 1][0];
                *val2 = stk8312_scale_table[data->range - 1][1];
                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;
@@ -264,6 +385,20 @@ static int stk8312_write_raw(struct iio_dev *indio_dev,
                ret = stk8312_set_range(data, index);
                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;
        }
 
@@ -277,6 +412,109 @@ static const struct iio_info stk8312_info = {
        .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;
+       u8 buffer[STK8312_ALL_CHANNEL_SIZE];
+
+       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,
+                                                   buffer);
+               if (ret < STK8312_ALL_CHANNEL_SIZE) {
+                       dev_err(&data->client->dev, "register read failed\n");
+                       mutex_unlock(&data->lock);
+                       goto err;
+               }
+               data->buffer[0] = buffer[0];
+               data->buffer[1] = buffer[1];
+               data->buffer[2] = buffer[2];
+       } 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,
                         const struct i2c_device_id *id)
 {
@@ -308,30 +546,90 @@ static int stk8312_probe(struct i2c_client *client,
                dev_err(&client->dev, "failed to reset sensor\n");
                return ret;
        }
+       data->sample_rate_idx = STK8312_SR_400HZ_IDX;
        ret = stk8312_set_range(data, 1);
        if (ret < 0)
                return ret;
 
-       ret = stk8312_set_mode(data, STK8312_MODE_ACTIVE);
+       ret = stk8312_set_mode(data, STK8312_INT_MODE | STK8312_MODE_ACTIVE);
        if (ret < 0)
                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);
        if (ret < 0) {
                dev_err(&client->dev, "device_register failed\n");
-               stk8312_set_mode(data, STK8312_MODE_STANDBY);
+               goto err_buffer_cleanup;
        }
 
        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:
+       stk8312_set_mode(data, STK8312_MODE_STANDBY);
+       return ret;
 }
 
 static int stk8312_remove(struct i2c_client *client)
 {
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct stk8312_data *data = iio_priv(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
@@ -341,7 +639,7 @@ static int stk8312_suspend(struct device *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)
@@ -350,7 +648,7 @@ static int stk8312_resume(struct device *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);
index 30950c6b36de1f36ac709c4a3548d0a804cb2ccf..16cee637109b846add6f4cf5b87a58e622c59657 100644 (file)
  */
 
 #include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/iio.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_YOUT                      0x04
 #define STK8BA50_REG_ZOUT                      0x06
 #define STK8BA50_REG_RANGE                     0x0F
+#define STK8BA50_REG_BWSEL                     0x10
 #define STK8BA50_REG_POWMODE                   0x11
 #define STK8BA50_REG_SWRST                     0x14
+#define STK8BA50_REG_INTEN2                    0x17
+#define STK8BA50_REG_INTMAP2                   0x1A
 
 #define STK8BA50_MODE_NORMAL                   0
 #define STK8BA50_MODE_SUSPEND                  1
 #define STK8BA50_MODE_POWERBIT                 BIT(7)
 #define STK8BA50_DATA_SHIFT                    6
 #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_GPIO                          "stk8ba50_gpio"
+#define STK8BA50_IRQ_NAME                      "stk8ba50_event"
 
 #define STK8BA50_SCALE_AVAIL                   "0.0384 0.0767 0.1534 0.3069"
 
  *
  * 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}
 };
 
+/* 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 i2c_client *client;
        struct mutex lock;
        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) {                    \
-       .type = IIO_ACCEL,                                      \
-       .address = reg,                                         \
-       .modified = 1,                                          \
-       .channel2 = IIO_MOD_##axis,                             \
-       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
-       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+#define STK8BA50_ACCEL_CHANNEL(index, reg, axis) {                     \
+       .type = IIO_ACCEL,                                              \
+       .address = reg,                                                 \
+       .modified = 1,                                                  \
+       .channel2 = IIO_MOD_##axis,                                     \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
+       .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[] = {
-       STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_XOUT, X),
-       STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_YOUT, Y),
-       STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_ZOUT, Z),
+       STK8BA50_ACCEL_CHANNEL(0, STK8BA50_REG_XOUT, X),
+       STK8BA50_ACCEL_CHANNEL(1, STK8BA50_REG_YOUT, Y),
+       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_SAMP_FREQ_AVAIL("14 25 56 112 224 448 896 1792");
+
 static struct attribute *stk8ba50_attributes[] = {
        &iio_const_attr_in_accel_scale_available.dev_attr.attr,
+       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        NULL,
 };
 
@@ -97,7 +154,61 @@ static int stk8ba50_read_accel(struct stk8ba50_data *data, u8 reg)
                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,
@@ -105,17 +216,37 @@ static int stk8ba50_read_raw(struct iio_dev *indio_dev,
                             int *val, int *val2, long mask)
 {
        struct stk8ba50_data *data = iio_priv(indio_dev);
+       int ret;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
+               if (iio_buffer_enabled(indio_dev))
+                       return -EBUSY;
                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);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
                *val = 0;
-               *val2 = stk8ba50_scale_table[data->range][1];
+               *val2 = stk8ba50_scale_table[data->range].scale_val;
                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;
@@ -136,7 +267,7 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev,
                        return -EINVAL;
 
                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;
                                break;
                        }
@@ -145,13 +276,32 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev,
 
                ret = i2c_smbus_write_byte_data(data->client,
                                STK8BA50_REG_RANGE,
-                               stk8ba50_scale_table[index][0]);
+                               stk8ba50_scale_table[index].reg_val);
                if (ret < 0)
                        dev_err(&data->client->dev,
                                        "failed to set measurement range\n");
                else
                        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;
        }
 
@@ -165,30 +315,100 @@ static const struct iio_info stk8ba50_info = {
        .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)
 {
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct stk8ba50_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 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)
+                               goto err;
+
+                       data->buffer[i++] = ret;
+               }
+       }
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+                                          pf->timestamp);
+err:
+       mutex_unlock(&data->lock);
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+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;
-       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 (!client)
+               return -EINVAL;
 
-       if (mode)
-               masked_reg = ret | STK8BA50_MODE_POWERBIT;
-       else
-               masked_reg = ret & (~STK8BA50_MODE_POWERBIT);
+       dev = &client->dev;
 
-       ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE,
-                                       masked_reg);
-       if (ret < 0)
-               goto exit_err;
+       /* 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);
+       }
 
-       return ret;
+       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;
 }
 
@@ -222,28 +442,104 @@ static int stk8ba50_probe(struct i2c_client *client,
                        STK8BA50_REG_SWRST, STK8BA50_RESET_CMD);
        if (ret < 0) {
                dev_err(&client->dev, "failed to reset sensor\n");
-               return ret;
+               goto err_power_off;
        }
 
        /* The default range is +/-2g */
        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);
        if (ret < 0) {
                dev_err(&client->dev, "device_register failed\n");
-               stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
+               goto err_buffer_cleanup;
        }
 
        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)
 {
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct stk8ba50_data *data = iio_priv(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
index 7c5565891cb83012f9034b3e9224629c08a00ced..dace593b158b49a1c4bc913332b0333ecb519ef1 100644 (file)
@@ -20,6 +20,9 @@ config AD7266
          Say yes here to build support for Analog Devices AD7265 and AD7266
          ADCs.
 
+         To compile this driver as a module, choose M here: the module will be
+         called ad7266.
+
 config AD7291
        tristate "Analog Devices AD7291 ADC driver"
        depends on I2C
@@ -52,8 +55,6 @@ config AD7476
          AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
          AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
 
-         If unsure, say N (but it's safe to say "Y").
-
          To compile this driver as a module, choose M here: the
          module will be called ad7476.
 
@@ -63,8 +64,7 @@ config AD7791
        select AD_SIGMA_DELTA
        help
          Say yes here to build support for Analog Devices AD7787, AD7788, AD7789,
-         AD7790 and AD7791 SPI analog to digital converters (ADC). If unsure, say
-         N (but it is safe to say "Y").
+         AD7790 and AD7791 SPI analog to digital converters (ADC).
 
          To compile this driver as a module, choose M here: the module will be
          called ad7791.
@@ -76,7 +76,6 @@ config AD7793
        help
          Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
          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
          module will be called AD7793.
@@ -89,7 +88,6 @@ config AD7887
        help
          Say yes here to build support for Analog Devices
          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
          module will be called ad7887.
@@ -117,6 +115,9 @@ config AD799X
          i2c analog to digital converters (ADC). Provides direct access
          via sysfs.
 
+         To compile this driver as a module, choose M here: the module will be
+         called ad799x.
+
 config AT91_ADC
        tristate "Atmel AT91 ADC"
        depends on ARCH_AT91
@@ -127,6 +128,9 @@ config AT91_ADC
        help
          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
        tristate "X-Powers AXP288 ADC driver"
        depends on MFD_AXP20X
@@ -135,6 +139,9 @@ config AXP288_ADC
          device. Depending on platform configuration, this general purpose ADC can
          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
        tristate "Marvell Berlin2 ADC driver"
        depends on ARCH_BERLIN
@@ -151,6 +158,9 @@ config DA9150_GPADC
          This driver can also be built as a module. If chosen, the module name
          will be da9150-gpadc.
 
+         To compile this driver as a module, choose M here: the module will be
+         called berlin2-adc.
+
 config CC10001_ADC
        tristate "Cosmic Circuits 10001 ADC driver"
        depends on HAVE_CLK || REGULATOR
@@ -171,12 +181,18 @@ config EXYNOS_ADC
          of SoCs for drivers such as the touchscreen and hwmon to use to share
          this resource.
 
+         To compile this driver as a module, choose M here: the module will be
+         called exynos_adc.
+
 config LP8788_ADC
        tristate "LP8788 ADC driver"
        depends on MFD_LP8788
        help
          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
        tristate "Maxim max1027 ADC driver"
        depends on SPI
@@ -186,6 +202,9 @@ config MAX1027
          Say yes here to build support for Maxim SPI ADC models
          max1027, max1029 and max1031.
 
+         To compile this driver as a module, choose M here: the module will be
+         called max1027.
+
 config MAX1363
        tristate "Maxim max1363 ADC driver"
        depends on I2C
@@ -202,6 +221,9 @@ config MAX1363
          max11646, max11647) Provides direct access via sysfs and buffered
          data via the iio dev interface.
 
+         To compile this driver as a module, choose M here: the module will be
+         called max1363.
+
 config MCP320X
        tristate "Microchip Technology MCP3x01/02/04/08"
        depends on SPI
@@ -310,15 +332,18 @@ config TI_AM335X_ADC
          Say yes here to build support for Texas Instruments ADC
          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
        tristate "TWL4030 MADC (Monitoring A/D Converter)"
        depends on TWL4030_CORE
        help
-       This driver provides support for Triton TWL4030-MADC. The
-       driver supports both RT and SW conversion methods.
+         This driver provides support for Triton TWL4030-MADC. The
+         driver supports both RT and SW conversion methods.
 
-       This driver can also be built as a module. If so, the module will be
-       called twl4030-madc.
+         This driver can also be built as a module. If so, the module will be
+         called twl4030-madc.
 
 config TWL6030_GPADC
        tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
@@ -351,6 +376,9 @@ config VIPERBOARD_ADC
          Say yes here to access the ADC part of the Nano River
          Technologies Viperboard.
 
+         To compile this driver as a module, choose M here: the module will be
+         called viperboard_adc.
+
 config XILINX_XADC
        tristate "Xilinx XADC driver"
        depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
index 115f6e99a7fa7c603ca9655d04759545c48e5932..8254f529b2a9a00738eb017f9e5d0f77c4aacfd8 100644 (file)
@@ -62,6 +62,7 @@ struct cc10001_adc_device {
        struct regulator *reg;
        u16 *buf;
 
+       bool shared;
        struct mutex lock;
        unsigned int start_delay_ns;
        unsigned int eoc_delay_ns;
@@ -153,7 +154,8 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
 
        mutex_lock(&adc_dev->lock);
 
-       cc10001_adc_power_up(adc_dev);
+       if (!adc_dev->shared)
+               cc10001_adc_power_up(adc_dev);
 
        /* Calculate delay step for eoc and sampled data */
        delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
@@ -177,7 +179,8 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
        }
 
 done:
-       cc10001_adc_power_down(adc_dev);
+       if (!adc_dev->shared)
+               cc10001_adc_power_down(adc_dev);
 
        mutex_unlock(&adc_dev->lock);
 
@@ -196,7 +199,8 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
        unsigned int delay_ns;
        u16 val;
 
-       cc10001_adc_power_up(adc_dev);
+       if (!adc_dev->shared)
+               cc10001_adc_power_up(adc_dev);
 
        /* Calculate delay step for eoc and sampled data */
        delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
@@ -205,7 +209,8 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
 
        val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
 
-       cc10001_adc_power_down(adc_dev);
+       if (!adc_dev->shared)
+               cc10001_adc_power_down(adc_dev);
 
        return val;
 }
@@ -322,8 +327,10 @@ static int cc10001_adc_probe(struct platform_device *pdev)
        adc_dev = iio_priv(indio_dev);
 
        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;
+       }
 
        adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
        if (IS_ERR(adc_dev->reg))
@@ -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->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 */
        ret = cc10001_adc_channel_init(indio_dev, channel_map);
        if (ret < 0)
@@ -402,6 +417,7 @@ static int cc10001_adc_remove(struct platform_device *pdev)
        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
        struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
 
+       cc10001_adc_power_down(adc_dev);
        iio_device_unregister(indio_dev);
        iio_triggered_buffer_cleanup(indio_dev);
        clk_disable_unprepare(adc_dev->adc_clk);
index b96c636470ef504e3b7f3d5612602bcc76a3a3a0..3555122008b4408950f10e860eff61647dcc71a7 100644 (file)
@@ -404,7 +404,6 @@ MODULE_DEVICE_TABLE(of, mcp3422_of_match);
 static struct i2c_driver mcp3422_driver = {
        .driver = {
                .name = "mcp3422",
-               .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(mcp3422_of_match),
        },
        .probe = mcp3422_probe,
index b3a82b4d1a7587b586077982f27856dcfdb7dee5..2c8374f8625201ea0578a1669490e3be65230abf 100644 (file)
@@ -140,7 +140,6 @@ MODULE_DEVICE_TABLE(of, adc081c_of_match);
 static struct i2c_driver adc081c_driver = {
        .driver = {
                .name = "adc081c",
-               .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(adc081c_of_match),
        },
        .probe = adc081c_probe,
index 9a40097e7cf81439933c892d7bfc205cc43d69d7..d338bb595db3eda0ec2d472b62ef8a195f09e1e8 100644 (file)
@@ -700,7 +700,6 @@ static struct spi_driver ssp_driver = {
        .remove = ssp_remove,
        .driver = {
                .pm = &ssp_pm_ops,
-               .bus = &spi_bus_type,
                .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(ssp_of_match),
                .name = "sensorhub"
index f03b92fd38031e67cb4e999991148a946f9a859a..c067e682149600f5d65eab9d442744f2fd6e9f62 100644 (file)
@@ -630,7 +630,6 @@ MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);
 static struct i2c_driver ad5064_i2c_driver = {
        .driver = {
                   .name = "ad5064",
-                  .owner = THIS_MODULE,
        },
        .probe = ad5064_i2c_probe,
        .remove = ad5064_i2c_remove,
index 9de4c4d382803056cd8645c52a60dac7ccf0f885..130de9b3e0bf4d0d969a87d7c1d62c3114e77848 100644 (file)
@@ -593,7 +593,6 @@ MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
 static struct i2c_driver ad5380_i2c_driver = {
        .driver = {
                   .name = "ad5380",
-                  .owner = THIS_MODULE,
        },
        .probe = ad5380_i2c_probe,
        .remove = ad5380_i2c_remove,
index 46bb62a5c1d4d62ad279a791d281253cfc4c356b..07e17d72a3f3d13922684c85dab2b6a13811c702 100644 (file)
@@ -569,7 +569,6 @@ MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids);
 static struct i2c_driver ad5446_i2c_driver = {
        .driver = {
                   .name = "ad5446",
-                  .owner = THIS_MODULE,
        },
        .probe = ad5446_i2c_probe,
        .remove = ad5446_i2c_remove,
index 6e914495b346450c6ebdb2bf75851de278a98863..28b8748ea8242277e0e0a9aff187c23493096e8d 100644 (file)
@@ -392,7 +392,6 @@ static struct i2c_driver max5821_driver = {
        .driver = {
                .name   = "max5821",
                .pm     = MAX5821_PM_OPS,
-               .owner  = THIS_MODULE,
        },
        .probe          = max5821_probe,
        .remove         = max5821_remove,
index 10a0dfc3b01fa8045a9c20bf597e3b1110b57d2e..9890c81c027d30b370483c3bdd778c0fcec4e79f 100644 (file)
@@ -72,7 +72,6 @@ static int adf4350_sync_config(struct adf4350_state *st)
        for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) {
                if ((st->regs_hw[i] != st->regs[i]) ||
                        ((i == ADF4350_REG0) && doublebuf)) {
-
                        switch (i) {
                        case ADF4350_REG1:
                        case ADF4350_REG4:
index f0fd94055d8858b722a5572b564edf0de125a90b..c102a6325bb00d287ac710079b63eeca2e22fd80 100644 (file)
@@ -379,7 +379,6 @@ MODULE_DEVICE_TABLE(i2c, itg3200_id);
 
 static struct i2c_driver itg3200_driver = {
        .driver = {
-               .owner  = THIS_MODULE,
                .name   = "itg3200",
                .pm     = &itg3200_pm_ops,
        },
index 64480b16c6895373c626b47d250c17500cc03311..6848451f817a239bc853f8bd90eda7aa98935282 100644 (file)
@@ -99,7 +99,6 @@ MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
 
 static struct i2c_driver st_gyro_driver = {
        .driver = {
-               .owner = THIS_MODULE,
                .name = "st-gyro-i2c",
                .of_match_table = of_match_ptr(st_gyro_of_match),
        },
index bdd586e6d955235a76f30303c3ac4da78fda4d66..91972ccd8aafb8d151953f344ba54933be79da3a 100644 (file)
@@ -177,7 +177,6 @@ MODULE_DEVICE_TABLE(i2c, si7005_id);
 static struct i2c_driver si7005_driver = {
        .driver = {
                .name   = "si7005",
-               .owner  = THIS_MODULE,
        },
        .probe = si7005_probe,
        .id_table = si7005_id,
index 17d4bb15be4d2998681f203b5944c5c82ce606ea..ca6de8e2d0f92df1f3b5e07b845eba046fd6b2ea 100644 (file)
@@ -673,6 +673,10 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
 
 /* constant IIO attribute */
 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,
        inv_mpu6050_fifo_rate_store);
 static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
@@ -685,6 +689,8 @@ static struct attribute *inv_attributes[] = {
        &iio_dev_attr_in_accel_matrix.dev_attr.attr,
        &iio_dev_attr_sampling_frequency.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,
 };
 
@@ -903,7 +909,6 @@ static struct i2c_driver inv_mpu_driver = {
        .remove         =       inv_mpu_remove,
        .id_table       =       inv_mpu_id,
        .driver = {
-               .owner  =       THIS_MODULE,
                .name   =       "inv-mpu6050",
                .pm     =       INV_MPU6050_PMOPS,
                .acpi_match_table = ACPI_PTR(inv_acpi_match),
index 6eee1b044c60ed5806494d95bfa69a83687103a6..f72be48e650cbfb106d2388af2376b55999a5fb1 100644 (file)
@@ -71,8 +71,9 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
 
        if (avail >= to_wait) {
                /* force a flush for non-blocking reads */
-               if (!to_wait && !avail && to_flush)
-                       iio_buffer_flush_hwfifo(indio_dev, buf, to_flush);
+               if (!to_wait && avail < to_flush)
+                       iio_buffer_flush_hwfifo(indio_dev, buf,
+                                               to_flush - avail);
                return true;
        }
 
@@ -100,8 +101,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_buffer *rb = indio_dev->buffer;
        size_t datum_size;
-       size_t to_wait = 0;
-       size_t to_read;
+       size_t to_wait;
        int ret;
 
        if (!indio_dev->info)
@@ -119,14 +119,14 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
        if (!datum_size)
                return 0;
 
-       to_read = min_t(size_t, n / datum_size, rb->watermark);
-
-       if (!(filp->f_flags & O_NONBLOCK))
-               to_wait = to_read;
+       if (filp->f_flags & O_NONBLOCK)
+               to_wait = 0;
+       else
+               to_wait = min_t(size_t, n / datum_size, rb->watermark);
 
        do {
                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)
                        return ret;
 
index 3524b0de872110d31442060a109c5c4243a3f0cf..d8051cdcbdc2212fe6e069c3bf60db0f2431aa58 100644 (file)
@@ -81,6 +81,14 @@ static const char * const iio_modifier_names[] = {
        [IIO_MOD_X] = "x",
        [IIO_MOD_Y] = "y",
        [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_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
        [IIO_MOD_LIGHT_BOTH] = "both",
index 15a5341b5e7b303b80257db09853a2a62560b8d1..4b2858ba1fd6c534e8a23bdcc4a6a5b9f813b56d 100644 (file)
@@ -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
  * @indio_dev:         IIO device structure
- * @pollfunc_bh:       Function which will be used as pollfunc bottom half
- * @pollfunc_th:       Function which will be used as pollfunc top half
+ * @h:                 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.
  *                     If NULL the default setup functions for triggered
  *                     buffers will be used.
@@ -42,8 +42,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
  * iio_triggered_buffer_cleanup().
  */
 int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
-       irqreturn_t (*pollfunc_bh)(int irq, void *p),
-       irqreturn_t (*pollfunc_th)(int irq, void *p),
+       irqreturn_t (*h)(int irq, void *p),
+       irqreturn_t (*thread)(int irq, void *p),
        const struct iio_buffer_setup_ops *setup_ops)
 {
        struct iio_buffer *buffer;
@@ -57,8 +57,8 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
 
        iio_device_attach_buffer(indio_dev, buffer);
 
-       indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh,
-                                                pollfunc_th,
+       indio_dev->pollfunc = iio_alloc_pollfunc(h,
+                                                thread,
                                                 IRQF_ONESHOT,
                                                 indio_dev,
                                                 "%s_consumer%d",
index e6198b7c9cbfcf55a04b12049ccedbf3800e9b83..730fa80c83ea3e841bac4495e592979bc2ef8186 100644 (file)
@@ -86,7 +86,7 @@ config CM3323
        depends on I2C
        tristate "Capella CM3323 color light sensor"
        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.
 
         To compile this driver as a module, choose M here: the module will
@@ -168,6 +168,17 @@ config JSA1212
         To compile this driver as a module, choose M here:
         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
        tristate "LM3533 ambient light sensor"
        depends on MFD_LM3533
index e2d50fd59c66fbadbc3c8b10098d9d11c7549399..adf97237db729509fc87ccdf6a51d19a55f81411 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_ISL29125)                += isl29125.o
 obj-$(CONFIG_JSA1212)          += jsa1212.o
 obj-$(CONFIG_SENSORS_LM3533)   += lm3533-als.o
 obj-$(CONFIG_LTR501)           += ltr501.o
+obj-$(CONFIG_RPR0521)          += rpr0521.o
 obj-$(CONFIG_SENSORS_TSL2563)  += tsl2563.o
 obj-$(CONFIG_STK3310)          += stk3310.o
 obj-$(CONFIG_TCS3414)          += tcs3414.o
index 9ddde0ca9c3415106ef8821027ad55b8f0b641fa..e1b9fa5a7e9153e0923f8c5f9d7df60928cfe875 100644 (file)
@@ -515,7 +515,6 @@ MODULE_DEVICE_TABLE(i2c, apds9300_id);
 static struct i2c_driver apds9300_driver = {
        .driver = {
                .name   = APDS9300_DRV_NAME,
-               .owner  = THIS_MODULE,
                .pm     = APDS9300_PM_OPS,
        },
        .probe          = apds9300_probe,
index 564c2b3c1a83dde9ae3358e6a8a2a04a997f06a9..8b4164343f2001c2128f7d5e7c5ce33090adeb50 100644 (file)
@@ -319,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, bh1750_id);
 static struct i2c_driver bh1750_driver = {
        .driver = {
                .name = "bh1750",
-               .owner = THIS_MODULE,
                .pm = BH1750_PM_OPS,
        },
        .probe = bh1750_probe,
index 5d12ae54d0886e1179ab18e8d72480bb9d12d40a..1c0de2f8885db046c319382185a629668d8e99e2 100644 (file)
@@ -358,7 +358,6 @@ static struct i2c_driver cm32181_driver = {
        .driver = {
                .name   = "cm32181",
                .of_match_table = of_match_ptr(cm32181_of_match),
-               .owner  = THIS_MODULE,
        },
        .id_table       = cm32181_id,
        .probe          = cm32181_probe,
index 39c8d99cc48ee988a59f17f605372d07258d0e05..1b508c65877c0603f784c15f807029a61d6e128a 100644 (file)
@@ -421,7 +421,6 @@ static const struct of_device_id cm3232_of_match[] = {
 static struct i2c_driver cm3232_driver = {
        .driver = {
                .name   = "cm3232",
-               .owner  = THIS_MODULE,
                .of_match_table = of_match_ptr(cm3232_of_match),
 #ifdef CONFIG_PM_SLEEP
                .pm     = &cm3232_pm_ops,
index 869033e48a1facdd4021e3c9d2889d9fc7ab0773..54c9e2df43f2003a934abf8edabcff17e55ec421 100644 (file)
@@ -29,7 +29,7 @@
 
 #define CM3323_CONF_SD_BIT     BIT(0) /* sensor disable */
 #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_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)
                                return ret;
 
                        data->reg_conf = reg_conf;
+
                        return 0;
                }
        }
+
        return -EINVAL;
 }
 
@@ -148,6 +150,7 @@ static int cm3323_get_it_bits(struct cm3323_data *data)
 
        if (bits >= ARRAY_SIZE(cm3323_int_time))
                return -EINVAL;
+
        return bits;
 }
 
@@ -155,7 +158,7 @@ static int cm3323_read_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan, int *val,
                           int *val2, long mask)
 {
-       int i, ret;
+       int ret;
        struct cm3323_data *data = iio_priv(indio_dev);
 
        switch (mask) {
@@ -172,14 +175,14 @@ static int cm3323_read_raw(struct iio_dev *indio_dev,
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_INT_TIME:
                mutex_lock(&data->mutex);
-               i = cm3323_get_it_bits(data);
-               if (i < 0) {
+               ret = cm3323_get_it_bits(data);
+               if (ret < 0) {
                        mutex_unlock(&data->mutex);
-                       return -EINVAL;
+                       return ret;
                }
 
-               *val = cm3323_int_time[i].val;
-               *val2 = cm3323_int_time[i].val2;
+               *val = cm3323_int_time[ret].val;
+               *val2 = cm3323_int_time[ret].val2;
                mutex_unlock(&data->mutex);
 
                return IIO_VAL_INT_PLUS_MICRO;
@@ -243,11 +246,13 @@ static int cm3323_probe(struct i2c_client *client,
                dev_err(&client->dev, "cm3323 chip init failed\n");
                return ret;
        }
+
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "failed to register iio dev\n");
                goto err_init;
        }
+
        return 0;
 err_init:
        cm3323_disable(indio_dev);
index 39fc67e82138470a1f8523d7de2902f072603a6f..2a39e141e90c0895e4104a8d9bccd8facc000610 100644 (file)
@@ -736,7 +736,6 @@ static struct i2c_driver cm36651_driver = {
        .driver = {
                .name   = "cm36651",
                .of_match_table = cm36651_of_match,
-               .owner  = THIS_MODULE,
        },
        .probe          = cm36651_probe,
        .remove         = cm36651_remove,
index 32b6449833faf5f6102e8b55edcb6810f2c25678..0334a814b5eb5956034a61108c2693375ac06e49 100644 (file)
@@ -1640,7 +1640,6 @@ static struct i2c_driver gp2ap020a00f_driver = {
        .driver = {
                .name   = GP2A_I2C_NAME,
                .of_match_table = of_match_ptr(gp2ap020a00f_of_match),
-               .owner  = THIS_MODULE,
        },
        .probe          = gp2ap020a00f_probe,
        .remove         = gp2ap020a00f_remove,
index 0d248476f4c9b64b7479e4135fbddb95e178bae2..45ca056f019ed2832bd68f14833ae2b4a4839fd7 100644 (file)
@@ -284,8 +284,7 @@ static int hid_prox_probe(struct platform_device *pdev)
                goto error_free_dev_mem;
        }
 
-       indio_dev->num_channels =
-                               ARRAY_SIZE(prox_channels);
+       indio_dev->num_channels = ARRAY_SIZE(prox_channels);
        indio_dev->dev.parent = &pdev->dev;
        indio_dev->info = &prox_info;
        indio_dev->name = name;
index c82f4a6f84645c2dd327f17ee74fdb6bf867544f..e2945a20e5f621a7740300b0aa1e48ca732ba16f 100644 (file)
@@ -197,9 +197,21 @@ done:
        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 = {
        .read_raw = isl29125_read_raw,
        .write_raw = isl29125_write_raw,
+       .attrs = &isl29125_attribute_group,
        .driver_module = THIS_MODULE,
 };
 
@@ -334,7 +346,6 @@ static struct i2c_driver isl29125_driver = {
        .driver = {
                .name   = ISL29125_DRV_NAME,
                .pm     = &isl29125_pm_ops,
-               .owner  = THIS_MODULE,
        },
        .probe          = isl29125_probe,
        .remove         = isl29125_remove,
index 3a3af89beaf962671c9a5e65d0b3dd7fc25ce2c4..c4e8c6b6c3c31ccbf0124b551694b48def01c269 100644 (file)
@@ -457,7 +457,6 @@ static struct i2c_driver jsa1212_driver = {
        .driver = {
                .name   = JSA1212_DRIVER_NAME,
                .pm     = JSA1212_PM_OPS,
-               .owner  = THIS_MODULE,
                .acpi_match_table = ACPI_PTR(jsa1212_acpi_match),
        },
        .probe          = jsa1212_probe,
index 1ef7d3773ab90b4ee54dd69656f95899daed0f56..f4c9a5cdfed6573e95204c464dbab7378737a13c 100644 (file)
@@ -1551,7 +1551,6 @@ static struct i2c_driver ltr501_driver = {
                .name   = LTR501_DRV_NAME,
                .pm     = &ltr501_pm_ops,
                .acpi_match_table = ACPI_PTR(ltr_acpi_match),
-               .owner  = THIS_MODULE,
        },
        .probe  = ltr501_probe,
        .remove = ltr501_remove,
diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c
new file mode 100644 (file)
index 0000000..4b75bb0
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ * RPR-0521 ROHM Ambient Light and Proximity Sensor
+ *
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
+ *
+ * TODO: illuminance channel, PM support, buffer
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/acpi.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/pm_runtime.h>
+
+#define RPR0521_REG_SYSTEM_CTRL                0x40
+#define RPR0521_REG_MODE_CTRL          0x41
+#define RPR0521_REG_ALS_CTRL           0x42
+#define RPR0521_REG_PXS_CTRL           0x43
+#define RPR0521_REG_PXS_DATA           0x44 /* 16-bit, little endian */
+#define RPR0521_REG_ALS_DATA0          0x46 /* 16-bit, little endian */
+#define RPR0521_REG_ALS_DATA1          0x48 /* 16-bit, little endian */
+#define RPR0521_REG_ID                 0x92
+
+#define RPR0521_MODE_ALS_MASK          BIT(7)
+#define RPR0521_MODE_PXS_MASK          BIT(6)
+#define RPR0521_MODE_MEAS_TIME_MASK    GENMASK(3, 0)
+#define RPR0521_ALS_DATA0_GAIN_MASK    GENMASK(5, 4)
+#define RPR0521_ALS_DATA0_GAIN_SHIFT   4
+#define RPR0521_ALS_DATA1_GAIN_MASK    GENMASK(3, 2)
+#define RPR0521_ALS_DATA1_GAIN_SHIFT   2
+#define RPR0521_PXS_GAIN_MASK          GENMASK(5, 4)
+#define RPR0521_PXS_GAIN_SHIFT         4
+
+#define RPR0521_MODE_ALS_ENABLE                BIT(7)
+#define RPR0521_MODE_ALS_DISABLE       0x00
+#define RPR0521_MODE_PXS_ENABLE                BIT(6)
+#define RPR0521_MODE_PXS_DISABLE       0x00
+
+#define RPR0521_MANUFACT_ID            0xE0
+#define RPR0521_DEFAULT_MEAS_TIME      0x06 /* ALS - 100ms, PXS - 100ms */
+
+#define RPR0521_DRV_NAME               "RPR0521"
+#define RPR0521_REGMAP_NAME            "rpr0521_regmap"
+
+#define RPR0521_SLEEP_DELAY_MS 2000
+
+#define RPR0521_ALS_SCALE_AVAIL "0.007812 0.015625 0.5 1"
+#define RPR0521_PXS_SCALE_AVAIL "0.125 0.5 1"
+
+struct rpr0521_gain {
+       int scale;
+       int uscale;
+};
+
+static const struct rpr0521_gain rpr0521_als_gain[4] = {
+       {1, 0},         /* x1 */
+       {0, 500000},    /* x2 */
+       {0, 15625},     /* x64 */
+       {0, 7812},      /* x128 */
+};
+
+static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
+       {1, 0},         /* x1 */
+       {0, 500000},    /* x2 */
+       {0, 125000},    /* x4 */
+};
+
+enum rpr0521_channel {
+       RPR0521_CHAN_ALS_DATA0,
+       RPR0521_CHAN_ALS_DATA1,
+       RPR0521_CHAN_PXS,
+};
+
+struct rpr0521_reg_desc {
+       u8 address;
+       u8 device_mask;
+};
+
+static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
+       [RPR0521_CHAN_ALS_DATA0] = {
+               .address        = RPR0521_REG_ALS_DATA0,
+               .device_mask    = RPR0521_MODE_ALS_MASK,
+       },
+       [RPR0521_CHAN_ALS_DATA1] = {
+               .address        = RPR0521_REG_ALS_DATA1,
+               .device_mask    = RPR0521_MODE_ALS_MASK,
+       },
+       [RPR0521_CHAN_PXS]      = {
+               .address        = RPR0521_REG_PXS_DATA,
+               .device_mask    = RPR0521_MODE_PXS_MASK,
+       },
+};
+
+static const struct rpr0521_gain_info {
+       u8 reg;
+       u8 mask;
+       u8 shift;
+       const struct rpr0521_gain *gain;
+       int size;
+} rpr0521_gain[] = {
+       [RPR0521_CHAN_ALS_DATA0] = {
+               .reg    = RPR0521_REG_ALS_CTRL,
+               .mask   = RPR0521_ALS_DATA0_GAIN_MASK,
+               .shift  = RPR0521_ALS_DATA0_GAIN_SHIFT,
+               .gain   = rpr0521_als_gain,
+               .size   = ARRAY_SIZE(rpr0521_als_gain),
+       },
+       [RPR0521_CHAN_ALS_DATA1] = {
+               .reg    = RPR0521_REG_ALS_CTRL,
+               .mask   = RPR0521_ALS_DATA1_GAIN_MASK,
+               .shift  = RPR0521_ALS_DATA1_GAIN_SHIFT,
+               .gain   = rpr0521_als_gain,
+               .size   = ARRAY_SIZE(rpr0521_als_gain),
+       },
+       [RPR0521_CHAN_PXS] = {
+               .reg    = RPR0521_REG_PXS_CTRL,
+               .mask   = RPR0521_PXS_GAIN_MASK,
+               .shift  = RPR0521_PXS_GAIN_SHIFT,
+               .gain   = rpr0521_pxs_gain,
+               .size   = ARRAY_SIZE(rpr0521_pxs_gain),
+       },
+};
+
+struct rpr0521_data {
+       struct i2c_client *client;
+
+       /* protect device params updates (e.g state, gain) */
+       struct mutex lock;
+
+       /* device active status */
+       bool als_dev_en;
+       bool pxs_dev_en;
+
+       /* optimize runtime pm ops - enable device only if needed */
+       bool als_ps_need_en;
+       bool pxs_ps_need_en;
+
+       struct regmap *regmap;
+};
+
+static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
+static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
+
+static struct attribute *rpr0521_attributes[] = {
+       &iio_const_attr_in_intensity_scale_available.dev_attr.attr,
+       &iio_const_attr_in_proximity_scale_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group rpr0521_attribute_group = {
+       .attrs = rpr0521_attributes,
+};
+
+static const struct iio_chan_spec rpr0521_channels[] = {
+       {
+               .type = IIO_INTENSITY,
+               .modified = 1,
+               .address = RPR0521_CHAN_ALS_DATA0,
+               .channel2 = IIO_MOD_LIGHT_BOTH,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE),
+       },
+       {
+               .type = IIO_INTENSITY,
+               .modified = 1,
+               .address = RPR0521_CHAN_ALS_DATA1,
+               .channel2 = IIO_MOD_LIGHT_IR,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE),
+       },
+       {
+               .type = IIO_PROXIMITY,
+               .address = RPR0521_CHAN_PXS,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE),
+       }
+};
+
+static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
+{
+       int ret;
+
+       ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+                                RPR0521_MODE_ALS_MASK,
+                                status);
+       if (ret < 0)
+               return ret;
+
+       data->als_dev_en = true;
+
+       return 0;
+}
+
+static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
+{
+       int ret;
+
+       ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+                                RPR0521_MODE_PXS_MASK,
+                                status);
+       if (ret < 0)
+               return ret;
+
+       data->pxs_dev_en = true;
+
+       return 0;
+}
+
+/**
+ * rpr0521_set_power_state - handles runtime PM state and sensors enabled status
+ *
+ * @data: rpr0521 device private data
+ * @on: state to be set for devices in @device_mask
+ * @device_mask: bitmask specifying for which device we need to update @on state
+ *
+ * We rely on rpr0521_runtime_resume to enable our @device_mask devices, but
+ * if (for example) PXS was enabled (pxs_dev_en = true) by a previous call to
+ * rpr0521_runtime_resume and we want to enable ALS we MUST set ALS enable
+ * bit of RPR0521_REG_MODE_CTRL here because rpr0521_runtime_resume will not
+ * be called twice.
+ */
+static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
+                                  u8 device_mask)
+{
+#ifdef CONFIG_PM
+       int ret;
+       u8 update_mask = 0;
+
+       if (device_mask & RPR0521_MODE_ALS_MASK) {
+               if (on && !data->als_ps_need_en && data->pxs_dev_en)
+                       update_mask |= RPR0521_MODE_ALS_MASK;
+               else
+                       data->als_ps_need_en = on;
+       }
+
+       if (device_mask & RPR0521_MODE_PXS_MASK) {
+               if (on && !data->pxs_ps_need_en && data->als_dev_en)
+                       update_mask |= RPR0521_MODE_PXS_MASK;
+               else
+                       data->pxs_ps_need_en = on;
+       }
+
+       if (update_mask) {
+               ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+                                        update_mask, update_mask);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (on) {
+               ret = pm_runtime_get_sync(&data->client->dev);
+       } else {
+               pm_runtime_mark_last_busy(&data->client->dev);
+               ret = pm_runtime_put_autosuspend(&data->client->dev);
+       }
+       if (ret < 0) {
+               dev_err(&data->client->dev,
+                       "Failed: rpr0521_set_power_state for %d, ret %d\n",
+                       on, ret);
+               if (on)
+                       pm_runtime_put_noidle(&data->client->dev);
+
+               return ret;
+       }
+#endif
+       return 0;
+}
+
+static int rpr0521_get_gain(struct rpr0521_data *data, int chan,
+                           int *val, int *val2)
+{
+       int ret, reg, idx;
+
+       ret = regmap_read(data->regmap, rpr0521_gain[chan].reg, &reg);
+       if (ret < 0)
+               return ret;
+
+       idx = (rpr0521_gain[chan].mask & reg) >> rpr0521_gain[chan].shift;
+       *val = rpr0521_gain[chan].gain[idx].scale;
+       *val2 = rpr0521_gain[chan].gain[idx].uscale;
+
+       return 0;
+}
+
+static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
+                           int val, int val2)
+{
+       int i, idx = -EINVAL;
+
+       /* get gain index */
+       for (i = 0; i < rpr0521_gain[chan].size; i++)
+               if (val == rpr0521_gain[chan].gain[i].scale &&
+                   val2 == rpr0521_gain[chan].gain[i].uscale) {
+                       idx = i;
+                       break;
+               }
+
+       if (idx < 0)
+               return idx;
+
+       return regmap_update_bits(data->regmap, rpr0521_gain[chan].reg,
+                                 rpr0521_gain[chan].mask,
+                                 idx << rpr0521_gain[chan].shift);
+}
+
+static int rpr0521_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan, int *val,
+                           int *val2, long mask)
+{
+       struct rpr0521_data *data = iio_priv(indio_dev);
+       int ret;
+       u8 device_mask;
+       __le16 raw_data;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY)
+                       return -EINVAL;
+
+               device_mask = rpr0521_data_reg[chan->address].device_mask;
+
+               mutex_lock(&data->lock);
+               ret = rpr0521_set_power_state(data, true, device_mask);
+               if (ret < 0) {
+                       mutex_unlock(&data->lock);
+                       return ret;
+               }
+
+               ret = regmap_bulk_read(data->regmap,
+                                      rpr0521_data_reg[chan->address].address,
+                                      &raw_data, 2);
+               if (ret < 0) {
+                       rpr0521_set_power_state(data, false, device_mask);
+                       mutex_unlock(&data->lock);
+                       return ret;
+               }
+
+               ret = rpr0521_set_power_state(data, false, device_mask);
+               mutex_unlock(&data->lock);
+               if (ret < 0)
+                       return ret;
+
+               *val = le16_to_cpu(raw_data);
+
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               mutex_lock(&data->lock);
+               ret = rpr0521_get_gain(data, chan->address, val, val2);
+               mutex_unlock(&data->lock);
+               if (ret < 0)
+                       return ret;
+
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int rpr0521_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan, int val,
+                            int val2, long mask)
+{
+       struct rpr0521_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               mutex_lock(&data->lock);
+               ret = rpr0521_set_gain(data, chan->address, val, val2);
+               mutex_unlock(&data->lock);
+
+               return ret;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info rpr0521_info = {
+       .driver_module  = THIS_MODULE,
+       .read_raw       = rpr0521_read_raw,
+       .write_raw      = rpr0521_write_raw,
+       .attrs          = &rpr0521_attribute_group,
+};
+
+static int rpr0521_init(struct rpr0521_data *data)
+{
+       int ret;
+       int id;
+
+       ret = regmap_read(data->regmap, RPR0521_REG_ID, &id);
+       if (ret < 0) {
+               dev_err(&data->client->dev, "Failed to read REG_ID register\n");
+               return ret;
+       }
+
+       if (id != RPR0521_MANUFACT_ID) {
+               dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
+                       id, RPR0521_MANUFACT_ID);
+               return -ENODEV;
+       }
+
+       /* set default measurement time - 100 ms for both ALS and PS */
+       ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+                                RPR0521_MODE_MEAS_TIME_MASK,
+                                RPR0521_DEFAULT_MEAS_TIME);
+       if (ret) {
+               pr_err("regmap_update_bits returned %d\n", ret);
+               return ret;
+       }
+
+       ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
+       if (ret < 0)
+               return ret;
+       ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int rpr0521_poweroff(struct rpr0521_data *data)
+{
+       int ret;
+
+       ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+                                RPR0521_MODE_ALS_MASK |
+                                RPR0521_MODE_PXS_MASK,
+                                RPR0521_MODE_ALS_DISABLE |
+                                RPR0521_MODE_PXS_DISABLE);
+       if (ret < 0)
+               return ret;
+
+       data->als_dev_en = false;
+       data->pxs_dev_en = false;
+
+       return 0;
+}
+
+static bool rpr0521_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case RPR0521_REG_MODE_CTRL:
+       case RPR0521_REG_ALS_CTRL:
+       case RPR0521_REG_PXS_CTRL:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static const struct regmap_config rpr0521_regmap_config = {
+       .name           = RPR0521_REGMAP_NAME,
+
+       .reg_bits       = 8,
+       .val_bits       = 8,
+
+       .max_register   = RPR0521_REG_ID,
+       .cache_type     = REGCACHE_RBTREE,
+       .volatile_reg   = rpr0521_is_volatile_reg,
+};
+
+static int rpr0521_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct rpr0521_data *data;
+       struct iio_dev *indio_dev;
+       struct regmap *regmap;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       regmap = devm_regmap_init_i2c(client, &rpr0521_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(&client->dev, "regmap_init failed!\n");
+               return PTR_ERR(regmap);
+       }
+
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
+       data->client = client;
+       data->regmap = regmap;
+
+       mutex_init(&data->lock);
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->info = &rpr0521_info;
+       indio_dev->name = RPR0521_DRV_NAME;
+       indio_dev->channels = rpr0521_channels;
+       indio_dev->num_channels = ARRAY_SIZE(rpr0521_channels);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = rpr0521_init(data);
+       if (ret < 0) {
+               dev_err(&client->dev, "rpr0521 chip init failed\n");
+               return ret;
+       }
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               return ret;
+
+       ret = pm_runtime_set_active(&client->dev);
+       if (ret < 0)
+               goto err_iio_unregister;
+
+       pm_runtime_enable(&client->dev);
+       pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
+       pm_runtime_use_autosuspend(&client->dev);
+
+       return 0;
+
+err_iio_unregister:
+       iio_device_unregister(indio_dev);
+       return ret;
+}
+
+static int rpr0521_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+       pm_runtime_disable(&client->dev);
+       pm_runtime_set_suspended(&client->dev);
+       pm_runtime_put_noidle(&client->dev);
+
+       iio_device_unregister(indio_dev);
+       rpr0521_poweroff(iio_priv(indio_dev));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int rpr0521_runtime_suspend(struct device *dev)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       struct rpr0521_data *data = iio_priv(indio_dev);
+       int ret;
+
+       /* disable channels and sets {als,pxs}_dev_en to false */
+       mutex_lock(&data->lock);
+       ret = rpr0521_poweroff(data);
+       mutex_unlock(&data->lock);
+
+       return ret;
+}
+
+static int rpr0521_runtime_resume(struct device *dev)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+       struct rpr0521_data *data = iio_priv(indio_dev);
+       int ret;
+
+       if (data->als_ps_need_en) {
+               ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
+               if (ret < 0)
+                       return ret;
+               data->als_ps_need_en = false;
+       }
+
+       if (data->pxs_ps_need_en) {
+               ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
+               if (ret < 0)
+                       return ret;
+               data->pxs_ps_need_en = false;
+       }
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops rpr0521_pm_ops = {
+       SET_RUNTIME_PM_OPS(rpr0521_runtime_suspend,
+                          rpr0521_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id rpr0521_acpi_match[] = {
+       {"RPR0521", 0},
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, rpr0521_acpi_match);
+
+static const struct i2c_device_id rpr0521_id[] = {
+       {"rpr0521", 0},
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, rpr0521_id);
+
+static struct i2c_driver rpr0521_driver = {
+       .driver = {
+               .name   = RPR0521_DRV_NAME,
+               .pm     = &rpr0521_pm_ops,
+               .acpi_match_table = ACPI_PTR(rpr0521_acpi_match),
+       },
+       .probe          = rpr0521_probe,
+       .remove         = rpr0521_remove,
+       .id_table       = rpr0521_id,
+};
+
+module_i2c_driver(rpr0521_driver);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
+MODULE_DESCRIPTION("RPR0521 ROHM Ambient Light and Proximity Sensor driver");
+MODULE_LICENSE("GPL v2");
index 71c2bde275aac65ef8b7eb2f756fb05acb4e1958..8075388aa6726e136d6d95859640952823e218d1 100644 (file)
@@ -392,7 +392,6 @@ static struct i2c_driver tcs3414_driver = {
        .driver = {
                .name   = TCS3414_DRV_NAME,
                .pm     = &tcs3414_pm_ops,
-               .owner  = THIS_MODULE,
        },
        .probe          = tcs3414_probe,
        .remove         = tcs3414_remove,
index 752569985d1dff295fb00df9723926b404a7dafb..1b530bf04c8984d30feb70938b56772c72b16b98 100644 (file)
@@ -366,7 +366,6 @@ static struct i2c_driver tcs3472_driver = {
        .driver = {
                .name   = TCS3472_DRV_NAME,
                .pm     = &tcs3472_pm_ops,
-               .owner  = THIS_MODULE,
        },
        .probe          = tcs3472_probe,
        .remove         = tcs3472_remove,
index 63c26e2d5d9722242cf82b0bc8c5dc3ec3eacd46..26979183d27cf323dc934d799b415e3a2b666980 100644 (file)
@@ -247,7 +247,6 @@ static struct i2c_driver tsl4531_driver = {
        .driver = {
                .name   = TSL4531_DRV_NAME,
                .pm     = TSL4531_PM_OPS,
-               .owner  = THIS_MODULE,
        },
        .probe  = tsl4531_probe,
        .remove = tsl4531_remove,
index d948c4778ba6cc98776654edb34ec1636f08f480..c9d85bbc9230059d4483567150b7838f01c65c54 100644 (file)
@@ -185,7 +185,6 @@ static int vcnl4000_probe(struct i2c_client *client,
 static struct i2c_driver vcnl4000_driver = {
        .driver = {
                .name   = VCNL4000_DRV_NAME,
-               .owner  = THIS_MODULE,
        },
        .probe  = vcnl4000_probe,
        .id_table = vcnl4000_id,
index d4c1788699911e934fc3c1baffa3de8928ac26a6..cd002710dd0273e0f5a8e4a2e907ac73666cf27d 100644 (file)
@@ -588,17 +588,6 @@ static int bmc150_magn_write_raw(struct iio_dev *indio_dev,
        }
 }
 
-static int bmc150_magn_validate_trigger(struct iio_dev *indio_dev,
-                                       struct iio_trigger *trig)
-{
-       struct bmc150_magn_data *data = iio_priv(indio_dev);
-
-       if (data->dready_trig != trig)
-               return -EINVAL;
-
-       return 0;
-}
-
 static ssize_t bmc150_magn_show_samp_freq_avail(struct device *dev,
                                                struct device_attribute *attr,
                                                char *buf)
@@ -659,7 +648,6 @@ static const struct iio_info bmc150_magn_info = {
        .attrs = &bmc150_magn_attrs_group,
        .read_raw = bmc150_magn_read_raw,
        .write_raw = bmc150_magn_write_raw,
-       .validate_trigger = bmc150_magn_validate_trigger,
        .driver_module = THIS_MODULE,
 };
 
@@ -682,7 +670,7 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
                                           pf->timestamp);
 
 err:
-       iio_trigger_notify_done(data->dready_trig);
+       iio_trigger_notify_done(indio_dev->trig);
 
        return IRQ_HANDLED;
 }
@@ -827,6 +815,27 @@ static const struct iio_trigger_ops bmc150_magn_trigger_ops = {
        .owner = THIS_MODULE,
 };
 
+static int bmc150_magn_buffer_preenable(struct iio_dev *indio_dev)
+{
+       struct bmc150_magn_data *data = iio_priv(indio_dev);
+
+       return bmc150_magn_set_power_state(data, true);
+}
+
+static int bmc150_magn_buffer_postdisable(struct iio_dev *indio_dev)
+{
+       struct bmc150_magn_data *data = iio_priv(indio_dev);
+
+       return bmc150_magn_set_power_state(data, false);
+}
+
+static const struct iio_buffer_setup_ops bmc150_magn_buffer_setup_ops = {
+       .preenable = bmc150_magn_buffer_preenable,
+       .postenable = iio_triggered_buffer_postenable,
+       .predisable = iio_triggered_buffer_predisable,
+       .postdisable = bmc150_magn_buffer_postdisable,
+};
+
 static int bmc150_magn_gpio_probe(struct i2c_client *client)
 {
        struct device *dev;
@@ -932,16 +941,6 @@ static int bmc150_magn_probe(struct i2c_client *client,
                        goto err_poweroff;
                }
 
-               ret = iio_triggered_buffer_setup(indio_dev,
-                                                &iio_pollfunc_store_time,
-                                                bmc150_magn_trigger_handler,
-                                                NULL);
-               if (ret < 0) {
-                       dev_err(&client->dev,
-                               "iio triggered buffer setup failed\n");
-                       goto err_trigger_unregister;
-               }
-
                ret = request_threaded_irq(client->irq,
                                           iio_trigger_generic_data_rdy_poll,
                                           NULL,
@@ -951,14 +950,24 @@ static int bmc150_magn_probe(struct i2c_client *client,
                if (ret < 0) {
                        dev_err(&client->dev, "request irq %d failed\n",
                                client->irq);
-                       goto err_buffer_cleanup;
+                       goto err_trigger_unregister;
                }
        }
 
+       ret = iio_triggered_buffer_setup(indio_dev,
+                                        iio_pollfunc_store_time,
+                                        bmc150_magn_trigger_handler,
+                                        &bmc150_magn_buffer_setup_ops);
+       if (ret < 0) {
+               dev_err(&client->dev,
+                       "iio triggered buffer setup failed\n");
+               goto err_free_irq;
+       }
+
        ret = iio_device_register(indio_dev);
        if (ret < 0) {
                dev_err(&client->dev, "unable to register iio device\n");
-               goto err_free_irq;
+               goto err_buffer_cleanup;
        }
 
        ret = pm_runtime_set_active(&client->dev);
@@ -976,12 +985,11 @@ static int bmc150_magn_probe(struct i2c_client *client,
 
 err_iio_unregister:
        iio_device_unregister(indio_dev);
+err_buffer_cleanup:
+       iio_triggered_buffer_cleanup(indio_dev);
 err_free_irq:
        if (client->irq > 0)
                free_irq(client->irq, data->dready_trig);
-err_buffer_cleanup:
-       if (data->dready_trig)
-               iio_triggered_buffer_cleanup(indio_dev);
 err_trigger_unregister:
        if (data->dready_trig)
                iio_trigger_unregister(data->dready_trig);
@@ -1000,14 +1008,13 @@ static int bmc150_magn_remove(struct i2c_client *client)
        pm_runtime_put_noidle(&client->dev);
 
        iio_device_unregister(indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
 
        if (client->irq > 0)
                free_irq(data->client->irq, data->dready_trig);
 
-       if (data->dready_trig) {
-               iio_triggered_buffer_cleanup(indio_dev);
+       if (data->dready_trig)
                iio_trigger_unregister(data->dready_trig);
-       }
 
        mutex_lock(&data->mutex);
        bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
@@ -1082,12 +1089,14 @@ static const struct dev_pm_ops bmc150_magn_pm_ops = {
 
 static const struct acpi_device_id bmc150_magn_acpi_match[] = {
        {"BMC150B", 0},
+       {"BMC156B", 0},
        {},
 };
 MODULE_DEVICE_TABLE(acpi, bmc150_magn_acpi_match);
 
 static const struct i2c_device_id bmc150_magn_id[] = {
        {"bmc150_magn", 0},
+       {"bmc156_magn", 0},
        {},
 };
 MODULE_DEVICE_TABLE(i2c, bmc150_magn_id);
index 5311d8aea8cc13ee73dd36bdbcdd202f61538120..28aa80731cea6729e6aed7ebb34204043bc8115c 100644 (file)
@@ -85,7 +85,6 @@ MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
 
 static struct i2c_driver st_magn_driver = {
        .driver = {
-               .owner = THIS_MODULE,
                .name = "st-magn-i2c",
                .of_match_table = of_match_ptr(st_magn_of_match),
        },
index fa62950419479233a3aecf0f1b3fe03c42e5fe6f..4745179ff64b4b6afee6f237555dec5294e0fdf1 100644 (file)
@@ -53,10 +53,10 @@ config MPL3115
           will be called mpl3115.
 
 config MS5611
-       tristate "Measurement Specialities MS5611 pressure sensor driver"
+       tristate "Measurement Specialties MS5611 pressure sensor driver"
        help
-         Say Y here to build support for the Measurement Specialities
-         MS5611 pressure and temperature sensor.
+         Say Y here to build support for the Measurement Specialties
+         MS5611, MS5607 pressure and temperature sensors.
 
          To compile this driver as a module, choose M here: the module will
          be called ms5611_core.
index 099c6cdea43f12572e118202d6a6eb10f4788cff..23b93c797dba7009cafacdb07b5c895652d834e0 100644 (file)
 
 #define MS5611_PROM_WORDS_NB           8
 
+enum {
+       MS5611,
+       MS5607,
+};
+
+struct ms5611_chip_info {
+       u16 prom[MS5611_PROM_WORDS_NB];
+
+       int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info,
+                                           s32 *temp, s32 *pressure);
+};
+
 struct ms5611_state {
        void *client;
        struct mutex lock;
@@ -36,9 +48,9 @@ struct ms5611_state {
        int (*read_adc_temp_and_pressure)(struct device *dev,
                                          s32 *temp, s32 *pressure);
 
-       u16 prom[MS5611_PROM_WORDS_NB];
+       struct ms5611_chip_info *chip_info;
 };
 
-int ms5611_probe(struct iio_dev *indio_dev, struct device *dev);
+int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, int type);
 
 #endif /* _MS5611_H */
index e42c8531d9b35d65f360fae6dc020c9b34465364..2f3d9b4aca4ec695b99f75e53e93af6107bf1d01 100644 (file)
@@ -9,6 +9,7 @@
  *
  * Data sheet:
  *  http://www.meas-spec.com/downloads/MS5611-01BA03.pdf
+ *  http://www.meas-spec.com/downloads/MS5607-02BA03.pdf
  *
  */
 
@@ -50,7 +51,8 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
        struct ms5611_state *st = iio_priv(indio_dev);
 
        for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
-               ret = st->read_prom_word(&indio_dev->dev, i, &st->prom[i]);
+               ret = st->read_prom_word(&indio_dev->dev,
+                                        i, &st->chip_info->prom[i]);
                if (ret < 0) {
                        dev_err(&indio_dev->dev,
                                "failed to read prom at %d\n", i);
@@ -58,7 +60,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
                }
        }
 
-       if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) {
+       if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
                dev_err(&indio_dev->dev, "PROM integrity check failed\n");
                return -ENODEV;
        }
@@ -70,22 +72,30 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
                                         s32 *temp, s32 *pressure)
 {
        int ret;
-       s32 t, p;
-       s64 off, sens, dt;
        struct ms5611_state *st = iio_priv(indio_dev);
 
-       ret = st->read_adc_temp_and_pressure(&indio_dev->dev, &t, &p);
+       ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure);
        if (ret < 0) {
                dev_err(&indio_dev->dev,
                        "failed to read temperature and pressure\n");
                return ret;
        }
 
-       dt = t - (st->prom[5] << 8);
-       off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7);
-       sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8);
+       return st->chip_info->temp_and_pressure_compensate(st->chip_info,
+                                                          temp, pressure);
+}
+
+static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
+                                              s32 *temp, s32 *pressure)
+{
+       s32 t = *temp, p = *pressure;
+       s64 off, sens, dt;
 
-       t = 2000 + ((st->prom[6] * dt) >> 23);
+       dt = t - (chip_info->prom[5] << 8);
+       off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
+       sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
+
+       t = 2000 + ((chip_info->prom[6] * dt) >> 23);
        if (t < 2000) {
                s64 off2, sens2, t2;
 
@@ -111,6 +121,42 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
        return 0;
 }
 
+static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
+                                              s32 *temp, s32 *pressure)
+{
+       s32 t = *temp, p = *pressure;
+       s64 off, sens, dt;
+
+       dt = t - (chip_info->prom[5] << 8);
+       off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
+       sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
+
+       t = 2000 + ((chip_info->prom[6] * dt) >> 23);
+       if (t < 2000) {
+               s64 off2, sens2, t2;
+
+               t2 = (dt * dt) >> 31;
+               off2 = (61 * (t - 2000) * (t - 2000)) >> 4;
+               sens2 = off2 << 1;
+
+               if (t < -1500) {
+                       s64 tmp = (t + 1500) * (t + 1500);
+
+                       off2 += 15 * tmp;
+                       sens2 += (8 * tmp);
+               }
+
+               t -= t2;
+               off -= off2;
+               sens -= sens2;
+       }
+
+       *temp = t;
+       *pressure = (((p * sens) >> 21) - off) >> 15;
+
+       return 0;
+}
+
 static int ms5611_reset(struct iio_dev *indio_dev)
 {
        int ret;
@@ -160,16 +206,23 @@ static int ms5611_read_raw(struct iio_dev *indio_dev,
        return -EINVAL;
 }
 
+static struct ms5611_chip_info chip_info_tbl[] = {
+       [MS5611] = {
+               .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
+       },
+       [MS5607] = {
+               .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
+       }
+};
+
 static const struct iio_chan_spec ms5611_channels[] = {
        {
                .type = IIO_PRESSURE,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-                       BIT(IIO_CHAN_INFO_SCALE)
+               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
        },
        {
                .type = IIO_TEMP,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-                       BIT(IIO_CHAN_INFO_SCALE)
+               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
        }
 };
 
@@ -189,12 +242,13 @@ static int ms5611_init(struct iio_dev *indio_dev)
        return ms5611_read_prom(indio_dev);
 }
 
-int ms5611_probe(struct iio_dev *indio_dev, struct device *dev)
+int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, int type)
 {
        int ret;
        struct ms5611_state *st = iio_priv(indio_dev);
 
        mutex_init(&st->lock);
+       st->chip_info = &chip_info_tbl[type];
        indio_dev->dev.parent = dev;
        indio_dev->name = dev->driver->name;
        indio_dev->info = &ms5611_info;
index 748fd9acaad8fc5af78ce8b33bcd0818acdd8990..245797d1ecf0677f4c59c8ecb3766b329298050b 100644 (file)
@@ -104,11 +104,12 @@ static int ms5611_i2c_probe(struct i2c_client *client,
        st->read_adc_temp_and_pressure = ms5611_i2c_read_adc_temp_and_pressure;
        st->client = client;
 
-       return ms5611_probe(indio_dev, &client->dev);
+       return ms5611_probe(indio_dev, &client->dev, id->driver_data);
 }
 
 static const struct i2c_device_id ms5611_id[] = {
-       { "ms5611", 0 },
+       { "ms5611", MS5611 },
+       { "ms5607", MS5607 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ms5611_id);
@@ -116,7 +117,6 @@ MODULE_DEVICE_TABLE(i2c, ms5611_id);
 static struct i2c_driver ms5611_driver = {
        .driver = {
                .name = "ms5611",
-               .owner = THIS_MODULE,
        },
        .id_table = ms5611_id,
        .probe = ms5611_i2c_probe,
index 976726fd4e6ce6b6e6fff65c25a468968c24f3f7..08ee6e88c79ff7068ce3e4751b35db827b1e7578 100644 (file)
@@ -103,11 +103,13 @@ static int ms5611_spi_probe(struct spi_device *spi)
        st->read_adc_temp_and_pressure = ms5611_spi_read_adc_temp_and_pressure;
        st->client = spi;
 
-       return ms5611_probe(indio_dev, &spi->dev);
+       return ms5611_probe(indio_dev, &spi->dev,
+                           spi_get_device_id(spi)->driver_data);
 }
 
 static const struct spi_device_id ms5611_id[] = {
-       { "ms5611", 0 },
+       { "ms5611", MS5611 },
+       { "ms5607", MS5607 },
        { }
 };
 MODULE_DEVICE_TABLE(spi, ms5611_id);
index 137788bba4a322a772f517a2348f165be24a8400..8fcf9766eaecbf0f3ef191e21a58e242e6419624 100644 (file)
@@ -79,7 +79,6 @@ MODULE_DEVICE_TABLE(i2c, st_press_id_table);
 
 static struct i2c_driver st_press_driver = {
        .driver = {
-               .owner = THIS_MODULE,
                .name = "st-press-i2c",
                .of_match_table = of_match_ptr(st_press_of_match),
        },
index cb2e8ad8bfdcd02e75b9ea4f82e31c598e95109e..90f70b4615678803b81003790e9ec82bfc17cb90 100644 (file)
@@ -551,7 +551,6 @@ static const struct dev_pm_ops mlx90614_pm_ops = {
 static struct i2c_driver mlx90614_driver = {
        .driver = {
                .name   = "mlx90614",
-               .owner  = THIS_MODULE,
                .pm     = &mlx90614_pm_ops,
        },
        .probe = mlx90614_probe,
index fcc49f89b9464cfa8d6206602c6b1f2d518c9ecc..395df23d7c8c585f98f57763bbed1486e0fcd9c0 100644 (file)
@@ -36,9 +36,9 @@
 #define TMP006_CONFIG_DRDY_EN BIT(8)
 #define TMP006_CONFIG_DRDY BIT(7)
 
-#define TMP006_CONFIG_MOD_MASK 0x7000
+#define TMP006_CONFIG_MOD_MASK GENMASK(14, 12)
 
-#define TMP006_CONFIG_CR_MASK 0x0e00
+#define TMP006_CONFIG_CR_MASK GENMASK(11, 9)
 #define TMP006_CONFIG_CR_SHIFT 9
 
 #define TMP006_MANUFACTURER_MAGIC 0x5449
@@ -277,7 +277,6 @@ static struct i2c_driver tmp006_driver = {
        .driver = {
                .name   = "tmp006",
                .pm     = &tmp006_pm_ops,
-               .owner  = THIS_MODULE,
        },
        .probe = tmp006_probe,
        .remove = tmp006_remove,
index 75ddd4f801a3daf9346c186e3a7dc9510b36817a..78fe0b55728020ed7d2c2c4ed90e0c152d45ec01 100644 (file)
@@ -124,7 +124,6 @@ static struct i2c_driver adt7316_driver = {
        .driver = {
                .name = "adt7316",
                .pm = ADT7316_PM_OPS,
-               .owner  = THIS_MODULE,
        },
        .probe = adt7316_i2c_probe,
        .id_table = adt7316_i2c_id,
index c54d5b5443a637ac10c40678f7aa54fdf8349700..6d38854c38c89a1032da9aedcc4bf65fec90e216 100644 (file)
@@ -214,6 +214,7 @@ static struct device iio_evgen_dev = {
        .groups = iio_evgen_groups,
        .release = &iio_evgen_release,
 };
+
 static __init int iio_dummy_evgen_init(void)
 {
        int ret = iio_dummy_evgen_create();
index 1629a8a6bf269ef672b35820f7746c5f767039a7..381f90ff468a983ca6ff7b318dadca61a7a168b6 100644 (file)
@@ -611,7 +611,6 @@ static int iio_dummy_probe(int index)
         */
        iio_dummy_devs[index] = indio_dev;
 
-
        /*
         * Set the device name.
         *
@@ -675,7 +674,6 @@ static void iio_dummy_remove(int index)
         */
        struct iio_dev *indio_dev = iio_dummy_devs[index];
 
-
        /* Unregister the device */
        iio_device_unregister(indio_dev);
 
index e877a99540abced251ef937f70a4abe7cab89f4a..8d00224e6fadb2ba8cd37debf0bf2e17d28ed27d 100644 (file)
@@ -119,6 +119,7 @@ static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
 {
        return 0;
 };
+
 static inline
 void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
 {};
index a651b8922d0a93039eb8ef6c71a35e7dd9ea0f48..00ed7745f3c5b768df4c707f78c0e2ea5c388326 100644 (file)
@@ -32,6 +32,7 @@ static const s16 fakedata[] = {
        [diffvoltage3m4] = -2,
        [accelx] = 344,
 };
+
 /**
  * iio_simple_dummy_trigger_h() - the trigger handler function
  * @irq: the interrupt number
@@ -178,7 +179,6 @@ error_free_buffer:
        iio_kfifo_free(indio_dev->buffer);
 error_ret:
        return ret;
-
 }
 
 /**
index e646c5d2400460c40016e21167452d962d688cad..019ba5245c2363ac2e671dcde9c4378eb19dcc02 100644 (file)
@@ -838,7 +838,6 @@ static struct i2c_driver isl29018_driver = {
                        .name = "isl29018",
                        .acpi_match_table = ACPI_PTR(isl29018_acpi_match),
                        .pm = ISL29018_PM_OPS,
-                       .owner = THIS_MODULE,
                        .of_match_table = isl29018_of_match,
                    },
        .probe   = isl29018_probe,
index e5b2fdc2334b71792355b718b209606be04c73f6..cd6f2727aa58739b329acc46ee49a3321f8daa39 100644 (file)
@@ -547,7 +547,6 @@ static struct i2c_driver isl29028_driver = {
        .class  = I2C_CLASS_HWMON,
        .driver  = {
                .name = "isl29028",
-               .owner = THIS_MODULE,
                .of_match_table = isl29028_of_match,
        },
        .probe   = isl29028_probe,
index c378ebec605ec617c101078b953799f49f9b8ebe..f72f70d5a97b2ae58b7ed769d0bb6984021d5d06 100644 (file)
@@ -7,8 +7,8 @@ struct iio_dev;
 struct iio_buffer_setup_ops;
 
 int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
-       irqreturn_t (*pollfunc_bh)(int irq, void *p),
-       irqreturn_t (*pollfunc_th)(int irq, void *p),
+       irqreturn_t (*h)(int irq, void *p),
+       irqreturn_t (*thread)(int irq, void *p),
        const struct iio_buffer_setup_ops *setup_ops);
 void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev);
 
index 4eebb6616e5ca33aca62a036db63c4a38a5fad61..0e737238ca74a473be64d74352821c489d88354f 100644 (file)
@@ -51,14 +51,33 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
                if (bytes % channels[i].bytes == 0)
                        channels[i].location = bytes;
                else
-                       channels[i].location = bytes - bytes%channels[i].bytes
-                               + channels[i].bytes;
+                       channels[i].location = bytes - bytes % channels[i].bytes
+                                              + channels[i].bytes;
+
                bytes = channels[i].location + channels[i].bytes;
                i++;
        }
+
        return bytes;
 }
 
+void print1byte(uint8_t input, struct iio_channel_info *info)
+{
+       /*
+        * Shift before conversion to avoid sign extension
+        * of left aligned data
+        */
+       input >>= info->shift;
+       input &= info->mask;
+       if (info->is_signed) {
+               int8_t val = (int8_t)(input << (8 - info->bits_used)) >>
+                            (8 - info->bits_used);
+               printf("%05f ", ((float)val + info->offset) * info->scale);
+       } else {
+               printf("%05f ", ((float)input + info->offset) * info->scale);
+       }
+}
+
 void print2byte(uint16_t input, struct iio_channel_info *info)
 {
        /* First swap if incorrect endian */
@@ -136,9 +155,9 @@ void print8byte(uint64_t input, struct iio_channel_info *info)
 /**
  * process_scan() - print out the values in SI units
  * @data:              pointer to the start of the scan
- * @channels:          information about the channels. Note
- *  size_from_channelarray must have been called first to fill the
- *  location offsets.
+ * @channels:          information about the channels.
+ *                     Note: size_from_channelarray must have been called first
+ *                           to fill the location offsets.
  * @num_channels:      number of channels
  **/
 void process_scan(char *data,
@@ -150,6 +169,10 @@ void process_scan(char *data,
        for (k = 0; k < num_channels; k++)
                switch (channels[k].bytes) {
                        /* only a few cases implemented so far */
+               case 1:
+                       print1byte(*(uint8_t *)(data + channels[k].location),
+                                  &channels[k]);
+                       break;
                case 2:
                        print2byte(*(uint16_t *)(data + channels[k].location),
                                   &channels[k]);
@@ -213,6 +236,7 @@ int main(int argc, char **argv)
                        num_loops = strtoul(optarg, &dummy, 10);
                        if (errno)
                                return -errno;
+
                        break;
                case 'e':
                        noevents = 1;
@@ -225,6 +249,7 @@ int main(int argc, char **argv)
                        buf_len = strtoul(optarg, &dummy, 10);
                        if (errno)
                                return -errno;
+
                        break;
                case 'n':
                        device_name = optarg;
@@ -257,6 +282,7 @@ int main(int argc, char **argv)
                printf("Failed to find the %s\n", device_name);
                return dev_num;
        }
+
        printf("iio device number being used is %d\n", dev_num);
 
        ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
@@ -285,9 +311,11 @@ int main(int argc, char **argv)
                        ret = trig_num;
                        goto error_free_triggername;
                }
+
                printf("iio trigger number being used is %d\n", trig_num);
-       } else
+       } else {
                printf("trigger-less mode selected\n");
+       }
 
        /*
         * Parse the files in scan_elements to identify what channels are
@@ -314,8 +342,10 @@ int main(int argc, char **argv)
 
        if (!notrigger) {
                printf("%s %s\n", dev_dir_name, trigger_name);
-               /* Set the device trigger to be the data ready trigger found
-                * above */
+               /*
+                * Set the device trigger to be the data ready trigger found
+                * above
+                */
                ret = write_sysfs_string_and_verify("trigger/current_trigger",
                                                    dev_dir_name,
                                                    trigger_name);
@@ -334,8 +364,9 @@ int main(int argc, char **argv)
        ret = write_sysfs_int("enable", buf_dir_name, 1);
        if (ret < 0)
                goto error_free_buf_dir_name;
+
        scan_size = size_from_channelarray(channels, num_channels);
-       data = malloc(scan_size*buf_len);
+       data = malloc(scan_size * buf_len);
        if (!data) {
                ret = -ENOMEM;
                goto error_free_buf_dir_name;
@@ -349,13 +380,12 @@ int main(int argc, char **argv)
 
        /* Attempt to open non blocking the access dev */
        fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
-       if (fp == -1) { /* If it isn't there make the node */
+       if (fp == -1) { /* TODO: If it isn't there make the node */
                ret = -errno;
                printf("Failed to open %s\n", buffer_access);
                goto error_free_buffer_access;
        }
 
-       /* Wait for events 10 times */
        for (j = 0; j < num_loops; j++) {
                if (!noevents) {
                        struct pollfd pfd = {
@@ -372,25 +402,22 @@ int main(int argc, char **argv)
                        }
 
                        toread = buf_len;
-
                } else {
                        usleep(timedelay);
                        toread = 64;
                }
 
-               read_size = read(fp,
-                                data,
-                                toread*scan_size);
+               read_size = read(fp, data, toread * scan_size);
                if (read_size < 0) {
                        if (errno == EAGAIN) {
                                printf("nothing available\n");
                                continue;
-                       } else
+                       } else {
                                break;
+                       }
                }
-               for (i = 0; i < read_size/scan_size; i++)
-                       process_scan(data + scan_size*i,
-                                    channels,
+               for (i = 0; i < read_size / scan_size; i++)
+                       process_scan(data + scan_size * i, channels,
                                     num_channels);
        }
 
@@ -409,6 +436,7 @@ int main(int argc, char **argv)
 error_close_buffer_access:
        if (close(fp) == -1)
                perror("Failed to close buffer");
+
 error_free_buffer_access:
        free(buffer_access);
 error_free_data:
@@ -424,6 +452,7 @@ error_free_channels:
 error_free_triggername:
        if (datardytrigger)
                free(trigger_name);
+
 error_free_dev_dir_name:
        free(dev_dir_name);
 
index 016760e769c0baf0f8eefee80f8a9f94ad42b586..703f4cb0e8e9b149f6a9d2f6b3d7e3896d33740d 100644 (file)
@@ -13,7 +13,6 @@
  *
  * Usage:
  *     iio_event_monitor <device_name>
- *
  */
 
 #include <unistd.h>
@@ -51,6 +50,9 @@ static const char * const iio_chan_type_name_spec[] = {
        [IIO_HUMIDITYRELATIVE] = "humidityrelative",
        [IIO_ACTIVITY] = "activity",
        [IIO_STEPS] = "steps",
+       [IIO_ENERGY] = "energy",
+       [IIO_DISTANCE] = "distance",
+       [IIO_VELOCITY] = "velocity",
 };
 
 static const char * const iio_ev_type_text[] = {
@@ -99,6 +101,7 @@ static const char * const iio_modifier_names[] = {
        [IIO_MOD_JOGGING] = "jogging",
        [IIO_MOD_WALKING] = "walking",
        [IIO_MOD_STILL] = "still",
+       [IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z] = "sqrt(x^2+y^2+z^2)",
 };
 
 static bool event_is_known(struct iio_event_data *event)
@@ -130,6 +133,9 @@ static bool event_is_known(struct iio_event_data *event)
        case IIO_HUMIDITYRELATIVE:
        case IIO_ACTIVITY:
        case IIO_STEPS:
+       case IIO_ENERGY:
+       case IIO_DISTANCE:
+       case IIO_VELOCITY:
                break;
        default:
                return false;
@@ -167,6 +173,7 @@ static bool event_is_known(struct iio_event_data *event)
        case IIO_MOD_JOGGING:
        case IIO_MOD_WALKING:
        case IIO_MOD_STILL:
+       case IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z:
                break;
        default:
                return false;
@@ -209,7 +216,8 @@ static void print_event(struct iio_event_data *event)
 
        if (!event_is_known(event)) {
                printf("Unknown event: time: %lld, id: %llx\n",
-                               event->timestamp, event->id);
+                      event->timestamp, event->id);
+
                return;
        }
 
@@ -229,6 +237,7 @@ static void print_event(struct iio_event_data *event)
 
        if (dir != IIO_EV_DIR_NONE)
                printf(", direction: %s", iio_ev_dir_text[dir]);
+
        printf("\n");
 }
 
@@ -251,14 +260,16 @@ int main(int argc, char **argv)
        dev_num = find_type_by_name(device_name, "iio:device");
        if (dev_num >= 0) {
                printf("Found IIO device with name %s with device number %d\n",
-                       device_name, dev_num);
+                      device_name, dev_num);
                ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num);
                if (ret < 0) {
                        return -ENOMEM;
                }
        } else {
-               /* If we can't find a IIO device by name assume device_name is a
-                  IIO chrdev */
+               /*
+                * If we can't find an IIO device by name assume device_name is
+                * an IIO chrdev
+                */
                chrdev_name = strdup(device_name);
                if (!chrdev_name)
                        return -ENOMEM;
@@ -299,6 +310,12 @@ int main(int argc, char **argv)
                        }
                }
 
+               if (ret != sizeof(event)) {
+                       printf("Reading event failed!\n");
+                       ret = -EIO;
+                       break;
+               }
+
                print_event(&event);
        }
 
index ec9ab7f9ae4c50e5ac77bedbdff5e6a144eafe78..8fb3214c70f255ec21b76c71ce96b15fa4a3f67e 100644 (file)
@@ -32,8 +32,7 @@ static char * const iio_direction[] = {
  *
  * Returns 0 on success, or a negative error code if string extraction failed.
  **/
-int iioutils_break_up_name(const char *full_name,
-                                 char **generic_name)
+int iioutils_break_up_name(const char *full_name, char **generic_name)
 {
        char *current;
        char *w, *r;
@@ -65,6 +64,7 @@ int iioutils_break_up_name(const char *full_name,
                        *w = *r;
                        w++;
                }
+
                r++;
        }
        *w = '\0';
@@ -88,15 +88,10 @@ int iioutils_break_up_name(const char *full_name,
  *
  * Returns a value >= 0 on success, otherwise a negative error code.
  **/
-int iioutils_get_type(unsigned *is_signed,
-                            unsigned *bytes,
-                            unsigned *bits_used,
-                            unsigned *shift,
-                            uint64_t *mask,
-                            unsigned *be,
-                            const char *device_dir,
-                            const char *name,
-                            const char *generic_name)
+int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used,
+                     unsigned *shift, uint64_t *mask, unsigned *be,
+                     const char *device_dir, const char *name,
+                     const char *generic_name)
 {
        FILE *sysfsfp;
        int ret;
@@ -126,6 +121,7 @@ int iioutils_get_type(unsigned *is_signed,
                ret = -errno;
                goto error_free_builtname_generic;
        }
+
        ret = -ENOENT;
        while (ent = readdir(dp), ent != NULL)
                /*
@@ -140,6 +136,7 @@ int iioutils_get_type(unsigned *is_signed,
                                ret = -ENOMEM;
                                goto error_closedir;
                        }
+
                        sysfsfp = fopen(filename, "r");
                        if (sysfsfp == NULL) {
                                ret = -errno;
@@ -162,12 +159,14 @@ int iioutils_get_type(unsigned *is_signed,
                                printf("scan type description didn't match\n");
                                goto error_close_sysfsfp;
                        }
+
                        *be = (endianchar == 'b');
                        *bytes = padint / 8;
                        if (*bits_used == 64)
                                *mask = ~0;
                        else
                                *mask = (1 << *bits_used) - 1;
+
                        *is_signed = (signchar == 's');
                        if (fclose(sysfsfp)) {
                                ret = -errno;
@@ -177,9 +176,9 @@ int iioutils_get_type(unsigned *is_signed,
 
                        sysfsfp = 0;
                        free(filename);
-
                        filename = 0;
                }
+
 error_close_sysfsfp:
        if (sysfsfp)
                if (fclose(sysfsfp))
@@ -188,6 +187,7 @@ error_close_sysfsfp:
 error_free_filename:
        if (filename)
                free(filename);
+
 error_closedir:
        if (closedir(dp) == -1)
                perror("iioutils_get_type(): Failed to close directory");
@@ -212,11 +212,9 @@ error_free_scan_el_dir:
  *
  * Returns a value >= 0 on success, otherwise a negative error code.
  **/
-int iioutils_get_param_float(float *output,
-                                   const char *param_name,
-                                   const char *device_dir,
-                                   const char *name,
-                                   const char *generic_name)
+int iioutils_get_param_float(float *output, const char *param_name,
+                            const char *device_dir, const char *name,
+                            const char *generic_name)
 {
        FILE *sysfsfp;
        int ret;
@@ -235,11 +233,13 @@ int iioutils_get_param_float(float *output,
                ret = -ENOMEM;
                goto error_free_builtname;
        }
+
        dp = opendir(device_dir);
        if (dp == NULL) {
                ret = -errno;
                goto error_free_builtname_generic;
        }
+
        ret = -ENOENT;
        while (ent = readdir(dp), ent != NULL)
                if ((strcmp(builtname, ent->d_name) == 0) ||
@@ -250,11 +250,13 @@ int iioutils_get_param_float(float *output,
                                ret = -ENOMEM;
                                goto error_closedir;
                        }
+
                        sysfsfp = fopen(filename, "r");
                        if (!sysfsfp) {
                                ret = -errno;
                                goto error_free_filename;
                        }
+
                        errno = 0;
                        if (fscanf(sysfsfp, "%f", output) != 1)
                                ret = errno ? -errno : -ENODATA;
@@ -264,6 +266,7 @@ int iioutils_get_param_float(float *output,
 error_free_filename:
        if (filename)
                free(filename);
+
 error_closedir:
        if (closedir(dp) == -1)
                perror("iioutils_get_param_float(): Failed to close directory");
@@ -282,16 +285,14 @@ error_free_builtname:
  * @cnt: the amount of array elements
  **/
 
-void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
-                                        int cnt)
+void bsort_channel_array_by_index(struct iio_channel_info **ci_array, int cnt)
 {
-
        struct iio_channel_info temp;
        int x, y;
 
        for (x = 0; x < cnt; x++)
                for (y = 0; y < (cnt - 1); y++)
-                       if ((*ci_array)[y].index > (*ci_array)[y+1].index) {
+                       if ((*ci_array)[y].index > (*ci_array)[y + 1].index) {
                                temp = (*ci_array)[y + 1];
                                (*ci_array)[y + 1] = (*ci_array)[y];
                                (*ci_array)[y] = temp;
@@ -307,8 +308,7 @@ void bsort_channel_array_by_index(struct iio_channel_info **ci_array,
  * Returns 0 on success, otherwise a negative error code.
  **/
 int build_channel_array(const char *device_dir,
-                             struct iio_channel_info **ci_array,
-                             int *counter)
+                       struct iio_channel_info **ci_array, int *counter)
 {
        DIR *dp;
        FILE *sysfsfp;
@@ -329,6 +329,7 @@ int build_channel_array(const char *device_dir,
                ret = -errno;
                goto error_free_name;
        }
+
        while (ent = readdir(dp), ent != NULL)
                if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
                           "_en") == 0) {
@@ -338,12 +339,14 @@ int build_channel_array(const char *device_dir,
                                ret = -ENOMEM;
                                goto error_close_dir;
                        }
+
                        sysfsfp = fopen(filename, "r");
                        if (sysfsfp == NULL) {
                                ret = -errno;
                                free(filename);
                                goto error_close_dir;
                        }
+
                        errno = 0;
                        if (fscanf(sysfsfp, "%i", &ret) != 1) {
                                ret = errno ? -errno : -ENODATA;
@@ -353,9 +356,9 @@ int build_channel_array(const char *device_dir,
                                free(filename);
                                goto error_close_dir;
                        }
-
                        if (ret == 1)
                                (*counter)++;
+
                        if (fclose(sysfsfp)) {
                                ret = -errno;
                                free(filename);
@@ -364,11 +367,13 @@ int build_channel_array(const char *device_dir,
 
                        free(filename);
                }
+
        *ci_array = malloc(sizeof(**ci_array) * (*counter));
        if (*ci_array == NULL) {
                ret = -ENOMEM;
                goto error_close_dir;
        }
+
        seekdir(dp, 0);
        while (ent = readdir(dp), ent != NULL) {
                if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
@@ -384,6 +389,7 @@ int build_channel_array(const char *device_dir,
                                count--;
                                goto error_cleanup_array;
                        }
+
                        sysfsfp = fopen(filename, "r");
                        if (sysfsfp == NULL) {
                                ret = -errno;
@@ -391,6 +397,7 @@ int build_channel_array(const char *device_dir,
                                count--;
                                goto error_cleanup_array;
                        }
+
                        errno = 0;
                        if (fscanf(sysfsfp, "%i", &current_enabled) != 1) {
                                ret = errno ? -errno : -ENODATA;
@@ -423,6 +430,7 @@ int build_channel_array(const char *device_dir,
                                count--;
                                goto error_cleanup_array;
                        }
+
                        /* Get the generic and specific name elements */
                        ret = iioutils_break_up_name(current->name,
                                                     &current->generic_name);
@@ -432,6 +440,7 @@ int build_channel_array(const char *device_dir,
                                count--;
                                goto error_cleanup_array;
                        }
+
                        ret = asprintf(&filename,
                                       "%s/%s_index",
                                       scan_el_dir,
@@ -441,6 +450,7 @@ int build_channel_array(const char *device_dir,
                                ret = -ENOMEM;
                                goto error_cleanup_array;
                        }
+
                        sysfsfp = fopen(filename, "r");
                        if (sysfsfp == NULL) {
                                ret = -errno;
@@ -474,6 +484,7 @@ int build_channel_array(const char *device_dir,
                                                       current->generic_name);
                        if (ret < 0)
                                goto error_cleanup_array;
+
                        ret = iioutils_get_param_float(&current->offset,
                                                       "offset",
                                                       device_dir,
@@ -481,6 +492,7 @@ int build_channel_array(const char *device_dir,
                                                       current->generic_name);
                        if (ret < 0)
                                goto error_cleanup_array;
+
                        ret = iioutils_get_type(&current->is_signed,
                                                &current->bytes,
                                                &current->bits_used,
@@ -549,7 +561,7 @@ int find_type_by_name(const char *name, const char *type)
        const struct dirent *ent;
        int number, numstrlen, ret;
 
-       FILE *nameFile;
+       FILE *namefp;
        DIR *dp;
        char thisname[IIO_MAX_NAME_LENGTH];
        char *filename;
@@ -562,9 +574,9 @@ int find_type_by_name(const char *name, const char *type)
 
        while (ent = readdir(dp), ent != NULL) {
                if (strcmp(ent->d_name, ".") != 0 &&
-                       strcmp(ent->d_name, "..") != 0 &&
-                       strlen(ent->d_name) > strlen(type) &&
-                       strncmp(ent->d_name, type, strlen(type)) == 0) {
+                   strcmp(ent->d_name, "..") != 0 &&
+                   strlen(ent->d_name) > strlen(type) &&
+                   strncmp(ent->d_name, type, strlen(type)) == 0) {
                        errno = 0;
                        ret = sscanf(ent->d_name + strlen(type), "%d", &number);
                        if (ret < 0) {
@@ -580,12 +592,9 @@ int find_type_by_name(const char *name, const char *type)
                        numstrlen = calc_digits(number);
                        /* verify the next character is not a colon */
                        if (strncmp(ent->d_name + strlen(type) + numstrlen,
-                                       ":",
-                                       1) != 0) {
-                               filename = malloc(strlen(iio_dir)
-                                               + strlen(type)
-                                               + numstrlen
-                                               + 6);
+                           ":", 1) != 0) {
+                               filename = malloc(strlen(iio_dir) + strlen(type)
+                                                 + numstrlen + 6);
                                if (filename == NULL) {
                                        ret = -ENOMEM;
                                        goto error_close_dir;
@@ -598,19 +607,20 @@ int find_type_by_name(const char *name, const char *type)
                                        goto error_close_dir;
                                }
 
-                               nameFile = fopen(filename, "r");
-                               if (!nameFile) {
+                               namefp = fopen(filename, "r");
+                               if (!namefp) {
                                        free(filename);
                                        continue;
                                }
+
                                free(filename);
                                errno = 0;
-                               if (fscanf(nameFile, "%s", thisname) != 1) {
+                               if (fscanf(namefp, "%s", thisname) != 1) {
                                        ret = errno ? -errno : -ENODATA;
                                        goto error_close_dir;
                                }
 
-                               if (fclose(nameFile)) {
+                               if (fclose(namefp)) {
                                        ret = -errno;
                                        goto error_close_dir;
                                }
@@ -618,6 +628,7 @@ int find_type_by_name(const char *name, const char *type)
                                if (strcmp(name, thisname) == 0) {
                                        if (closedir(dp) == -1)
                                                return -errno;
+
                                        return number;
                                }
                        }
@@ -631,6 +642,7 @@ int find_type_by_name(const char *name, const char *type)
 error_close_dir:
        if (closedir(dp) == -1)
                perror("find_type_by_name(): Failed to close directory");
+
        return ret;
 }
 
@@ -644,6 +656,7 @@ static int _write_sysfs_int(const char *filename, const char *basedir, int val,
 
        if (temp == NULL)
                return -ENOMEM;
+
        ret = sprintf(temp, "%s/%s", basedir, filename);
        if (ret < 0)
                goto error_free;
@@ -654,6 +667,7 @@ static int _write_sysfs_int(const char *filename, const char *basedir, int val,
                printf("failed to open %s\n", temp);
                goto error_free;
        }
+
        ret = fprintf(sysfsfp, "%d", val);
        if (ret < 0) {
                if (fclose(sysfsfp))
@@ -674,6 +688,7 @@ static int _write_sysfs_int(const char *filename, const char *basedir, int val,
                        printf("failed to open %s\n", temp);
                        goto error_free;
                }
+
                if (fscanf(sysfsfp, "%d", &test) != 1) {
                        ret = errno ? -errno : -ENODATA;
                        if (fclose(sysfsfp))
@@ -688,13 +703,12 @@ static int _write_sysfs_int(const char *filename, const char *basedir, int val,
                }
 
                if (test != val) {
-                       printf("Possible failure in int write %d to %s%s\n",
-                               val,
-                               basedir,
-                               filename);
+                       printf("Possible failure in int write %d to %s/%s\n",
+                              val, basedir, filename);
                        ret = -1;
                }
        }
+
 error_free:
        free(temp);
        return ret;
@@ -739,6 +753,7 @@ static int _write_sysfs_string(const char *filename, const char *basedir,
                printf("Memory allocation failed\n");
                return -ENOMEM;
        }
+
        ret = sprintf(temp, "%s/%s", basedir, filename);
        if (ret < 0)
                goto error_free;
@@ -749,6 +764,7 @@ static int _write_sysfs_string(const char *filename, const char *basedir,
                printf("Could not open %s\n", temp);
                goto error_free;
        }
+
        ret = fprintf(sysfsfp, "%s", val);
        if (ret < 0) {
                if (fclose(sysfsfp))
@@ -766,9 +782,10 @@ static int _write_sysfs_string(const char *filename, const char *basedir,
                sysfsfp = fopen(temp, "r");
                if (sysfsfp == NULL) {
                        ret = -errno;
-                       printf("could not open file to verify\n");
+                       printf("Could not open file to verify\n");
                        goto error_free;
                }
+
                if (fscanf(sysfsfp, "%s", temp) != 1) {
                        ret = errno ? -errno : -ENODATA;
                        if (fclose(sysfsfp))
@@ -784,15 +801,12 @@ static int _write_sysfs_string(const char *filename, const char *basedir,
 
                if (strcmp(temp, val) != 0) {
                        printf("Possible failure in string write of %s "
-                               "Should be %s "
-                               "written to %s\%s\n",
-                               temp,
-                               val,
-                               basedir,
-                               filename);
+                              "Should be %s written to %s/%s\n", temp, val,
+                              basedir, filename);
                        ret = -1;
                }
        }
+
 error_free:
        free(temp);
 
@@ -845,6 +859,7 @@ int read_sysfs_posint(const char *filename, const char *basedir)
                printf("Memory allocation failed");
                return -ENOMEM;
        }
+
        ret = sprintf(temp, "%s/%s", basedir, filename);
        if (ret < 0)
                goto error_free;
@@ -854,6 +869,7 @@ int read_sysfs_posint(const char *filename, const char *basedir)
                ret = -errno;
                goto error_free;
        }
+
        errno = 0;
        if (fscanf(sysfsfp, "%d\n", &ret) != 1) {
                ret = errno ? -errno : -ENODATA;
@@ -868,6 +884,7 @@ int read_sysfs_posint(const char *filename, const char *basedir)
 
 error_free:
        free(temp);
+
        return ret;
 }
 
@@ -889,6 +906,7 @@ int read_sysfs_float(const char *filename, const char *basedir, float *val)
                printf("Memory allocation failed");
                return -ENOMEM;
        }
+
        ret = sprintf(temp, "%s/%s", basedir, filename);
        if (ret < 0)
                goto error_free;
@@ -898,6 +916,7 @@ int read_sysfs_float(const char *filename, const char *basedir, float *val)
                ret = -errno;
                goto error_free;
        }
+
        errno = 0;
        if (fscanf(sysfsfp, "%f\n", val) != 1) {
                ret = errno ? -errno : -ENODATA;
@@ -912,6 +931,7 @@ int read_sysfs_float(const char *filename, const char *basedir, float *val)
 
 error_free:
        free(temp);
+
        return ret;
 }
 
@@ -933,6 +953,7 @@ int read_sysfs_string(const char *filename, const char *basedir, char *str)
                printf("Memory allocation failed");
                return -ENOMEM;
        }
+
        ret = sprintf(temp, "%s/%s", basedir, filename);
        if (ret < 0)
                goto error_free;
@@ -942,6 +963,7 @@ int read_sysfs_string(const char *filename, const char *basedir, char *str)
                ret = -errno;
                goto error_free;
        }
+
        errno = 0;
        if (fscanf(sysfsfp, "%s\n", str) != 1) {
                ret = errno ? -errno : -ENODATA;
@@ -956,6 +978,7 @@ int read_sysfs_string(const char *filename, const char *basedir, char *str)
 
 error_free:
        free(temp);
+
        return ret;
 }
 
index 379eed9deaea242025fc53e081bc350b3d931097..086610139ade32b6ec8b0dfe8572e2bcd14d9b34 100644 (file)
@@ -51,17 +51,16 @@ struct iio_channel_info {
 };
 
 int iioutils_break_up_name(const char *full_name, char **generic_name);
-int iioutils_get_type(unsigned *is_signed, unsigned *bytes,
-                                         unsigned *bits_used, unsigned *shift,
-                                         uint64_t *mask, unsigned *be,
-                                         const char *device_dir, const char *name,
-                                         const char *generic_name);
+int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used,
+                     unsigned *shift, uint64_t *mask, unsigned *be,
+                     const char *device_dir, const char *name,
+                     const char *generic_name);
 int iioutils_get_param_float(float *output, const char *param_name,
-                                                        const char *device_dir, const char *name,
-                                                        const char *generic_name);
+                            const char *device_dir, const char *name,
+                            const char *generic_name);
 void bsort_channel_array_by_index(struct iio_channel_info **ci_array, int cnt);
 int build_channel_array(const char *device_dir,
-                                               struct iio_channel_info **ci_array, int *counter);
+                       struct iio_channel_info **ci_array, int *counter);
 int find_type_by_name(const char *name, const char *type);
 int write_sysfs_int(const char *filename, const char *basedir, int val);
 int write_sysfs_int_and_verify(const char *filename, const char *basedir,
index b59ee1733924025c240fd7e6dbcef4f29ce2802a..7f432a55a6c4d133095e251dafa6a8c6c346da38 100644 (file)
@@ -20,7 +20,6 @@
 #include <sys/dir.h>
 #include "iio_utils.h"
 
-
 static enum verbosity {
        VERBLEVEL_DEFAULT,      /* 0 gives lspci behaviour */
        VERBLEVEL_SENSORS,      /* 1 lists sensors */
@@ -29,17 +28,16 @@ static enum verbosity {
 const char *type_device = "iio:device";
 const char *type_trigger = "trigger";
 
-
 static inline int check_prefix(const char *str, const char *prefix)
 {
        return strlen(str) > strlen(prefix) &&
-               strncmp(str, prefix, strlen(prefix)) == 0;
+              strncmp(str, prefix, strlen(prefix)) == 0;
 }
 
 static inline int check_postfix(const char *str, const char *postfix)
 {
        return strlen(str) > strlen(postfix) &&
-               strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
+              strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
 }
 
 static int dump_channels(const char *dev_dir_name)
@@ -50,11 +48,11 @@ static int dump_channels(const char *dev_dir_name)
        dp = opendir(dev_dir_name);
        if (dp == NULL)
                return -errno;
+
        while (ent = readdir(dp), ent != NULL)
                if (check_prefix(ent->d_name, "in_") &&
-                   check_postfix(ent->d_name, "_raw")) {
+                   check_postfix(ent->d_name, "_raw"))
                        printf("   %-10s\n", ent->d_name);
-               }
 
        return (closedir(dp) == -1) ? -errno : 0;
 }
@@ -63,20 +61,22 @@ static int dump_one_device(const char *dev_dir_name)
 {
        char name[IIO_MAX_NAME_LENGTH];
        int dev_idx;
-       int retval;
+       int ret;
 
-       retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device),
-                       "%i", &dev_idx);
-       if (retval != 1)
+       ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
+                    &dev_idx);
+       if (ret != 1)
                return -EINVAL;
-       retval = read_sysfs_string("name", dev_dir_name, name);
-       if (retval)
-               return retval;
+
+       ret = read_sysfs_string("name", dev_dir_name, name);
+       if (ret)
+               return ret;
 
        printf("Device %03d: %s\n", dev_idx, name);
 
        if (verblevel >= VERBLEVEL_SENSORS)
                return dump_channels(dev_dir_name);
+
        return 0;
 }
 
@@ -84,17 +84,19 @@ static int dump_one_trigger(const char *dev_dir_name)
 {
        char name[IIO_MAX_NAME_LENGTH];
        int dev_idx;
-       int retval;
+       int ret;
 
-       retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
-                       "%i", &dev_idx);
-       if (retval != 1)
+       ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
+                    "%i", &dev_idx);
+       if (ret != 1)
                return -EINVAL;
-       retval = read_sysfs_string("name", dev_dir_name, name);
-       if (retval)
-               return retval;
+
+       ret = read_sysfs_string("name", dev_dir_name, name);
+       if (ret)
+               return ret;
 
        printf("Trigger %03d: %s\n", dev_idx, name);
+
        return 0;
 }
 
@@ -151,6 +153,7 @@ static int dump_devices(void)
                        free(dev_dir_name);
                }
        }
+
        return (closedir(dp) == -1) ? -errno : 0;
 
 error_close_dir: