Re: [PATCH] iio: accel: st_accel: add SPI-3wire support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> On Mon,  3 Jul 2017 20:07:11 +0200
> Lorenzo Bianconi <lorenzo.bianconi83@xxxxxxxxx> wrote:
>
>> Add sensor interface mode (SIM) lookup table to support devices
>> (like LSM303AGR accel sensor) that support 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
>>
>> Fixes: ddc05fa28606 (iio: st-accel: add support for lsm303agr accel)
>> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@xxxxxx>
> Just checked and the 3-wire device tree property is documented in spi-bus.txt
>
> So, that's all fine.  However, I'm not keen on introducing a special look up
> table for this when we already have a convenient one covering all the other
> per device registers etc.

Hi Jonathan,

thanks for the review

>
> Another approach suggested inline...
>> ---
>>  drivers/iio/accel/st_accel_core.c               | 37 +++++++++++++++++++++++++
>>  drivers/iio/common/st_sensors/st_sensors_core.c | 36 ++++++++++++++++++++++++
>>  include/linux/iio/common/st_sensors.h           | 11 ++++++++
>>  include/linux/platform_data/st_sensors_pdata.h  |  2 ++
>>  4 files changed, 86 insertions(+)
>>
>> diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
>> index 07d1489cd457..195966e82516 100644
>> --- a/drivers/iio/accel/st_accel_core.c
>> +++ b/drivers/iio/accel/st_accel_core.c
>> @@ -619,6 +619,38 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
>>       },
>>  };
>>
>> +static const struct st_sensor_sim st_accel_sim_table[] = {
>> +     {
>> +             .sensors = {
>> +                     [0] = LSM303AGR_ACCEL_DEV_NAME,
>> +                     [1] = LIS3DH_ACCEL_DEV_NAME,
>> +                     [2] = LIS2DH12_ACCEL_DEV_NAME,
>> +                     [3] = LIS331DLH_ACCEL_DEV_NAME,
>> +                     [4] = LNG2DM_ACCEL_DEV_NAME,
>> +                     [5] = LSM330D_ACCEL_DEV_NAME,
>> +                     [6] = LSM330DL_ACCEL_DEV_NAME,
>> +                     [7] = LSM330DLC_ACCEL_DEV_NAME,
> The index has no meaning as we really have an unordered
> list so perhaps drop it and let it automatically place them.

Ack

>
> Doing it by name is particularly ugly given we already
> have a big look up table for device differences.
>
> One option would be to split the st_sensors_check_device_support
> function into two parts - the first does the match by name
> and the second does the wai check.   That way you could
> then stick your configuration in between the two and
> put this info in with all the other device specific
> characteristics.
>
> To make the transition easy you could add the two split
> functions and call them from the original.  Then you can
> introduce the split as needed into the various st sensor
> drivers.

Fine. I guess it is enough to add a static version of
st_sensors_init_interface_mode
with a reference to the right entry in st_sensor_settings from the top
half of st_sensors_check_device_support.
If the everything is ok with SIM configuration we will go forward to
wai check in st_sensors_check_device_support bottom half.
Maybe it is not necessary to split st_sensors_check_device_support in
two separate functions. Do you agree?

Regards,
Lorenzo

>> +             },
>> +             .addr = 0x23,
>> +             .val = BIT(0),
>> +     },
>> +     {
>> +             .sensors = {
>> +                     [0] = LSM330_ACCEL_DEV_NAME,
>> +             },
>> +             .addr = 0x24,
>> +             .val = BIT(0),
>> +     },
>> +     {
>> +             .sensors = {
>> +                     [0] = LIS3L02DQ_ACCEL_DEV_NAME,
>> +                     [1] = LIS3LV02DL_ACCEL_DEV_NAME,
>> +             },
>> +             .addr = 0x21,
>> +             .val = BIT(1),
>> +     },
>> +};
>> +
>>  static int st_accel_read_raw(struct iio_dev *indio_dev,
>>                       struct iio_chan_spec const *ch, int *val,
>>                                                       int *val2, long mask)
>> @@ -719,6 +751,11 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>>       indio_dev->info = &accel_info;
>>       mutex_init(&adata->tb.buf_lock);
>>
>> +     err = st_sensors_init_interface_mode(indio_dev, st_accel_sim_table,
>> +                                          ARRAY_SIZE(st_accel_sim_table));
>> +     if (err < 0)
>> +             return err;
>> +
>>       err = st_sensors_power_enable(indio_dev);
>>       if (err)
>>               return err;
>> diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
>> index 274868100fd0..50c281b6286d 100644
>> --- a/drivers/iio/common/st_sensors/st_sensors_core.c
>> +++ b/drivers/iio/common/st_sensors/st_sensors_core.c
>> @@ -384,6 +384,42 @@ static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
>>  }
>>  #endif
>>
>> +int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
>> +                                const struct st_sensor_sim *sim_table,
>> +                                int sim_len)
>> +{
>> +     struct st_sensor_data *sdata = iio_priv(indio_dev);
>> +     struct device_node *np = sdata->dev->of_node;
>> +     struct st_sensors_platform_data *pdata;
>> +     int err = 0;
>> +
>> +     pdata = (struct st_sensors_platform_data *)sdata->dev->platform_data;
>> +     if ((np && of_property_read_bool(np, "spi-3wire")) ||
>> +         (pdata && pdata->spi_3wire)) {
>> +             int i, j;
>> +
>> +             for (i = 0; i < sim_len; i++) {
>> +                     for (j = 0; j < ST_SENSORS_MAX_SIM; j++) {
>> +                             if (!strcmp(sim_table[i].sensors[j],
>> +                                         indio_dev->name))
>> +                                     break;
>> +                     }
>> +                     if (j < ST_SENSORS_MAX_SIM)
>> +                             break;
>> +             }
>> +
>> +             if (i == sim_len)
>> +                     return -EINVAL;
>> +
>> +             err = sdata->tf->write_byte(&sdata->tb, sdata->dev,
>> +                                         sim_table[i].addr,
>> +                                         sim_table[i].val);
>> +     }
>> +
>> +     return err;
>> +}
>> +EXPORT_SYMBOL(st_sensors_init_interface_mode);
>> +
>>  int st_sensors_init_sensor(struct iio_dev *indio_dev,
>>                                       struct st_sensors_platform_data *pdata)
>>  {
>> diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
>> index 1f8211b6438b..15ce0cb360d7 100644
>> --- a/include/linux/iio/common/st_sensors.h
>> +++ b/include/linux/iio/common/st_sensors.h
>> @@ -41,6 +41,7 @@
>>
>>  #define ST_SENSORS_MAX_NAME                  17
>>  #define ST_SENSORS_MAX_4WAI                  7
>> +#define ST_SENSORS_MAX_SIM                   9
>>
>>  #define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \
>>                                       ch2, s, endian, rbits, sbits, addr) \
>> @@ -105,6 +106,12 @@ struct st_sensor_fullscale {
>>       struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
>>  };
>>
>> +struct st_sensor_sim {
>> +     char sensors[ST_SENSORS_MAX_SIM][ST_SENSORS_MAX_NAME];
>> +     u8 addr;
>> +     u8 val;
>> +};
>> +
>>  /**
>>   * struct st_sensor_bdu - ST sensor device block data update
>>   * @addr: address of the register.
>> @@ -325,6 +332,10 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
>>  ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
>>                               struct device_attribute *attr, char *buf);
>>
>> +int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
>> +                                const struct st_sensor_sim *sim_table,
>> +                                int sim_len);
>> +
>>  #ifdef CONFIG_OF
>>  void st_sensors_of_name_probe(struct device *dev,
>>                             const struct of_device_id *match,
>> diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h
>> index 79b0e4cdb814..f8274b0c6888 100644
>> --- 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 */
>



-- 
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux