1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * 3-axis accelerometer driver supporting following Bosch-Sensortec chips: |
4 | * - BMI088 |
5 | * - BMI085 |
6 | * - BMI090L |
7 | * |
8 | * Copyright (c) 2018-2020, Topic Embedded Products |
9 | */ |
10 | |
11 | #include <linux/module.h> |
12 | #include <linux/regmap.h> |
13 | #include <linux/slab.h> |
14 | #include <linux/spi/spi.h> |
15 | |
16 | #include "bmi088-accel.h" |
17 | |
18 | static int bmi088_regmap_spi_write(void *context, const void *data, size_t count) |
19 | { |
20 | struct spi_device *spi = context; |
21 | |
22 | /* Write register is same as generic SPI */ |
23 | return spi_write(spi, buf: data, len: count); |
24 | } |
25 | |
26 | static int bmi088_regmap_spi_read(void *context, const void *reg, |
27 | size_t reg_size, void *val, size_t val_size) |
28 | { |
29 | struct spi_device *spi = context; |
30 | u8 addr[2]; |
31 | |
32 | addr[0] = *(u8 *)reg; |
33 | addr[0] |= BIT(7); /* Set RW = '1' */ |
34 | addr[1] = 0; /* Read requires a dummy byte transfer */ |
35 | |
36 | return spi_write_then_read(spi, txbuf: addr, n_tx: sizeof(addr), rxbuf: val, n_rx: val_size); |
37 | } |
38 | |
39 | static struct regmap_bus bmi088_regmap_bus = { |
40 | .write = bmi088_regmap_spi_write, |
41 | .read = bmi088_regmap_spi_read, |
42 | }; |
43 | |
44 | static int bmi088_accel_probe(struct spi_device *spi) |
45 | { |
46 | struct regmap *regmap; |
47 | const struct spi_device_id *id = spi_get_device_id(sdev: spi); |
48 | |
49 | regmap = devm_regmap_init(&spi->dev, &bmi088_regmap_bus, |
50 | spi, &bmi088_regmap_conf); |
51 | |
52 | if (IS_ERR(ptr: regmap)) { |
53 | dev_err(&spi->dev, "Failed to initialize spi regmap\n" ); |
54 | return PTR_ERR(ptr: regmap); |
55 | } |
56 | |
57 | return bmi088_accel_core_probe(dev: &spi->dev, regmap, irq: spi->irq, |
58 | type: id->driver_data); |
59 | } |
60 | |
61 | static void bmi088_accel_remove(struct spi_device *spi) |
62 | { |
63 | bmi088_accel_core_remove(dev: &spi->dev); |
64 | } |
65 | |
66 | static const struct of_device_id bmi088_of_match[] = { |
67 | { .compatible = "bosch,bmi085-accel" }, |
68 | { .compatible = "bosch,bmi088-accel" }, |
69 | { .compatible = "bosch,bmi090l-accel" }, |
70 | {} |
71 | }; |
72 | MODULE_DEVICE_TABLE(of, bmi088_of_match); |
73 | |
74 | static const struct spi_device_id bmi088_accel_id[] = { |
75 | {"bmi085-accel" , BOSCH_BMI085}, |
76 | {"bmi088-accel" , BOSCH_BMI088}, |
77 | {"bmi090l-accel" , BOSCH_BMI090L}, |
78 | {} |
79 | }; |
80 | MODULE_DEVICE_TABLE(spi, bmi088_accel_id); |
81 | |
82 | static struct spi_driver bmi088_accel_driver = { |
83 | .driver = { |
84 | .name = "bmi088_accel_spi" , |
85 | .pm = pm_ptr(&bmi088_accel_pm_ops), |
86 | .of_match_table = bmi088_of_match, |
87 | }, |
88 | .probe = bmi088_accel_probe, |
89 | .remove = bmi088_accel_remove, |
90 | .id_table = bmi088_accel_id, |
91 | }; |
92 | module_spi_driver(bmi088_accel_driver); |
93 | |
94 | MODULE_AUTHOR("Niek van Agt <niek.van.agt@topicproducts.com>" ); |
95 | MODULE_LICENSE("GPL v2" ); |
96 | MODULE_DESCRIPTION("BMI088 accelerometer driver (SPI)" ); |
97 | MODULE_IMPORT_NS(IIO_BMI088); |
98 | |