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: Denis Ciocca <denis.ciocca@st.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Denis Ciocca 2019-07-18 15:53:52 -07:00 коммит произвёл Jonathan Cameron
Родитель 570c2c55ef
Коммит 1ecd245e0e
12 изменённых файлов: 97 добавлений и 71 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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);

Просмотреть файл

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

Просмотреть файл

@ -91,7 +91,9 @@ static int st_gyro_spi_probe(struct spi_device *spi)
gdata = iio_priv(indio_dev);
gdata->sensor_settings = (struct st_sensor_settings *)settings;
st_sensors_spi_configure(indio_dev, spi, gdata);
err = st_sensors_spi_configure(indio_dev, spi);
if (err < 0)
return err;
err = st_gyro_common_probe(indio_dev);
if (err < 0)

Просмотреть файл

@ -502,9 +502,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
if (err)
return err;
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_magn_sensors_settings),
st_magn_sensors_settings);
err = st_sensors_verify_id(indio_dev);
if (err < 0)
goto st_magn_power_off;

Просмотреть файл

@ -73,7 +73,9 @@ static int st_magn_spi_probe(struct spi_device *spi)
mdata = iio_priv(indio_dev);
mdata->sensor_settings = (struct st_sensor_settings *)settings;
st_sensors_spi_configure(indio_dev, spi, mdata);
err = st_sensors_spi_configure(indio_dev, spi);
if (err < 0)
return err;
err = st_magn_common_probe(indio_dev);
if (err < 0)

Просмотреть файл

@ -698,9 +698,7 @@ int st_press_common_probe(struct iio_dev *indio_dev)
if (err)
return err;
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_press_sensors_settings),
st_press_sensors_settings);
err = st_sensors_verify_id(indio_dev);
if (err < 0)
goto st_press_power_off;

Просмотреть файл

@ -83,7 +83,9 @@ static int st_press_spi_probe(struct spi_device *spi)
press_data = iio_priv(indio_dev);
press_data->sensor_settings = (struct st_sensor_settings *)settings;
st_sensors_spi_configure(indio_dev, spi, press_data);
err = st_sensors_spi_configure(indio_dev, spi);
if (err < 0)
return err;
err = st_press_common_probe(indio_dev);
if (err < 0)

Просмотреть файл

@ -338,8 +338,7 @@ int st_sensors_get_settings_index(const char *name,
const struct st_sensor_settings *list,
const int list_length);
int st_sensors_check_device_support(struct iio_dev *indio_dev,
int num_sensors_list, const struct st_sensor_settings *sensor_settings);
int st_sensors_verify_id(struct iio_dev *indio_dev);
ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
struct device_attribute *attr, char *buf);

Просмотреть файл

@ -13,7 +13,7 @@
#include <linux/spi/spi.h>
#include <linux/iio/common/st_sensors.h>
void st_sensors_spi_configure(struct iio_dev *indio_dev,
struct spi_device *spi, struct st_sensor_data *sdata);
int st_sensors_spi_configure(struct iio_dev *indio_dev,
struct spi_device *spi);
#endif /* ST_SENSORS_SPI_H */