Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d1fb2d5 authored by Linus Walleij's avatar Linus Walleij Committed by Jonathan Cameron
Browse files

iio: accel: kxsd9: Convert to use regmap for transport



This converts the KXSD9 driver to drop the custom transport
mechanism and just use regmap like everything else.

Tested-by: default avatarJonathan Cameron <jic23@kernel.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent ab04f734
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ config KXSD9_SPI
	depends on KXSD9
	depends on SPI
	default KXSD9
	select REGMAP_SPI
	help
	  Say yes here to enable the Kionix KXSD9 accelerometer
	  SPI transport channel.
+17 −62
Original line number Diff line number Diff line
@@ -3,75 +3,30 @@
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/regmap.h>

#include "kxsd9.h"

#define KXSD9_READ(a) (0x80 | (a))
#define KXSD9_WRITE(a) (a)

static int kxsd9_spi_readreg(struct kxsd9_transport *tr, u8 address)
{
	struct spi_device *spi = tr->trdev;

	return spi_w8r8(spi, KXSD9_READ(address));
}

static int kxsd9_spi_writereg(struct kxsd9_transport *tr, u8 address, u8 val)
{
	struct spi_device *spi = tr->trdev;

	tr->tx[0] = KXSD9_WRITE(address),
	tr->tx[1] = val;
	return spi_write(spi, tr->tx, 2);
}

static int kxsd9_spi_readval(struct kxsd9_transport *tr, u8 address)
{
	struct spi_device *spi = tr->trdev;
	struct spi_transfer xfers[] = {
		{
			.bits_per_word = 8,
			.len = 1,
			.delay_usecs = 200,
			.tx_buf = tr->tx,
		}, {
			.bits_per_word = 8,
			.len = 2,
			.rx_buf = tr->rx,
		},
	};
	int ret;

	tr->tx[0] = KXSD9_READ(address);
	ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
	if (!ret)
		ret = (((u16)(tr->rx[0])) << 8) | (tr->rx[1]);
	return ret;
}

static int kxsd9_spi_probe(struct spi_device *spi)
{
	struct kxsd9_transport *transport;
	int ret;

	transport = devm_kzalloc(&spi->dev, sizeof(*transport), GFP_KERNEL);
	if (!transport)
		return -ENOMEM;
	static const struct regmap_config config = {
		.reg_bits = 8,
		.val_bits = 8,
		.max_register = 0x0e,
	};
	struct regmap *regmap;

	transport->trdev = spi;
	transport->readreg = kxsd9_spi_readreg;
	transport->writereg = kxsd9_spi_writereg;
	transport->readval = kxsd9_spi_readval;
	spi->mode = SPI_MODE_0;
	spi_setup(spi);
	regmap = devm_regmap_init_spi(spi, &config);
	if (IS_ERR(regmap)) {
		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
			__func__, PTR_ERR(regmap));
		return PTR_ERR(regmap);
	}

	ret = kxsd9_common_probe(&spi->dev,
				 transport,
	return kxsd9_common_probe(&spi->dev,
				  regmap,
				  spi_get_device_id(spi)->name);
	if (ret)
		return ret;

	return 0;
}

static int kxsd9_spi_remove(struct spi_device *spi)
+24 −16
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/module.h>

#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

@@ -46,7 +46,7 @@
 * @us:		spi device
 **/
struct kxsd9_state {
	struct kxsd9_transport *transport;
	struct regmap *map;
	struct mutex buf_lock;
};

