1 // SPDX-License-Identifier: GPL-2.0-only
3 * BMA220 Digital triaxial acceleration sensor driver
5 * Copyright (c) 2016,2020 Intel Corporation.
8 #include <linux/bits.h>
9 #include <linux/kernel.h>
10 #include <linux/mod_devicetable.h>
11 #include <linux/module.h>
12 #include <linux/spi/spi.h>
14 #include <linux/iio/buffer.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17 #include <linux/iio/trigger_consumer.h>
18 #include <linux/iio/triggered_buffer.h>
20 #define BMA220_REG_ID 0x00
21 #define BMA220_REG_ACCEL_X 0x02
22 #define BMA220_REG_ACCEL_Y 0x03
23 #define BMA220_REG_ACCEL_Z 0x04
24 #define BMA220_REG_RANGE 0x11
25 #define BMA220_REG_SUSPEND 0x18
27 #define BMA220_CHIP_ID 0xDD
28 #define BMA220_READ_MASK BIT(7)
29 #define BMA220_RANGE_MASK GENMASK(1, 0)
30 #define BMA220_SUSPEND_SLEEP 0xFF
31 #define BMA220_SUSPEND_WAKE 0x00
33 #define BMA220_DEVICE_NAME "bma220"
35 #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \
39 .channel2 = IIO_MOD_##axis, \
40 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
41 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
42 .scan_index = index, \
48 .endianness = IIO_CPU, \
58 static const int bma220_scale_table
[][2] = {
59 {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000},
63 struct spi_device
*spi_device
;
67 /* Ensure timestamp is naturally aligned. */
68 s64 timestamp
__aligned(8);
70 u8 tx_buf
[2] __aligned(IIO_DMA_MINALIGN
);
73 static const struct iio_chan_spec bma220_channels
[] = {
74 BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X
, X
),
75 BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y
, Y
),
76 BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z
, Z
),
77 IIO_CHAN_SOFT_TIMESTAMP(3),
80 static inline int bma220_read_reg(struct spi_device
*spi
, u8 reg
)
82 return spi_w8r8(spi
, reg
| BMA220_READ_MASK
);
85 static const unsigned long bma220_accel_scan_masks
[] = {
86 BIT(AXIS_X
) | BIT(AXIS_Y
) | BIT(AXIS_Z
),
90 static irqreturn_t
bma220_trigger_handler(int irq
, void *p
)
93 struct iio_poll_func
*pf
= p
;
94 struct iio_dev
*indio_dev
= pf
->indio_dev
;
95 struct bma220_data
*data
= iio_priv(indio_dev
);
96 struct spi_device
*spi
= data
->spi_device
;
98 mutex_lock(&data
->lock
);
99 data
->tx_buf
[0] = BMA220_REG_ACCEL_X
| BMA220_READ_MASK
;
100 ret
= spi_write_then_read(spi
, data
->tx_buf
, 1, &data
->scan
.chans
,
101 ARRAY_SIZE(bma220_channels
) - 1);
105 iio_push_to_buffers_with_timestamp(indio_dev
, &data
->scan
,
108 mutex_unlock(&data
->lock
);
109 iio_trigger_notify_done(indio_dev
->trig
);
114 static int bma220_read_raw(struct iio_dev
*indio_dev
,
115 struct iio_chan_spec
const *chan
,
116 int *val
, int *val2
, long mask
)
120 struct bma220_data
*data
= iio_priv(indio_dev
);
123 case IIO_CHAN_INFO_RAW
:
124 ret
= bma220_read_reg(data
->spi_device
, chan
->address
);
127 *val
= sign_extend32(ret
>> chan
->scan_type
.shift
,
128 chan
->scan_type
.realbits
- 1);
130 case IIO_CHAN_INFO_SCALE
:
131 ret
= bma220_read_reg(data
->spi_device
, BMA220_REG_RANGE
);
134 range_idx
= ret
& BMA220_RANGE_MASK
;
135 *val
= bma220_scale_table
[range_idx
][0];
136 *val2
= bma220_scale_table
[range_idx
][1];
137 return IIO_VAL_INT_PLUS_MICRO
;
143 static int bma220_write_raw(struct iio_dev
*indio_dev
,
144 struct iio_chan_spec
const *chan
,
145 int val
, int val2
, long mask
)
150 struct bma220_data
*data
= iio_priv(indio_dev
);
153 case IIO_CHAN_INFO_SCALE
:
154 for (i
= 0; i
< ARRAY_SIZE(bma220_scale_table
); i
++)
155 if (val
== bma220_scale_table
[i
][0] &&
156 val2
== bma220_scale_table
[i
][1]) {
163 mutex_lock(&data
->lock
);
164 data
->tx_buf
[0] = BMA220_REG_RANGE
;
165 data
->tx_buf
[1] = index
;
166 ret
= spi_write(data
->spi_device
, data
->tx_buf
,
167 sizeof(data
->tx_buf
));
169 dev_err(&data
->spi_device
->dev
,
170 "failed to set measurement range\n");
171 mutex_unlock(&data
->lock
);
179 static int bma220_read_avail(struct iio_dev
*indio_dev
,
180 struct iio_chan_spec
const *chan
,
181 const int **vals
, int *type
, int *length
,
185 case IIO_CHAN_INFO_SCALE
:
186 *vals
= (int *)bma220_scale_table
;
187 *type
= IIO_VAL_INT_PLUS_MICRO
;
188 *length
= ARRAY_SIZE(bma220_scale_table
) * 2;
189 return IIO_AVAIL_LIST
;
195 static const struct iio_info bma220_info
= {
196 .read_raw
= bma220_read_raw
,
197 .write_raw
= bma220_write_raw
,
198 .read_avail
= bma220_read_avail
,
201 static int bma220_init(struct spi_device
*spi
)
205 ret
= bma220_read_reg(spi
, BMA220_REG_ID
);
206 if (ret
!= BMA220_CHIP_ID
)
209 /* Make sure the chip is powered on */
210 ret
= bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
211 if (ret
== BMA220_SUSPEND_WAKE
)
212 ret
= bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
215 if (ret
== BMA220_SUSPEND_WAKE
)
221 static int bma220_power(struct spi_device
*spi
, bool up
)
226 * The chip can be suspended/woken up by a simple register read.
227 * So, we need up to 2 register reads of the suspend register
228 * to make sure that the device is in the desired state.
230 for (i
= 0; i
< 2; i
++) {
231 ret
= bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
235 if (up
&& ret
== BMA220_SUSPEND_SLEEP
)
238 if (!up
&& ret
== BMA220_SUSPEND_WAKE
)
245 static void bma220_deinit(void *spi
)
247 bma220_power(spi
, false);
250 static int bma220_probe(struct spi_device
*spi
)
253 struct iio_dev
*indio_dev
;
254 struct bma220_data
*data
;
256 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*data
));
258 dev_err(&spi
->dev
, "iio allocation failed!\n");
262 data
= iio_priv(indio_dev
);
263 data
->spi_device
= spi
;
264 mutex_init(&data
->lock
);
266 indio_dev
->info
= &bma220_info
;
267 indio_dev
->name
= BMA220_DEVICE_NAME
;
268 indio_dev
->modes
= INDIO_DIRECT_MODE
;
269 indio_dev
->channels
= bma220_channels
;
270 indio_dev
->num_channels
= ARRAY_SIZE(bma220_channels
);
271 indio_dev
->available_scan_masks
= bma220_accel_scan_masks
;
273 ret
= bma220_init(data
->spi_device
);
277 ret
= devm_add_action_or_reset(&spi
->dev
, bma220_deinit
, spi
);
281 ret
= devm_iio_triggered_buffer_setup(&spi
->dev
, indio_dev
,
282 iio_pollfunc_store_time
,
283 bma220_trigger_handler
, NULL
);
285 dev_err(&spi
->dev
, "iio triggered buffer setup failed\n");
289 return devm_iio_device_register(&spi
->dev
, indio_dev
);
292 static int bma220_suspend(struct device
*dev
)
294 struct spi_device
*spi
= to_spi_device(dev
);
296 return bma220_power(spi
, false);
299 static int bma220_resume(struct device
*dev
)
301 struct spi_device
*spi
= to_spi_device(dev
);
303 return bma220_power(spi
, true);
305 static DEFINE_SIMPLE_DEV_PM_OPS(bma220_pm_ops
, bma220_suspend
, bma220_resume
);
307 static const struct spi_device_id bma220_spi_id
[] = {
312 static const struct acpi_device_id bma220_acpi_id
[] = {
316 MODULE_DEVICE_TABLE(spi
, bma220_spi_id
);
318 static struct spi_driver bma220_driver
= {
320 .name
= "bma220_spi",
321 .pm
= pm_sleep_ptr(&bma220_pm_ops
),
322 .acpi_match_table
= bma220_acpi_id
,
324 .probe
= bma220_probe
,
325 .id_table
= bma220_spi_id
,
327 module_spi_driver(bma220_driver
);
329 MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
330 MODULE_DESCRIPTION("BMA220 acceleration sensor driver");
331 MODULE_LICENSE("GPL v2");