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

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

 



On Wed,  5 Jul 2017 20:30:01 +0200
Lorenzo Bianconi <lorenzo.bianconi83@xxxxxxxxx> wrote:

> 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
> 
> Fixes: ddc05fa28606 (iio: st-accel: add support for lsm303agr accel)
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@xxxxxx>
Applied to the fixes-togreg branch and marked for stable.

I added a brief note for stable maintainers saying that whilst
substantial logic was simple and better to have a proper fix than
a work around.

Jonathan
> ---
> Changes since v1:
> - move SIM register information in st_sensor_settings look up table
> - make st_sensors_init_interface_mode static and use name lookup
>   performed by st_sensors_check_device_support
> ---
>  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(+)
> 
> diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
> index 07d1489cd457..e44f62bf9caa 100644
> --- 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 st_accel_sensors_settings[] = {
>  			.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 st_accel_sensors_settings[] = {
>  			.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 st_accel_sensors_settings[] = {
>  				.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 st_accel_sensors_settings[] = {
>  			.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 st_accel_sensors_settings[] = {
>  			.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 st_accel_sensors_settings[] = {
>  			.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 st_accel_sensors_settings[] = {
>  			.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 st_accel_sensors_settings[] = {
>  			.mask_ihl = 0x02,
>  			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
>  		},
> +		.sim = {
> +			.addr = 0x23,
> +			.value = BIT(0),
> +		},
>  		.multi_read_bit = true,
>  		.bootime = 2,
>  	},
> diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
> index 274868100fd0..d99bb1460fe2 100644
> --- a/drivers/iio/common/st_sensors/st_sensors_core.c
> +++ b/drivers/iio/common/st_sensors/st_sensors_core.c
> @@ -581,6 +581,31 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
>  }
>  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)
> @@ -605,6 +630,10 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
>  		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);
> diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
> index 1f8211b6438b..7b0fa8b5c120 100644
> --- 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;
>  };
> 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 */

--
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