2 * BMA220 Digital triaxial acceleration sensor driver
4 * Copyright (c) 2016, Intel Corporation.
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
11 #include <linux/acpi.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/iio/buffer.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17 #include <linux/spi/spi.h>
18 #include <linux/iio/trigger_consumer.h>
19 #include <linux/iio/triggered_buffer.h>
21 #define BMA220_REG_ID 0x00
22 #define BMA220_REG_ACCEL_X 0x02
23 #define BMA220_REG_ACCEL_Y 0x03
24 #define BMA220_REG_ACCEL_Z 0x04
25 #define BMA220_REG_RANGE 0x11
26 #define BMA220_REG_SUSPEND 0x18
28 #define BMA220_CHIP_ID 0xDD
29 #define BMA220_READ_MASK 0x80
30 #define BMA220_RANGE_MASK 0x03
31 #define BMA220_DATA_SHIFT 2
32 #define BMA220_SUSPEND_SLEEP 0xFF
33 #define BMA220_SUSPEND_WAKE 0x00
35 #define BMA220_DEVICE_NAME "bma220"
36 #define BMA220_SCALE_AVAILABLE "0.623 1.248 2.491 4.983"
38 #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \
42 .channel2 = IIO_MOD_##axis, \
43 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
44 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
45 .scan_index = index, \
50 .shift = BMA220_DATA_SHIFT, \
51 .endianness = IIO_CPU, \
61 static IIO_CONST_ATTR(in_accel_scale_available
, BMA220_SCALE_AVAILABLE
);
63 static struct attribute
*bma220_attributes
[] = {
64 &iio_const_attr_in_accel_scale_available
.dev_attr
.attr
,
68 static const struct attribute_group bma220_attribute_group
= {
69 .attrs
= bma220_attributes
,
72 static const int bma220_scale_table
[][4] = {
73 {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000}
77 struct spi_device
*spi_device
;
79 s8 buffer
[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */
80 u8 tx_buf
[2] ____cacheline_aligned
;
83 static const struct iio_chan_spec bma220_channels
[] = {
84 BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X
, X
),
85 BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y
, Y
),
86 BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z
, Z
),
87 IIO_CHAN_SOFT_TIMESTAMP(3),
90 static inline int bma220_read_reg(struct spi_device
*spi
, u8 reg
)
92 return spi_w8r8(spi
, reg
| BMA220_READ_MASK
);
95 static const unsigned long bma220_accel_scan_masks
[] = {
96 BIT(AXIS_X
) | BIT(AXIS_Y
) | BIT(AXIS_Z
),
100 static irqreturn_t
bma220_trigger_handler(int irq
, void *p
)
103 struct iio_poll_func
*pf
= p
;
104 struct iio_dev
*indio_dev
= pf
->indio_dev
;
105 struct bma220_data
*data
= iio_priv(indio_dev
);
106 struct spi_device
*spi
= data
->spi_device
;
108 mutex_lock(&data
->lock
);
109 data
->tx_buf
[0] = BMA220_REG_ACCEL_X
| BMA220_READ_MASK
;
110 ret
= spi_write_then_read(spi
, data
->tx_buf
, 1, data
->buffer
,
111 ARRAY_SIZE(bma220_channels
) - 1);
115 iio_push_to_buffers_with_timestamp(indio_dev
, data
->buffer
,
118 mutex_unlock(&data
->lock
);
119 iio_trigger_notify_done(indio_dev
->trig
);
124 static int bma220_read_raw(struct iio_dev
*indio_dev
,
125 struct iio_chan_spec
const *chan
,
126 int *val
, int *val2
, long mask
)
130 struct bma220_data
*data
= iio_priv(indio_dev
);
133 case IIO_CHAN_INFO_RAW
:
134 ret
= bma220_read_reg(data
->spi_device
, chan
->address
);
137 *val
= sign_extend32(ret
>> BMA220_DATA_SHIFT
, 5);
139 case IIO_CHAN_INFO_SCALE
:
140 ret
= bma220_read_reg(data
->spi_device
, BMA220_REG_RANGE
);
143 range_idx
= ret
& BMA220_RANGE_MASK
;
144 *val
= bma220_scale_table
[range_idx
][0];
145 *val2
= bma220_scale_table
[range_idx
][1];
146 return IIO_VAL_INT_PLUS_MICRO
;
152 static int bma220_write_raw(struct iio_dev
*indio_dev
,
153 struct iio_chan_spec
const *chan
,
154 int val
, int val2
, long mask
)
159 struct bma220_data
*data
= iio_priv(indio_dev
);
162 case IIO_CHAN_INFO_SCALE
:
163 for (i
= 0; i
< ARRAY_SIZE(bma220_scale_table
); i
++)
164 if (val
== bma220_scale_table
[i
][0] &&
165 val2
== bma220_scale_table
[i
][1]) {
172 mutex_lock(&data
->lock
);
173 data
->tx_buf
[0] = BMA220_REG_RANGE
;
174 data
->tx_buf
[1] = index
;
175 ret
= spi_write(data
->spi_device
, data
->tx_buf
,
176 sizeof(data
->tx_buf
));
178 dev_err(&data
->spi_device
->dev
,
179 "failed to set measurement range\n");
180 mutex_unlock(&data
->lock
);
188 static const struct iio_info bma220_info
= {
189 .read_raw
= bma220_read_raw
,
190 .write_raw
= bma220_write_raw
,
191 .attrs
= &bma220_attribute_group
,
194 static int bma220_init(struct spi_device
*spi
)
198 ret
= bma220_read_reg(spi
, BMA220_REG_ID
);
199 if (ret
!= BMA220_CHIP_ID
)
202 /* Make sure the chip is powered on */
203 ret
= bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
206 else if (ret
== BMA220_SUSPEND_WAKE
)
207 return bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
212 static int bma220_deinit(struct spi_device
*spi
)
216 /* Make sure the chip is powered off */
217 ret
= bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
220 else if (ret
== BMA220_SUSPEND_SLEEP
)
221 return bma220_read_reg(spi
, BMA220_REG_SUSPEND
);
226 static int bma220_probe(struct spi_device
*spi
)
229 struct iio_dev
*indio_dev
;
230 struct bma220_data
*data
;
232 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*data
));
234 dev_err(&spi
->dev
, "iio allocation failed!\n");
238 data
= iio_priv(indio_dev
);
239 data
->spi_device
= spi
;
240 spi_set_drvdata(spi
, indio_dev
);
241 mutex_init(&data
->lock
);
243 indio_dev
->dev
.parent
= &spi
->dev
;
244 indio_dev
->info
= &bma220_info
;
245 indio_dev
->name
= BMA220_DEVICE_NAME
;
246 indio_dev
->modes
= INDIO_DIRECT_MODE
;
247 indio_dev
->channels
= bma220_channels
;
248 indio_dev
->num_channels
= ARRAY_SIZE(bma220_channels
);
249 indio_dev
->available_scan_masks
= bma220_accel_scan_masks
;
251 ret
= bma220_init(data
->spi_device
);
255 ret
= iio_triggered_buffer_setup(indio_dev
, iio_pollfunc_store_time
,
256 bma220_trigger_handler
, NULL
);
258 dev_err(&spi
->dev
, "iio triggered buffer setup failed\n");
262 ret
= iio_device_register(indio_dev
);
264 dev_err(&spi
->dev
, "iio_device_register failed\n");
265 iio_triggered_buffer_cleanup(indio_dev
);
272 return bma220_deinit(spi
);
275 static int bma220_remove(struct spi_device
*spi
)
277 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
279 iio_device_unregister(indio_dev
);
280 iio_triggered_buffer_cleanup(indio_dev
);
282 return bma220_deinit(spi
);
285 #ifdef CONFIG_PM_SLEEP
286 static int bma220_suspend(struct device
*dev
)
288 struct bma220_data
*data
=
289 iio_priv(spi_get_drvdata(to_spi_device(dev
)));
291 /* The chip can be suspended/woken up by a simple register read. */
292 return bma220_read_reg(data
->spi_device
, BMA220_REG_SUSPEND
);
295 static int bma220_resume(struct device
*dev
)
297 struct bma220_data
*data
=
298 iio_priv(spi_get_drvdata(to_spi_device(dev
)));
300 return bma220_read_reg(data
->spi_device
, BMA220_REG_SUSPEND
);
303 static SIMPLE_DEV_PM_OPS(bma220_pm_ops
, bma220_suspend
, bma220_resume
);
305 #define BMA220_PM_OPS (&bma220_pm_ops)
307 #define BMA220_PM_OPS NULL
310 static const struct spi_device_id bma220_spi_id
[] = {
315 static const struct acpi_device_id bma220_acpi_id
[] = {
320 MODULE_DEVICE_TABLE(spi
, bma220_spi_id
);
322 static struct spi_driver bma220_driver
= {
324 .name
= "bma220_spi",
326 .acpi_match_table
= ACPI_PTR(bma220_acpi_id
),
328 .probe
= bma220_probe
,
329 .remove
= bma220_remove
,
330 .id_table
= bma220_spi_id
,
333 module_spi_driver(bma220_driver
);
335 MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
336 MODULE_DESCRIPTION("BMA220 acceleration sensor driver");
337 MODULE_LICENSE("GPL v2");