lkml.org 
[lkml]   [2017]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.12 31/65] iio: accel: st_accel: add SPI-3wire support
    Date
    4.12-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>

    commit a7b8829d242b1a58107e9c02b09e93aec446d55c upstream.

    Add SPI Serial Interface Mode (SIM) register information
    in st_sensor_settings look up table to support devices
    (like LSM303AGR accel sensor) that allow just SPI-3wire
    communication mode. SIM mode has to be configured before any
    other operation since it is not enabled by default and the driver
    is not able to read without that configuration

    Whilst a fairly substantial patch, the actual logic is simple and it
    is better to have the generic fix than a band aid.

    Fixes: ddc05fa28606 (iio: st-accel: add support for lsm303agr accel)
    Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@st.com>
    Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/iio/accel/st_accel_core.c | 32 ++++++++++++++++++++++++
    drivers/iio/common/st_sensors/st_sensors_core.c | 29 +++++++++++++++++++++
    include/linux/iio/common/st_sensors.h | 7 +++++
    include/linux/platform_data/st_sensors_pdata.h | 2 +
    4 files changed, 70 insertions(+)

    --- a/drivers/iio/accel/st_accel_core.c
    +++ b/drivers/iio/accel/st_accel_core.c
    @@ -166,6 +166,10 @@ static const struct st_sensor_settings s
    .mask_ihl = 0x02,
    .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
    },
    + .sim = {
    + .addr = 0x23,
    + .value = BIT(0),
    + },
    .multi_read_bit = true,
    .bootime = 2,
    },
    @@ -234,6 +238,10 @@ static const struct st_sensor_settings s
    .mask_od = 0x40,
    .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
    },
    + .sim = {
    + .addr = 0x23,
    + .value = BIT(0),
    + },
    .multi_read_bit = true,
    .bootime = 2,
    },
    @@ -316,6 +324,10 @@ static const struct st_sensor_settings s
    .en_mask = 0x08,
    },
    },
    + .sim = {
    + .addr = 0x24,
    + .value = BIT(0),
    + },
    .multi_read_bit = false,
    .bootime = 2,
    },
    @@ -379,6 +391,10 @@ static const struct st_sensor_settings s
    .mask_int1 = 0x04,
    .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
    },
    + .sim = {
    + .addr = 0x21,
    + .value = BIT(1),
    + },
    .multi_read_bit = true,
    .bootime = 2, /* guess */
    },
    @@ -437,6 +453,10 @@ static const struct st_sensor_settings s
    .mask_od = 0x40,
    .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
    },
    + .sim = {
    + .addr = 0x21,
    + .value = BIT(7),
    + },
    .multi_read_bit = false,
    .bootime = 2, /* guess */
    },
    @@ -499,6 +519,10 @@ static const struct st_sensor_settings s
    .addr_ihl = 0x22,
    .mask_ihl = 0x80,
    },
    + .sim = {
    + .addr = 0x23,
    + .value = BIT(0),
    + },
    .multi_read_bit = true,
    .bootime = 2,
    },
    @@ -547,6 +571,10 @@ static const struct st_sensor_settings s
    .mask_int1 = 0x04,
    .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
    },
    + .sim = {
    + .addr = 0x21,
    + .value = BIT(1),
    + },
    .multi_read_bit = false,
    .bootime = 2,
    },
    @@ -614,6 +642,10 @@ static const struct st_sensor_settings s
    .mask_ihl = 0x02,
    .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
    },
    + .sim = {
    + .addr = 0x23,
    + .value = BIT(0),
    + },
    .multi_read_bit = true,
    .bootime = 2,
    },
    --- a/drivers/iio/common/st_sensors/st_sensors_core.c
    +++ b/drivers/iio/common/st_sensors/st_sensors_core.c
    @@ -550,6 +550,31 @@ out:
    }
    EXPORT_SYMBOL(st_sensors_read_info_raw);

    +static int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
    + const struct st_sensor_settings *sensor_settings)
    +{
    + struct st_sensor_data *sdata = iio_priv(indio_dev);
    + struct device_node *np = sdata->dev->of_node;
    + struct st_sensors_platform_data *pdata;
    +
    + pdata = (struct st_sensors_platform_data *)sdata->dev->platform_data;
    + if (((np && of_property_read_bool(np, "spi-3wire")) ||
    + (pdata && pdata->spi_3wire)) && sensor_settings->sim.addr) {
    + int err;
    +
    + err = sdata->tf->write_byte(&sdata->tb, sdata->dev,
    + sensor_settings->sim.addr,
    + sensor_settings->sim.value);
    + if (err < 0) {
    + dev_err(&indio_dev->dev,
    + "failed to init interface mode\n");
    + return err;
    + }
    + }
    +
    + return 0;
    +}
    +
    int st_sensors_check_device_support(struct iio_dev *indio_dev,
    int num_sensors_list,
    const struct st_sensor_settings *sensor_settings)
    @@ -574,6 +599,10 @@ int st_sensors_check_device_support(stru
    return -ENODEV;
    }

    + err = st_sensors_init_interface_mode(indio_dev, &sensor_settings[i]);
    + if (err < 0)
    + return err;
    +
    if (sensor_settings[i].wai_addr) {
    err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
    sensor_settings[i].wai_addr, &wai);
    --- a/include/linux/iio/common/st_sensors.h
    +++ b/include/linux/iio/common/st_sensors.h
    @@ -105,6 +105,11 @@ struct st_sensor_fullscale {
    struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
    };

    +struct st_sensor_sim {
    + u8 addr;
    + u8 value;
    +};
    +
    /**
    * struct st_sensor_bdu - ST sensor device block data update
    * @addr: address of the register.
    @@ -197,6 +202,7 @@ struct st_sensor_transfer_function {
    * @bdu: Block data update register.
    * @das: Data Alignment Selection register.
    * @drdy_irq: Data ready register of the sensor.
    + * @sim: SPI serial interface mode register of the sensor.
    * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
    * @bootime: samples to discard when sensor passing from power-down to power-up.
    */
    @@ -213,6 +219,7 @@ struct st_sensor_settings {
    struct st_sensor_bdu bdu;
    struct st_sensor_das das;
    struct st_sensor_data_ready_irq drdy_irq;
    + struct st_sensor_sim sim;
    bool multi_read_bit;
    unsigned int bootime;
    };
    --- a/include/linux/platform_data/st_sensors_pdata.h
    +++ b/include/linux/platform_data/st_sensors_pdata.h
    @@ -17,10 +17,12 @@
    * Available only for accelerometer and pressure sensors.
    * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet).
    * @open_drain: set the interrupt line to be open drain if possible.
    + * @spi_3wire: enable spi-3wire mode.
    */
    struct st_sensors_platform_data {
    u8 drdy_int_pin;
    bool open_drain;
    + bool spi_3wire;
    };

    #endif /* ST_SENSORS_PDATA_H */

    \
     
     \ /
      Last update: 2017-08-15 03:21    [W:4.382 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site