Commit 1ecd245e authored by Denis Ciocca's avatar Denis Ciocca Committed by Jonathan Cameron
Browse files

iio: move 3-wire spi initialization to st_sensors_spi



Some devices need to be configured with special bit in order to
use spi 3-wire. This was done during device identification phase.
Instead, let's move this part as spi specific.
Doing this the check_device_support function becomes a simple
device id check, so let's rename it.

Signed-off-by: default avatarDenis Ciocca <denis.ciocca@st.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 570c2c55
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -1183,9 +1183,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
	if (err)
		return err;

	err = st_sensors_check_device_support(indio_dev,
					ARRAY_SIZE(st_accel_sensors_settings),
					st_accel_sensors_settings);
	err = st_sensors_verify_id(indio_dev);
	if (err < 0)
		goto st_accel_power_off;

+3 −1
Original line number Diff line number Diff line
@@ -124,7 +124,9 @@ static int st_accel_spi_probe(struct spi_device *spi)
	adata = iio_priv(indio_dev);
	adata->sensor_settings = (struct st_sensor_settings *)settings;

	st_sensors_spi_configure(indio_dev, spi, adata);
	err = st_sensors_spi_configure(indio_dev, spi);
	if (err < 0)
		return err;

	err = st_accel_common_probe(indio_dev);
	if (err < 0)
+15 −49
Original line number Diff line number Diff line
@@ -608,31 +608,6 @@ 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;
}

/*
 * st_sensors_get_settings_index() - get index of the sensor settings for a
 *				     specific device from list of settings
@@ -660,36 +635,30 @@ int st_sensors_get_settings_index(const char *name,
}
EXPORT_SYMBOL(st_sensors_get_settings_index);

int st_sensors_check_device_support(struct iio_dev *indio_dev,
			int num_sensors_list,
			const struct st_sensor_settings *sensor_settings)
/*
 * st_sensors_verify_id() - verify sensor ID (WhoAmI) is matching with the
 *			    expected value
 * @indio_dev: IIO device reference.
 *
 * Return: 0 on success (valid sensor ID), else a negative error code.
 */
int st_sensors_verify_id(struct iio_dev *indio_dev)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	int i, err;
	int err;
	u8 wai;

	i = st_sensors_get_settings_index(indio_dev->name,
					  sensor_settings, num_sensors_list);
	if (i < 0) {
		dev_err(&indio_dev->dev, "device name %s not recognized.\n",
			indio_dev->name);
		return i;
	}

	err = st_sensors_init_interface_mode(indio_dev, &sensor_settings[i]);
	if (err < 0)
		return err;

	if (sensor_settings[i].wai_addr) {
	if (sdata->sensor_settings->wai_addr) {
		err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
					   sensor_settings[i].wai_addr, &wai);
					   sdata->sensor_settings->wai_addr,
					   &wai);
		if (err < 0) {
			dev_err(&indio_dev->dev,
				"failed to read Who-Am-I register.\n");
			return err;
		}

		if (sensor_settings[i].wai != wai) {
		if (sdata->sensor_settings->wai != wai) {
			dev_err(&indio_dev->dev,
				"%s: WhoAmI mismatch (0x%x).\n",
				indio_dev->name, wai);
@@ -697,12 +666,9 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
		}
	}

	sdata->sensor_settings =
			(struct st_sensor_settings *)&sensor_settings[i];

	return i;
	return 0;
}
EXPORT_SYMBOL(st_sensors_check_device_support);
EXPORT_SYMBOL(st_sensors_verify_id);

ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
				struct device_attribute *attr, char *buf)
+63 −2
Original line number Diff line number Diff line
@@ -102,9 +102,68 @@ static const struct st_sensor_transfer_function st_sensors_tf_spi = {
	.read_multiple_byte = st_sensors_spi_read_multiple_byte,
};

void st_sensors_spi_configure(struct iio_dev *indio_dev,
			struct spi_device *spi, struct st_sensor_data *sdata)
/*
 * st_sensors_is_spi_3_wire() - check if SPI 3-wire mode has been selected
 * @spi: spi device reference.
 *
 * Return: true if SPI 3-wire mode is selected, false otherwise.
 */
static bool st_sensors_is_spi_3_wire(struct spi_device *spi)
{
	struct device_node *np = spi->dev.of_node;
	struct st_sensors_platform_data *pdata;

	pdata = (struct st_sensors_platform_data *)spi->dev.platform_data;
	if ((np && of_property_read_bool(np, "spi-3wire")) ||
	    (pdata && pdata->spi_3wire)) {
		return true;
	}

	return false;
}

/*
 * st_sensors_configure_spi_3_wire() - configure SPI 3-wire if needed
 * @spi: spi device reference.
 * @settings: sensor specific settings reference.
 *
 * Return: 0 on success, else a negative error code.
 */
static int st_sensors_configure_spi_3_wire(struct spi_device *spi,
					   struct st_sensor_settings *settings)
{
	if (settings->sim.addr) {
		u8 buffer[] = {
			settings->sim.addr,
			settings->sim.value
		};

		return spi_write(spi, buffer, 2);
	}

	return 0;
}

/*
 * st_sensors_spi_configure() - configure SPI interface
 * @indio_dev: IIO device reference.
 * @spi: spi device reference.
 *
 * Return: 0 on success, else a negative error code.
 */
int st_sensors_spi_configure(struct iio_dev *indio_dev,
			     struct spi_device *spi)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	int err;

	if (st_sensors_is_spi_3_wire(spi)) {
		err = st_sensors_configure_spi_3_wire(spi,
						      sdata->sensor_settings);
		if (err < 0)
			return err;
	}

	spi_set_drvdata(spi, indio_dev);

	indio_dev->dev.parent = &spi->dev;
@@ -113,6 +172,8 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev,
	sdata->dev = &spi->dev;
	sdata->tf = &st_sensors_tf_spi;
	sdata->get_irq_data_ready = st_sensors_spi_get_irq;

	return 0;
}
EXPORT_SYMBOL(st_sensors_spi_configure);

+1 −3
Original line number Diff line number Diff line
@@ -400,9 +400,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
	if (err)
		return err;

	err = st_sensors_check_device_support(indio_dev,
					ARRAY_SIZE(st_gyro_sensors_settings),
					st_gyro_sensors_settings);
	err = st_sensors_verify_id(indio_dev);
	if (err < 0)
		goto st_gyro_power_off;

Loading