@@ -63,6 +63,7 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
	int ret, i;
	struct kxsd9_state *st = iio_priv(indio_dev);
	bool foundit = false;
	unsigned int val;

	for (i = 0; i < 4; i++)
		if (micro == kxsd9_micro_scales[i]) {
@@ -73,13 +74,14 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
		return -EINVAL;

	mutex_lock(&st->buf_lock);
	ret = st->transport->readreg(st->transport,
				     KXSD9_REG_CTRL_C);
	ret = regmap_read(st->map,
			  KXSD9_REG_CTRL_C,
			  &val);
	if (ret < 0)
		goto error_ret;
	ret = st->transport->writereg(st->transport,
	ret = regmap_write(st->map,
			   KXSD9_REG_CTRL_C,
				      (ret & ~KXSD9_FS_MASK) | i);
			   (val & ~KXSD9_FS_MASK) | i);
error_ret:
	mutex_unlock(&st->buf_lock);
	return ret;
@@ -89,11 +91,15 @@ static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
{
	int ret;
	struct kxsd9_state *st = iio_priv(indio_dev);
	__be16 raw_val;

	mutex_lock(&st->buf_lock);
	ret = st->transport->readval(st->transport, address);
	ret = regmap_bulk_read(st->map, address, &raw_val, sizeof(raw_val));
	if (ret)
		goto out_fail_read;
	/* Only 12 bits are valid */
	ret &= 0xfff0;
	ret = be16_to_cpu(raw_val) & 0xfff0;
out_fail_read:
	mutex_unlock(&st->buf_lock);
	return ret;
}
@@ -133,6 +139,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
{
	int ret = -EINVAL;
	struct kxsd9_state *st = iio_priv(indio_dev);
	unsigned int regval;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
@@ -143,12 +150,13 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
		ret = IIO_VAL_INT;
		break;
	case IIO_CHAN_INFO_SCALE:
		ret = st->transport->readreg(st->transport,
					     KXSD9_REG_CTRL_C);
		ret = regmap_read(st->map,
				  KXSD9_REG_CTRL_C,
				  &regval);
		if (ret < 0)
			goto error_ret;
		*val = 0;
		*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
		*val2 = kxsd9_micro_scales[regval & KXSD9_FS_MASK];
		ret = IIO_VAL_INT_PLUS_MICRO;
		break;
	}
@@ -184,10 +192,10 @@ static int kxsd9_power_up(struct kxsd9_state *st)
{
	int ret;

	ret = st->transport->writereg(st->transport, KXSD9_REG_CTRL_B, 0x40);
	ret = regmap_write(st->map, KXSD9_REG_CTRL_B, 0x40);
	if (ret)
		return ret;
	return st->transport->writereg(st->transport, KXSD9_REG_CTRL_C, 0x9b);
	return regmap_write(st->map, KXSD9_REG_CTRL_C, 0x9b);
};

static const struct iio_info kxsd9_info = {
@@ -198,7 +206,7 @@ static const struct iio_info kxsd9_info = {
};

int kxsd9_common_probe(struct device *parent,
		       struct kxsd9_transport *transport,
		       struct regmap *map,
		       const char *name)
{
	struct iio_dev *indio_dev;
@@ -210,7 +218,7 @@ int kxsd9_common_probe(struct device *parent,
		return -ENOMEM;

	st = iio_priv(indio_dev);
	st->transport = transport;
	st->map = map;

	mutex_init(&st->buf_lock);
	indio_dev->channels = kxsd9_channels;
+1 −21
Original line number Diff line number Diff line
@@ -4,27 +4,7 @@
#define KXSD9_STATE_RX_SIZE 2
#define KXSD9_STATE_TX_SIZE 2

struct kxsd9_transport;

/**
 * struct kxsd9_transport - transport adapter for SPI or I2C
 * @trdev: transport device such as SPI or I2C
 * @readreg(): function to read a byte from an address in the device
 * @writereg(): function to write a byte to an address in the device
 * @readval(): function to read a 16bit value from the device
 * @rx: cache aligned read buffer
 * @tx: cache aligned write buffer
 */
struct kxsd9_transport {
	void *trdev;
	int (*readreg) (struct kxsd9_transport *tr, u8 address);
	int (*writereg) (struct kxsd9_transport *tr, u8 address, u8 val);
	int (*readval) (struct kxsd9_transport *tr, u8 address);
	u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
	u8 tx[KXSD9_STATE_TX_SIZE];
};

int kxsd9_common_probe(struct device *parent,
		       struct kxsd9_transport *transport,
		       struct regmap *map,
		       const char *name);
int kxsd9_common_remove(struct device *parent);