aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2016-09-01 05:44:40 -0400
committerJonathan Cameron <jic23@kernel.org>2016-09-18 06:28:21 -0400
commit0d1fb2d52d8b4a1124cb2db7d22c4131ad5805cf (patch)
tree33e6f6fe5223f60dac2c166749bd3fcecb2b0790
parentab04f734b08a404550ba5f8391307bad2145acff (diff)
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: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/accel/Kconfig1
-rw-r--r--drivers/iio/accel/kxsd9-spi.c79
-rw-r--r--drivers/iio/accel/kxsd9.c40
-rw-r--r--drivers/iio/accel/kxsd9.h22
4 files changed, 43 insertions, 99 deletions
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 89bc5c5d6fd0..eebc20d6c827 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -131,6 +131,7 @@ config KXSD9_SPI
131 depends on KXSD9 131 depends on KXSD9
132 depends on SPI 132 depends on SPI
133 default KXSD9 133 default KXSD9
134 select REGMAP_SPI
134 help 135 help
135 Say yes here to enable the Kionix KXSD9 accelerometer 136 Say yes here to enable the Kionix KXSD9 accelerometer
136 SPI transport channel. 137 SPI transport channel.
diff --git a/drivers/iio/accel/kxsd9-spi.c b/drivers/iio/accel/kxsd9-spi.c
index a49c10cd7634..c5af51b7dd7e 100644
--- a/drivers/iio/accel/kxsd9-spi.c
+++ b/drivers/iio/accel/kxsd9-spi.c
@@ -3,75 +3,30 @@
3#include <linux/spi/spi.h> 3#include <linux/spi/spi.h>
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/slab.h> 5#include <linux/slab.h>
6#include <linux/regmap.h>
6 7
7#include "kxsd9.h" 8#include "kxsd9.h"
8 9
9#define KXSD9_READ(a) (0x80 | (a))
10#define KXSD9_WRITE(a) (a)
11
12static int kxsd9_spi_readreg(struct kxsd9_transport *tr, u8 address)
13{
14 struct spi_device *spi = tr->trdev;
15
16 return spi_w8r8(spi, KXSD9_READ(address));
17}
18
19static int kxsd9_spi_writereg(struct kxsd9_transport *tr, u8 address, u8 val)
20{
21 struct spi_device *spi = tr->trdev;
22
23 tr->tx[0] = KXSD9_WRITE(address),
24 tr->tx[1] = val;
25 return spi_write(spi, tr->tx, 2);
26}
27
28static int kxsd9_spi_readval(struct kxsd9_transport *tr, u8 address)
29{
30 struct spi_device *spi = tr->trdev;
31 struct spi_transfer xfers[] = {
32 {
33 .bits_per_word = 8,
34 .len = 1,
35 .delay_usecs = 200,
36 .tx_buf = tr->tx,
37 }, {
38 .bits_per_word = 8,
39 .len = 2,
40 .rx_buf = tr->rx,
41 },
42 };
43 int ret;
44
45 tr->tx[0] = KXSD9_READ(address);
46 ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
47 if (!ret)
48 ret = (((u16)(tr->rx[0])) << 8) | (tr->rx[1]);
49 return ret;
50}
51
52static int kxsd9_spi_probe(struct spi_device *spi) 10static int kxsd9_spi_probe(struct spi_device *spi)
53{ 11{
54 struct kxsd9_transport *transport; 12 static const struct regmap_config config = {
55 int ret; 13 .reg_bits = 8,
56 14 .val_bits = 8,
57 transport = devm_kzalloc(&spi->dev, sizeof(*transport), GFP_KERNEL); 15 .max_register = 0x0e,
58 if (!transport) 16 };
59 return -ENOMEM; 17 struct regmap *regmap;
60 18
61 transport->trdev = spi;
62 transport->readreg = kxsd9_spi_readreg;
63 transport->writereg = kxsd9_spi_writereg;
64 transport->readval = kxsd9_spi_readval;
65 spi->mode = SPI_MODE_0; 19 spi->mode = SPI_MODE_0;
66 spi_setup(spi); 20 regmap = devm_regmap_init_spi(spi, &config);
67 21 if (IS_ERR(regmap)) {
68 ret = kxsd9_common_probe(&spi->dev, 22 dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
69 transport, 23 __func__, PTR_ERR(regmap));
70 spi_get_device_id(spi)->name); 24 return PTR_ERR(regmap);
71 if (ret) 25 }
72 return ret; 26
73 27 return kxsd9_common_probe(&spi->dev,
74 return 0; 28 regmap,
29 spi_get_device_id(spi)->name);
75} 30}
76 31
77static int kxsd9_spi_remove(struct spi_device *spi) 32static int kxsd9_spi_remove(struct spi_device *spi)
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index a787ec236608..c065c6e09fa4 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -21,7 +21,7 @@
21#include <linux/sysfs.h> 21#include <linux/sysfs.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/module.h> 23#include <linux/module.h>
24 24#include <linux/regmap.h>
25#include <linux/iio/iio.h> 25#include <linux/iio/iio.h>
26#include <linux/iio/sysfs.h> 26#include <linux/iio/sysfs.h>
27 27
@@ -46,7 +46,7 @@
46 * @us: spi device 46 * @us: spi device
47 **/ 47 **/
48struct kxsd9_state { 48struct kxsd9_state {
49 struct kxsd9_transport *transport; 49 struct regmap *map;
50 struct mutex buf_lock; 50 struct mutex buf_lock;
51}; 51};
52 52
@@ -63,6 +63,7 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
63 int ret, i; 63 int ret, i;
64 struct kxsd9_state *st = iio_priv(indio_dev); 64 struct kxsd9_state *st = iio_priv(indio_dev);
65 bool foundit = false; 65 bool foundit = false;
66 unsigned int val;
66 67
67 for (i = 0; i < 4; i++) 68 for (i = 0; i < 4; i++)
68 if (micro == kxsd9_micro_scales[i]) { 69 if (micro == kxsd9_micro_scales[i]) {
@@ -73,13 +74,14 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
73 return -EINVAL; 74 return -EINVAL;
74 75
75 mutex_lock(&st->buf_lock); 76 mutex_lock(&st->buf_lock);
76 ret = st->transport->readreg(st->transport, 77 ret = regmap_read(st->map,
77 KXSD9_REG_CTRL_C); 78 KXSD9_REG_CTRL_C,
79 &val);
78 if (ret < 0) 80 if (ret < 0)
79 goto error_ret; 81 goto error_ret;
80 ret = st->transport->writereg(st->transport, 82 ret = regmap_write(st->map,
81 KXSD9_REG_CTRL_C, 83 KXSD9_REG_CTRL_C,
82 (ret & ~KXSD9_FS_MASK) | i); 84 (val & ~KXSD9_FS_MASK) | i);
83error_ret: 85error_ret:
84 mutex_unlock(&st->buf_lock); 86 mutex_unlock(&st->buf_lock);
85 return ret; 87 return ret;
@@ -89,11 +91,15 @@ static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
89{ 91{
90 int ret; 92 int ret;
91 struct kxsd9_state *st = iio_priv(indio_dev); 93 struct kxsd9_state *st = iio_priv(indio_dev);
94 __be16 raw_val;
92 95
93 mutex_lock(&st->buf_lock); 96 mutex_lock(&st->buf_lock);
94 ret = st->transport->readval(st->transport, address); 97 ret = regmap_bulk_read(st->map, address, &raw_val, sizeof(raw_val));
98 if (ret)
99 goto out_fail_read;
95 /* Only 12 bits are valid */ 100 /* Only 12 bits are valid */
96 ret &= 0xfff0; 101 ret = be16_to_cpu(raw_val) & 0xfff0;
102out_fail_read:
97 mutex_unlock(&st->buf_lock); 103 mutex_unlock(&st->buf_lock);
98 return ret; 104 return ret;
99} 105}
@@ -133,6 +139,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
133{ 139{
134 int ret = -EINVAL; 140 int ret = -EINVAL;
135 struct kxsd9_state *st = iio_priv(indio_dev); 141 struct kxsd9_state *st = iio_priv(indio_dev);
142 unsigned int regval;
136 143
137 switch (mask) { 144 switch (mask) {
138 case IIO_CHAN_INFO_RAW: 145 case IIO_CHAN_INFO_RAW:
@@ -143,12 +150,13 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
143 ret = IIO_VAL_INT; 150 ret = IIO_VAL_INT;
144 break; 151 break;
145 case IIO_CHAN_INFO_SCALE: 152 case IIO_CHAN_INFO_SCALE:
146 ret = st->transport->readreg(st->transport, 153 ret = regmap_read(st->map,
147 KXSD9_REG_CTRL_C); 154 KXSD9_REG_CTRL_C,
155 &regval);
148 if (ret < 0) 156 if (ret < 0)
149 goto error_ret; 157 goto error_ret;
150 *val = 0; 158 *val = 0;
151 *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; 159 *val2 = kxsd9_micro_scales[regval & KXSD9_FS_MASK];
152 ret = IIO_VAL_INT_PLUS_MICRO; 160 ret = IIO_VAL_INT_PLUS_MICRO;
153 break; 161 break;
154 } 162 }
@@ -184,10 +192,10 @@ static int kxsd9_power_up(struct kxsd9_state *st)
184{ 192{
185 int ret; 193 int ret;
186 194
187 ret = st->transport->writereg(st->transport, KXSD9_REG_CTRL_B, 0x40); 195 ret = regmap_write(st->map, KXSD9_REG_CTRL_B, 0x40);
188 if (ret) 196 if (ret)
189 return ret; 197 return ret;
190 return st->transport->writereg(st->transport, KXSD9_REG_CTRL_C, 0x9b); 198 return regmap_write(st->map, KXSD9_REG_CTRL_C, 0x9b);
191}; 199};
192 200
193static const struct iio_info kxsd9_info = { 201static const struct iio_info kxsd9_info = {
@@ -198,7 +206,7 @@ static const struct iio_info kxsd9_info = {
198}; 206};
199 207
200int kxsd9_common_probe(struct device *parent, 208int kxsd9_common_probe(struct device *parent,
201 struct kxsd9_transport *transport, 209 struct regmap *map,
202 const char *name) 210 const char *name)
203{ 211{
204 struct iio_dev *indio_dev; 212 struct iio_dev *indio_dev;
@@ -210,7 +218,7 @@ int kxsd9_common_probe(struct device *parent,
210 return -ENOMEM; 218 return -ENOMEM;
211 219
212 st = iio_priv(indio_dev); 220 st = iio_priv(indio_dev);
213 st->transport = transport; 221 st->map = map;
214 222
215 mutex_init(&st->buf_lock); 223 mutex_init(&st->buf_lock);
216 indio_dev->channels = kxsd9_channels; 224 indio_dev->channels = kxsd9_channels;
diff --git a/drivers/iio/accel/kxsd9.h b/drivers/iio/accel/kxsd9.h
index b6328e88b56f..19131a7a692c 100644
--- a/drivers/iio/accel/kxsd9.h
+++ b/drivers/iio/accel/kxsd9.h
@@ -4,27 +4,7 @@
4#define KXSD9_STATE_RX_SIZE 2 4#define KXSD9_STATE_RX_SIZE 2
5#define KXSD9_STATE_TX_SIZE 2 5#define KXSD9_STATE_TX_SIZE 2
6 6
7struct kxsd9_transport;
8
9/**
10 * struct kxsd9_transport - transport adapter for SPI or I2C
11 * @trdev: transport device such as SPI or I2C
12 * @readreg(): function to read a byte from an address in the device
13 * @writereg(): function to write a byte to an address in the device
14 * @readval(): function to read a 16bit value from the device
15 * @rx: cache aligned read buffer
16 * @tx: cache aligned write buffer
17 */
18struct kxsd9_transport {
19 void *trdev;
20 int (*readreg) (struct kxsd9_transport *tr, u8 address);
21 int (*writereg) (struct kxsd9_transport *tr, u8 address, u8 val);
22 int (*readval) (struct kxsd9_transport *tr, u8 address);
23 u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
24 u8 tx[KXSD9_STATE_TX_SIZE];
25};
26
27int kxsd9_common_probe(struct device *parent, 7int kxsd9_common_probe(struct device *parent,
28 struct kxsd9_transport *transport, 8 struct regmap *map,
29 const char *name); 9 const char *name);
30int kxsd9_common_remove(struct device *parent); 10int kxsd9_common_remove(struct device *parent);