1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2015 Intel Corporation Inc. |
4 | */ |
5 | #include <linux/mod_devicetable.h> |
6 | #include <linux/module.h> |
7 | #include <linux/property.h> |
8 | #include <linux/spi/spi.h> |
9 | #include <linux/regmap.h> |
10 | #include <linux/iio/iio.h> |
11 | #include "inv_mpu_iio.h" |
12 | |
13 | static const struct regmap_config inv_mpu_regmap_config = { |
14 | .reg_bits = 8, |
15 | .val_bits = 8, |
16 | }; |
17 | |
18 | static int inv_mpu_i2c_disable(struct iio_dev *indio_dev) |
19 | { |
20 | struct inv_mpu6050_state *st = iio_priv(indio_dev); |
21 | int ret = 0; |
22 | |
23 | if (st->reg->i2c_if) { |
24 | ret = regmap_write(map: st->map, reg: st->reg->i2c_if, |
25 | INV_ICM20602_BIT_I2C_IF_DIS); |
26 | } else { |
27 | st->chip_config.user_ctrl |= INV_MPU6050_BIT_I2C_IF_DIS; |
28 | ret = regmap_write(map: st->map, reg: st->reg->user_ctrl, |
29 | val: st->chip_config.user_ctrl); |
30 | } |
31 | |
32 | return ret; |
33 | } |
34 | |
35 | static int inv_mpu_probe(struct spi_device *spi) |
36 | { |
37 | const void *match; |
38 | struct regmap *regmap; |
39 | const struct spi_device_id *spi_id; |
40 | const char *name = NULL; |
41 | enum inv_devices chip_type; |
42 | |
43 | if ((spi_id = spi_get_device_id(sdev: spi))) { |
44 | chip_type = (enum inv_devices)spi_id->driver_data; |
45 | name = spi_id->name; |
46 | } else if ((match = device_get_match_data(dev: &spi->dev))) { |
47 | chip_type = (uintptr_t)match; |
48 | name = dev_name(dev: &spi->dev); |
49 | } else { |
50 | return -ENODEV; |
51 | } |
52 | |
53 | regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config); |
54 | if (IS_ERR(ptr: regmap)) { |
55 | dev_err(&spi->dev, "Failed to register spi regmap: %pe\n" , |
56 | regmap); |
57 | return PTR_ERR(ptr: regmap); |
58 | } |
59 | |
60 | return inv_mpu_core_probe(regmap, irq: spi->irq, name, |
61 | inv_mpu_bus_setup: inv_mpu_i2c_disable, chip_type); |
62 | } |
63 | |
64 | /* |
65 | * device id table is used to identify what device can be |
66 | * supported by this driver |
67 | */ |
68 | static const struct spi_device_id inv_mpu_id[] = { |
69 | {"mpu6000" , INV_MPU6000}, |
70 | {"mpu6500" , INV_MPU6500}, |
71 | {"mpu6515" , INV_MPU6515}, |
72 | {"mpu6880" , INV_MPU6880}, |
73 | {"mpu9250" , INV_MPU9250}, |
74 | {"mpu9255" , INV_MPU9255}, |
75 | {"icm20608" , INV_ICM20608}, |
76 | {"icm20608d" , INV_ICM20608D}, |
77 | {"icm20609" , INV_ICM20609}, |
78 | {"icm20689" , INV_ICM20689}, |
79 | {"icm20600" , INV_ICM20600}, |
80 | {"icm20602" , INV_ICM20602}, |
81 | {"icm20690" , INV_ICM20690}, |
82 | {"iam20680" , INV_IAM20680}, |
83 | {} |
84 | }; |
85 | |
86 | MODULE_DEVICE_TABLE(spi, inv_mpu_id); |
87 | |
88 | static const struct of_device_id inv_of_match[] = { |
89 | { |
90 | .compatible = "invensense,mpu6000" , |
91 | .data = (void *)INV_MPU6000 |
92 | }, |
93 | { |
94 | .compatible = "invensense,mpu6500" , |
95 | .data = (void *)INV_MPU6500 |
96 | }, |
97 | { |
98 | .compatible = "invensense,mpu6515" , |
99 | .data = (void *)INV_MPU6515 |
100 | }, |
101 | { |
102 | .compatible = "invensense,mpu6880" , |
103 | .data = (void *)INV_MPU6880 |
104 | }, |
105 | { |
106 | .compatible = "invensense,mpu9250" , |
107 | .data = (void *)INV_MPU9250 |
108 | }, |
109 | { |
110 | .compatible = "invensense,mpu9255" , |
111 | .data = (void *)INV_MPU9255 |
112 | }, |
113 | { |
114 | .compatible = "invensense,icm20608" , |
115 | .data = (void *)INV_ICM20608 |
116 | }, |
117 | { |
118 | .compatible = "invensense,icm20608d" , |
119 | .data = (void *)INV_ICM20608D |
120 | }, |
121 | { |
122 | .compatible = "invensense,icm20609" , |
123 | .data = (void *)INV_ICM20609 |
124 | }, |
125 | { |
126 | .compatible = "invensense,icm20689" , |
127 | .data = (void *)INV_ICM20689 |
128 | }, |
129 | { |
130 | .compatible = "invensense,icm20600" , |
131 | .data = (void *)INV_ICM20600 |
132 | }, |
133 | { |
134 | .compatible = "invensense,icm20602" , |
135 | .data = (void *)INV_ICM20602 |
136 | }, |
137 | { |
138 | .compatible = "invensense,icm20690" , |
139 | .data = (void *)INV_ICM20690 |
140 | }, |
141 | { |
142 | .compatible = "invensense,iam20680" , |
143 | .data = (void *)INV_IAM20680 |
144 | }, |
145 | { } |
146 | }; |
147 | MODULE_DEVICE_TABLE(of, inv_of_match); |
148 | |
149 | static const struct acpi_device_id inv_acpi_match[] = { |
150 | {"INVN6000" , INV_MPU6000}, |
151 | { }, |
152 | }; |
153 | MODULE_DEVICE_TABLE(acpi, inv_acpi_match); |
154 | |
155 | static struct spi_driver inv_mpu_driver = { |
156 | .probe = inv_mpu_probe, |
157 | .id_table = inv_mpu_id, |
158 | .driver = { |
159 | .of_match_table = inv_of_match, |
160 | .acpi_match_table = inv_acpi_match, |
161 | .name = "inv-mpu6000-spi" , |
162 | .pm = pm_ptr(&inv_mpu_pmops), |
163 | }, |
164 | }; |
165 | |
166 | module_spi_driver(inv_mpu_driver); |
167 | |
168 | MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>" ); |
169 | MODULE_DESCRIPTION("Invensense device MPU6000 driver" ); |
170 | MODULE_LICENSE("GPL" ); |
171 | MODULE_IMPORT_NS(IIO_MPU6050); |
172 | |