Commit 062809ef authored by Denis Ciocca's avatar Denis Ciocca Committed by Jonathan Cameron
Browse files

iio: make st_sensors drivers use regmap



This patch is meant to replace the i2c/spi transfer functions with
regmap. SPI framework requires DMA safe buffers so let's add GFP_DMA
flag for memory allocation used by bulk_read functions.

Signed-off-by: default avatarDenis Ciocca <denis.ciocca@st.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 1ecd245e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -39,7 +39,8 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
	int err;
	struct st_sensor_data *adata = iio_priv(indio_dev);

	adata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
	adata->buffer_data = kmalloc(indio_dev->scan_bytes,
				     GFP_DMA | GFP_KERNEL);
	if (adata->buffer_data == NULL) {
		err = -ENOMEM;
		goto allocate_memory_error;
+0 −3
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/acpi.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
@@ -1177,7 +1176,6 @@ int st_accel_common_probe(struct iio_dev *indio_dev)

	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &accel_info;
	mutex_init(&adata->tb.buf_lock);

	err = st_sensors_power_enable(indio_dev);
	if (err)
@@ -1188,7 +1186,6 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
		goto st_accel_power_off;

	adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
	adata->multiread_bit = adata->sensor_settings->multi_read_bit;
	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;

	channels_size = indio_dev->num_channels * sizeof(struct iio_chan_spec);
+3 −1
Original line number Diff line number Diff line
@@ -174,7 +174,9 @@ static int st_accel_i2c_probe(struct i2c_client *client)
	adata = iio_priv(indio_dev);
	adata->sensor_settings = (struct st_sensor_settings *)settings;

	st_sensors_i2c_configure(indio_dev, client, adata);
	ret = st_sensors_i2c_configure(indio_dev, client);
	if (ret < 0)
		return ret;

	ret = st_accel_common_probe(indio_dev);
	if (ret < 0)
+4 −6
Original line number Diff line number Diff line
@@ -17,15 +17,16 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/irqreturn.h>
#include <linux/regmap.h>

#include <linux/iio/common/st_sensors.h>


static int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf)
{
	int i;
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	unsigned int num_data_channels = sdata->num_data_channels;
	int i;

	for_each_set_bit(i, indio_dev->active_scan_mask, num_data_channels) {
		const struct iio_chan_spec *channel = &indio_dev->channels[i];
@@ -36,11 +37,8 @@ static int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf)
			channel->scan_type.storagebits >> 3;

		buf = PTR_ALIGN(buf, storage_bytes);
		if (sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
						  channel->address,
						  bytes_to_read, buf,
						  sdata->multiread_bit) <
		    bytes_to_read)
		if (regmap_bulk_read(sdata->regmap, channel->address,
				     buf, bytes_to_read) < 0)
			return -EIO;

		/* Advance the buffer pointer */
+12 −27
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/regulator/consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <asm/unaligned.h>
#include <linux/iio/common/st_sensors.h>

@@ -28,19 +29,10 @@ static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
				    u8 reg_addr, u8 mask, u8 data)
{
	int err;
	u8 new_data;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = sdata->tf->read_byte(&sdata->tb, sdata->dev, reg_addr, &new_data);
	if (err < 0)
		goto st_sensors_write_data_with_mask_error;

	new_data = ((new_data & (~mask)) | ((data << __ffs(mask)) & mask));
	err = sdata->tf->write_byte(&sdata->tb, sdata->dev, reg_addr, new_data);

st_sensors_write_data_with_mask_error:
	return err;
	return regmap_update_bits(sdata->regmap,
				  reg_addr, mask, data << __ffs(mask));
}

int st_sensors_debugfs_reg_access(struct iio_dev *indio_dev,
@@ -48,19 +40,15 @@ int st_sensors_debugfs_reg_access(struct iio_dev *indio_dev,
				  unsigned *readval)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	u8 readdata;
	int err;

	if (!readval)
		return sdata->tf->write_byte(&sdata->tb, sdata->dev,
					     (u8)reg, (u8)writeval);
		return regmap_write(sdata->regmap, reg, writeval);

	err = sdata->tf->read_byte(&sdata->tb, sdata->dev, (u8)reg, &readdata);
	err = regmap_read(sdata->regmap, reg, readval);
	if (err < 0)
		return err;

	*readval = (unsigned)readdata;

	return 0;
}
EXPORT_SYMBOL(st_sensors_debugfs_reg_access);
@@ -554,13 +542,12 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,

	byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
					ch->scan_type.shift, 8);
	outdata = kmalloc(byte_for_channel, GFP_KERNEL);
	outdata = kmalloc(byte_for_channel, GFP_DMA | GFP_KERNEL);
	if (!outdata)
		return -ENOMEM;

	err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
				ch->address, byte_for_channel,
				outdata, sdata->multiread_bit);
	err = regmap_bulk_read(sdata->regmap, ch->address,
			       outdata, byte_for_channel);
	if (err < 0)
		goto st_sensors_free_memory;

@@ -645,13 +632,11 @@ EXPORT_SYMBOL(st_sensors_get_settings_index);
int st_sensors_verify_id(struct iio_dev *indio_dev)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	int err;
	u8 wai;
	int wai, err;

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