diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-09-01 05:44:40 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2016-09-18 06:28:21 -0400 |
commit | 0d1fb2d52d8b4a1124cb2db7d22c4131ad5805cf (patch) | |
tree | 33e6f6fe5223f60dac2c166749bd3fcecb2b0790 | |
parent | ab04f734b08a404550ba5f8391307bad2145acff (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/iio/accel/kxsd9-spi.c | 79 | ||||
-rw-r--r-- | drivers/iio/accel/kxsd9.c | 40 | ||||
-rw-r--r-- | drivers/iio/accel/kxsd9.h | 22 |
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 | |||
12 | static 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 | |||
19 | static 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 | |||
28 | static 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 | |||
52 | static int kxsd9_spi_probe(struct spi_device *spi) | 10 | static 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 | ||
77 | static int kxsd9_spi_remove(struct spi_device *spi) | 32 | static 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 | **/ |
48 | struct kxsd9_state { | 48 | struct 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); |
83 | error_ret: | 85 | error_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; |
102 | out_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 | ®val); | ||
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 | ||
193 | static const struct iio_info kxsd9_info = { | 201 | static const struct iio_info kxsd9_info = { |
@@ -198,7 +206,7 @@ static const struct iio_info kxsd9_info = { | |||
198 | }; | 206 | }; |
199 | 207 | ||
200 | int kxsd9_common_probe(struct device *parent, | 208 | int 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 | ||
7 | struct 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 | */ | ||
18 | struct 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 | |||
27 | int kxsd9_common_probe(struct device *parent, | 7 | int kxsd9_common_probe(struct device *parent, |
28 | struct kxsd9_transport *transport, | 8 | struct regmap *map, |
29 | const char *name); | 9 | const char *name); |
30 | int kxsd9_common_remove(struct device *parent); | 10 | int kxsd9_common_remove(struct device *parent); |