forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Invensense, Inc.
3
-*
4
-* This software is licensed under the terms of the GNU General Public
5
-* License version 2, as published by the Free Software Foundation, and
6
-* may be copied, distributed, and modified under those terms.
7
-*
8
-* This program is distributed in the hope that it will be useful,
9
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
-* GNU General Public License for more details.
124 */
135
146 #include <linux/acpi.h>
....@@ -18,6 +10,7 @@
1810 #include <linux/iio/iio.h>
1911 #include <linux/module.h>
2012 #include <linux/of_device.h>
13
+#include <linux/property.h>
2114 #include "inv_mpu_iio.h"
2215
2316 static const struct regmap_config inv_mpu_regmap_config = {
....@@ -27,53 +20,71 @@
2720
2821 static int inv_mpu6050_select_bypass(struct i2c_mux_core *muxc, u32 chan_id)
2922 {
30
- struct iio_dev *indio_dev = i2c_mux_priv(muxc);
31
- struct inv_mpu6050_state *st = iio_priv(indio_dev);
32
- int ret;
33
-
34
- mutex_lock(&st->lock);
35
-
36
- ret = inv_mpu6050_set_power_itg(st, true);
37
- if (ret)
38
- goto error_unlock;
39
-
40
- ret = regmap_write(st->map, st->reg->int_pin_cfg,
41
- st->irq_mask | INV_MPU6050_BIT_BYPASS_EN);
42
-
43
-error_unlock:
44
- mutex_unlock(&st->lock);
45
-
46
- return ret;
47
-}
48
-
49
-static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id)
50
-{
51
- struct iio_dev *indio_dev = i2c_mux_priv(muxc);
52
- struct inv_mpu6050_state *st = iio_priv(indio_dev);
53
-
54
- mutex_lock(&st->lock);
55
-
56
- /* It doesn't really matter if any of the calls fail */
57
- regmap_write(st->map, st->reg->int_pin_cfg, st->irq_mask);
58
- inv_mpu6050_set_power_itg(st, false);
59
-
60
- mutex_unlock(&st->lock);
61
-
6223 return 0;
6324 }
6425
65
-static const char *inv_mpu_match_acpi_device(struct device *dev,
66
- enum inv_devices *chip_id)
26
+static bool inv_mpu_i2c_aux_bus(struct device *dev)
6727 {
68
- const struct acpi_device_id *id;
28
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev));
6929
70
- id = acpi_match_device(dev->driver->acpi_match_table, dev);
71
- if (!id)
72
- return NULL;
30
+ switch (st->chip_type) {
31
+ case INV_ICM20608:
32
+ case INV_ICM20609:
33
+ case INV_ICM20689:
34
+ case INV_ICM20602:
35
+ case INV_IAM20680:
36
+ /* no i2c auxiliary bus on the chip */
37
+ return false;
38
+ case INV_MPU9150:
39
+ case INV_MPU9250:
40
+ case INV_MPU9255:
41
+ if (st->magn_disabled)
42
+ return true;
43
+ else
44
+ return false;
45
+ default:
46
+ return true;
47
+ }
48
+}
7349
74
- *chip_id = (int)id->driver_data;
50
+static int inv_mpu_i2c_aux_setup(struct iio_dev *indio_dev)
51
+{
52
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
53
+ struct device *dev = indio_dev->dev.parent;
54
+ struct device_node *mux_node;
55
+ int ret;
7556
76
- return dev_name(dev);
57
+ /*
58
+ * MPU9xxx magnetometer support requires to disable i2c auxiliary bus.
59
+ * To ensure backward compatibility with existing setups, do not disable
60
+ * i2c auxiliary bus if it used.
61
+ * Check for i2c-gate node in devicetree and set magnetometer disabled.
62
+ * Only MPU6500 is supported by ACPI, no need to check.
63
+ */
64
+ switch (st->chip_type) {
65
+ case INV_MPU9150:
66
+ case INV_MPU9250:
67
+ case INV_MPU9255:
68
+ mux_node = of_get_child_by_name(dev->of_node, "i2c-gate");
69
+ if (mux_node != NULL) {
70
+ st->magn_disabled = true;
71
+ dev_warn(dev, "disable internal use of magnetometer\n");
72
+ }
73
+ of_node_put(mux_node);
74
+ break;
75
+ default:
76
+ break;
77
+ }
78
+
79
+ /* enable i2c bypass when using i2c auxiliary bus */
80
+ if (inv_mpu_i2c_aux_bus(dev)) {
81
+ ret = regmap_write(st->map, st->reg->int_pin_cfg,
82
+ st->irq_mask | INV_MPU6050_BIT_BYPASS_EN);
83
+ if (ret)
84
+ return ret;
85
+ }
86
+
87
+ return 0;
7788 }
7889
7990 /**
....@@ -86,6 +97,7 @@
8697 static int inv_mpu_probe(struct i2c_client *client,
8798 const struct i2c_device_id *id)
8899 {
100
+ const void *match;
89101 struct inv_mpu6050_state *st;
90102 int result;
91103 enum inv_devices chip_type;
....@@ -96,46 +108,36 @@
96108 I2C_FUNC_SMBUS_I2C_BLOCK))
97109 return -EOPNOTSUPP;
98110
99
- if (client->dev.of_node) {
100
- chip_type = (enum inv_devices)
101
- of_device_get_match_data(&client->dev);
111
+ match = device_get_match_data(&client->dev);
112
+ if (match) {
113
+ chip_type = (enum inv_devices)match;
102114 name = client->name;
103115 } else if (id) {
104116 chip_type = (enum inv_devices)
105117 id->driver_data;
106118 name = id->name;
107
- } else if (ACPI_HANDLE(&client->dev)) {
108
- name = inv_mpu_match_acpi_device(&client->dev, &chip_type);
109
- if (!name)
110
- return -ENODEV;
111119 } else {
112120 return -ENOSYS;
113121 }
114122
115123 regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
116124 if (IS_ERR(regmap)) {
117
- dev_err(&client->dev, "Failed to register i2c regmap %d\n",
118
- (int)PTR_ERR(regmap));
125
+ dev_err(&client->dev, "Failed to register i2c regmap: %pe\n",
126
+ regmap);
119127 return PTR_ERR(regmap);
120128 }
121129
122130 result = inv_mpu_core_probe(regmap, client->irq, name,
123
- NULL, chip_type);
131
+ inv_mpu_i2c_aux_setup, chip_type);
124132 if (result < 0)
125133 return result;
126134
127135 st = iio_priv(dev_get_drvdata(&client->dev));
128
- switch (st->chip_type) {
129
- case INV_ICM20608:
130
- case INV_ICM20602:
131
- /* no i2c auxiliary bus on the chip */
132
- break;
133
- default:
136
+ if (inv_mpu_i2c_aux_bus(&client->dev)) {
134137 /* declare i2c auxiliary bus */
135138 st->muxc = i2c_mux_alloc(client->adapter, &client->dev,
136139 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
137
- inv_mpu6050_select_bypass,
138
- inv_mpu6050_deselect_bypass);
140
+ inv_mpu6050_select_bypass, NULL);
139141 if (!st->muxc)
140142 return -ENOMEM;
141143 st->muxc->priv = dev_get_drvdata(&client->dev);
....@@ -145,7 +147,6 @@
145147 result = inv_mpu_acpi_create_mux_client(client);
146148 if (result)
147149 goto out_del_mux;
148
- break;
149150 }
150151
151152 return 0;
....@@ -180,7 +181,11 @@
180181 {"mpu9250", INV_MPU9250},
181182 {"mpu9255", INV_MPU9255},
182183 {"icm20608", INV_ICM20608},
184
+ {"icm20609", INV_ICM20609},
185
+ {"icm20689", INV_ICM20689},
183186 {"icm20602", INV_ICM20602},
187
+ {"icm20690", INV_ICM20690},
188
+ {"iam20680", INV_IAM20680},
184189 {}
185190 };
186191
....@@ -216,9 +221,25 @@
216221 .data = (void *)INV_ICM20608
217222 },
218223 {
224
+ .compatible = "invensense,icm20609",
225
+ .data = (void *)INV_ICM20609
226
+ },
227
+ {
228
+ .compatible = "invensense,icm20689",
229
+ .data = (void *)INV_ICM20689
230
+ },
231
+ {
219232 .compatible = "invensense,icm20602",
220233 .data = (void *)INV_ICM20602
221234 },
235
+ {
236
+ .compatible = "invensense,icm20690",
237
+ .data = (void *)INV_ICM20690
238
+ },
239
+ {
240
+ .compatible = "invensense,iam20680",
241
+ .data = (void *)INV_IAM20680
242
+ },
222243 { }
223244 };
224245 MODULE_DEVICE_TABLE(of, inv_of_match);