.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /** |
---|
2 | 3 | * BMA220 Digital triaxial acceleration sensor driver |
---|
3 | 4 | * |
---|
4 | | - * Copyright (c) 2016, Intel Corporation. |
---|
5 | | - * |
---|
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. |
---|
| 5 | + * Copyright (c) 2016,2020 Intel Corporation. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | | -#include <linux/acpi.h> |
---|
| 8 | +#include <linux/bits.h> |
---|
12 | 9 | #include <linux/kernel.h> |
---|
| 10 | +#include <linux/mod_devicetable.h> |
---|
13 | 11 | #include <linux/module.h> |
---|
| 12 | +#include <linux/spi/spi.h> |
---|
| 13 | + |
---|
14 | 14 | #include <linux/iio/buffer.h> |
---|
15 | 15 | #include <linux/iio/iio.h> |
---|
16 | 16 | #include <linux/iio/sysfs.h> |
---|
17 | | -#include <linux/spi/spi.h> |
---|
18 | 17 | #include <linux/iio/trigger_consumer.h> |
---|
19 | 18 | #include <linux/iio/triggered_buffer.h> |
---|
20 | 19 | |
---|
.. | .. |
---|
26 | 25 | #define BMA220_REG_SUSPEND 0x18 |
---|
27 | 26 | |
---|
28 | 27 | #define BMA220_CHIP_ID 0xDD |
---|
29 | | -#define BMA220_READ_MASK 0x80 |
---|
30 | | -#define BMA220_RANGE_MASK 0x03 |
---|
| 28 | +#define BMA220_READ_MASK BIT(7) |
---|
| 29 | +#define BMA220_RANGE_MASK GENMASK(1, 0) |
---|
31 | 30 | #define BMA220_DATA_SHIFT 2 |
---|
32 | 31 | #define BMA220_SUSPEND_SLEEP 0xFF |
---|
33 | 32 | #define BMA220_SUSPEND_WAKE 0x00 |
---|
34 | 33 | |
---|
35 | 34 | #define BMA220_DEVICE_NAME "bma220" |
---|
36 | | -#define BMA220_SCALE_AVAILABLE "0.623 1.248 2.491 4.983" |
---|
37 | 35 | |
---|
38 | 36 | #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ |
---|
39 | 37 | .type = IIO_ACCEL, \ |
---|
.. | .. |
---|
58 | 56 | AXIS_Z, |
---|
59 | 57 | }; |
---|
60 | 58 | |
---|
61 | | -static IIO_CONST_ATTR(in_accel_scale_available, BMA220_SCALE_AVAILABLE); |
---|
62 | | - |
---|
63 | | -static struct attribute *bma220_attributes[] = { |
---|
64 | | - &iio_const_attr_in_accel_scale_available.dev_attr.attr, |
---|
65 | | - NULL, |
---|
66 | | -}; |
---|
67 | | - |
---|
68 | | -static const struct attribute_group bma220_attribute_group = { |
---|
69 | | - .attrs = bma220_attributes, |
---|
70 | | -}; |
---|
71 | | - |
---|
72 | | -static const int bma220_scale_table[][4] = { |
---|
73 | | - {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000} |
---|
| 59 | +static const int bma220_scale_table[][2] = { |
---|
| 60 | + {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000}, |
---|
74 | 61 | }; |
---|
75 | 62 | |
---|
76 | 63 | struct bma220_data { |
---|
.. | .. |
---|
189 | 176 | return -EINVAL; |
---|
190 | 177 | } |
---|
191 | 178 | |
---|
| 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, |
---|
| 182 | + long mask) |
---|
| 183 | +{ |
---|
| 184 | + switch (mask) { |
---|
| 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; |
---|
| 190 | + default: |
---|
| 191 | + return -EINVAL; |
---|
| 192 | + } |
---|
| 193 | +} |
---|
| 194 | + |
---|
192 | 195 | static const struct iio_info bma220_info = { |
---|
193 | 196 | .read_raw = bma220_read_raw, |
---|
194 | 197 | .write_raw = bma220_write_raw, |
---|
195 | | - .attrs = &bma220_attribute_group, |
---|
| 198 | + .read_avail = bma220_read_avail, |
---|
196 | 199 | }; |
---|
197 | 200 | |
---|
198 | 201 | static int bma220_init(struct spi_device *spi) |
---|
.. | .. |
---|
205 | 208 | |
---|
206 | 209 | /* Make sure the chip is powered on */ |
---|
207 | 210 | ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); |
---|
| 211 | + if (ret == BMA220_SUSPEND_WAKE) |
---|
| 212 | + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); |
---|
208 | 213 | if (ret < 0) |
---|
209 | 214 | return ret; |
---|
210 | | - else if (ret == BMA220_SUSPEND_WAKE) |
---|
211 | | - return bma220_read_reg(spi, BMA220_REG_SUSPEND); |
---|
| 215 | + if (ret == BMA220_SUSPEND_WAKE) |
---|
| 216 | + return -EBUSY; |
---|
212 | 217 | |
---|
213 | 218 | return 0; |
---|
214 | 219 | } |
---|
.. | .. |
---|
219 | 224 | |
---|
220 | 225 | /* Make sure the chip is powered off */ |
---|
221 | 226 | ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); |
---|
| 227 | + if (ret == BMA220_SUSPEND_SLEEP) |
---|
| 228 | + ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); |
---|
222 | 229 | if (ret < 0) |
---|
223 | 230 | return ret; |
---|
224 | | - else if (ret == BMA220_SUSPEND_SLEEP) |
---|
225 | | - return bma220_read_reg(spi, BMA220_REG_SUSPEND); |
---|
| 231 | + if (ret == BMA220_SUSPEND_SLEEP) |
---|
| 232 | + return -EBUSY; |
---|
226 | 233 | |
---|
227 | 234 | return 0; |
---|
228 | 235 | } |
---|
.. | .. |
---|
244 | 251 | spi_set_drvdata(spi, indio_dev); |
---|
245 | 252 | mutex_init(&data->lock); |
---|
246 | 253 | |
---|
247 | | - indio_dev->dev.parent = &spi->dev; |
---|
248 | 254 | indio_dev->info = &bma220_info; |
---|
249 | 255 | indio_dev->name = BMA220_DEVICE_NAME; |
---|
250 | 256 | indio_dev->modes = INDIO_DIRECT_MODE; |
---|
.. | .. |
---|
253 | 259 | indio_dev->available_scan_masks = bma220_accel_scan_masks; |
---|
254 | 260 | |
---|
255 | 261 | ret = bma220_init(data->spi_device); |
---|
256 | | - if (ret < 0) |
---|
| 262 | + if (ret) |
---|
257 | 263 | return ret; |
---|
258 | 264 | |
---|
259 | 265 | ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, |
---|
.. | .. |
---|
286 | 292 | return bma220_deinit(spi); |
---|
287 | 293 | } |
---|
288 | 294 | |
---|
289 | | -#ifdef CONFIG_PM_SLEEP |
---|
290 | | -static int bma220_suspend(struct device *dev) |
---|
| 295 | +static __maybe_unused int bma220_suspend(struct device *dev) |
---|
291 | 296 | { |
---|
292 | | - struct bma220_data *data = |
---|
293 | | - iio_priv(spi_get_drvdata(to_spi_device(dev))); |
---|
| 297 | + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); |
---|
294 | 298 | |
---|
295 | 299 | /* The chip can be suspended/woken up by a simple register read. */ |
---|
296 | 300 | return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); |
---|
297 | 301 | } |
---|
298 | 302 | |
---|
299 | | -static int bma220_resume(struct device *dev) |
---|
| 303 | +static __maybe_unused int bma220_resume(struct device *dev) |
---|
300 | 304 | { |
---|
301 | | - struct bma220_data *data = |
---|
302 | | - iio_priv(spi_get_drvdata(to_spi_device(dev))); |
---|
| 305 | + struct bma220_data *data = iio_priv(dev_get_drvdata(dev)); |
---|
303 | 306 | |
---|
304 | 307 | return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); |
---|
305 | 308 | } |
---|
306 | | - |
---|
307 | 309 | static SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume); |
---|
308 | | - |
---|
309 | | -#define BMA220_PM_OPS (&bma220_pm_ops) |
---|
310 | | -#else |
---|
311 | | -#define BMA220_PM_OPS NULL |
---|
312 | | -#endif |
---|
313 | 310 | |
---|
314 | 311 | static const struct spi_device_id bma220_spi_id[] = { |
---|
315 | 312 | {"bma220", 0}, |
---|
.. | .. |
---|
320 | 317 | {"BMA0220", 0}, |
---|
321 | 318 | {} |
---|
322 | 319 | }; |
---|
323 | | - |
---|
324 | 320 | MODULE_DEVICE_TABLE(spi, bma220_spi_id); |
---|
325 | 321 | |
---|
326 | 322 | static struct spi_driver bma220_driver = { |
---|
327 | 323 | .driver = { |
---|
328 | 324 | .name = "bma220_spi", |
---|
329 | | - .pm = BMA220_PM_OPS, |
---|
330 | | - .acpi_match_table = ACPI_PTR(bma220_acpi_id), |
---|
| 325 | + .pm = &bma220_pm_ops, |
---|
| 326 | + .acpi_match_table = bma220_acpi_id, |
---|
331 | 327 | }, |
---|
332 | 328 | .probe = bma220_probe, |
---|
333 | 329 | .remove = bma220_remove, |
---|
334 | 330 | .id_table = bma220_spi_id, |
---|
335 | 331 | }; |
---|
336 | | - |
---|
337 | 332 | module_spi_driver(bma220_driver); |
---|
338 | 333 | |
---|
339 | 334 | MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); |
---|