diff options
Diffstat (limited to 'drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c')
-rw-r--r-- | drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 111 |
1 files changed, 47 insertions, 64 deletions
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index f47a28b4be23..6993d3b87bb0 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -10,6 +10,7 @@ #include <linux/iio/iio.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/property.h> #include "inv_mpu_iio.h" static const struct regmap_config inv_mpu_regmap_config = { @@ -19,62 +20,19 @@ static const struct regmap_config inv_mpu_regmap_config = { static int inv_mpu6050_select_bypass(struct i2c_mux_core *muxc, u32 chan_id) { - struct iio_dev *indio_dev = i2c_mux_priv(muxc); - struct inv_mpu6050_state *st = iio_priv(indio_dev); - int ret; - - mutex_lock(&st->lock); - - ret = inv_mpu6050_set_power_itg(st, true); - if (ret) - goto error_unlock; - - ret = regmap_write(st->map, st->reg->int_pin_cfg, - st->irq_mask | INV_MPU6050_BIT_BYPASS_EN); - -error_unlock: - mutex_unlock(&st->lock); - - return ret; -} - -static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id) -{ - struct iio_dev *indio_dev = i2c_mux_priv(muxc); - struct inv_mpu6050_state *st = iio_priv(indio_dev); - - mutex_lock(&st->lock); - - /* It doesn't really matter if any of the calls fail */ - regmap_write(st->map, st->reg->int_pin_cfg, st->irq_mask); - inv_mpu6050_set_power_itg(st, false); - - mutex_unlock(&st->lock); - return 0; } -static const char *inv_mpu_match_acpi_device(struct device *dev, - enum inv_devices *chip_id) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - *chip_id = (int)id->driver_data; - - return dev_name(dev); -} - static bool inv_mpu_i2c_aux_bus(struct device *dev) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev)); switch (st->chip_type) { case INV_ICM20608: + case INV_ICM20609: + case INV_ICM20689: case INV_ICM20602: + case INV_IAM20680: /* no i2c auxiliary bus on the chip */ return false; case INV_MPU9150: @@ -89,19 +47,20 @@ static bool inv_mpu_i2c_aux_bus(struct device *dev) } } -/* - * MPU9xxx magnetometer support requires to disable i2c auxiliary bus support. - * To ensure backward compatibility with existing setups, do not disable - * i2c auxiliary bus if it used. - * Check for i2c-gate node in devicetree and set magnetometer disabled. - * Only MPU6500 is supported by ACPI, no need to check. - */ -static int inv_mpu_magn_disable(struct iio_dev *indio_dev) +static int inv_mpu_i2c_aux_setup(struct iio_dev *indio_dev) { struct inv_mpu6050_state *st = iio_priv(indio_dev); struct device *dev = indio_dev->dev.parent; struct device_node *mux_node; + int ret; + /* + * MPU9xxx magnetometer support requires to disable i2c auxiliary bus. + * To ensure backward compatibility with existing setups, do not disable + * i2c auxiliary bus if it used. + * Check for i2c-gate node in devicetree and set magnetometer disabled. + * Only MPU6500 is supported by ACPI, no need to check. + */ switch (st->chip_type) { case INV_MPU9150: case INV_MPU9250: @@ -117,6 +76,14 @@ static int inv_mpu_magn_disable(struct iio_dev *indio_dev) break; } + /* enable i2c bypass when using i2c auxiliary bus */ + if (inv_mpu_i2c_aux_bus(dev)) { + ret = regmap_write(st->map, st->reg->int_pin_cfg, + st->irq_mask | INV_MPU6050_BIT_BYPASS_EN); + if (ret) + return ret; + } + return 0; } @@ -130,6 +97,7 @@ static int inv_mpu_magn_disable(struct iio_dev *indio_dev) static int inv_mpu_probe(struct i2c_client *client, const struct i2c_device_id *id) { + const void *match; struct inv_mpu6050_state *st; int result; enum inv_devices chip_type; @@ -140,18 +108,14 @@ static int inv_mpu_probe(struct i2c_client *client, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EOPNOTSUPP; - if (client->dev.of_node) { - chip_type = (enum inv_devices) - of_device_get_match_data(&client->dev); + match = device_get_match_data(&client->dev); + if (match) { + chip_type = (enum inv_devices)match; name = client->name; } else if (id) { chip_type = (enum inv_devices) id->driver_data; name = id->name; - } else if (ACPI_HANDLE(&client->dev)) { - name = inv_mpu_match_acpi_device(&client->dev, &chip_type); - if (!name) - return -ENODEV; } else { return -ENOSYS; } @@ -164,7 +128,7 @@ static int inv_mpu_probe(struct i2c_client *client, } result = inv_mpu_core_probe(regmap, client->irq, name, - inv_mpu_magn_disable, chip_type); + inv_mpu_i2c_aux_setup, chip_type); if (result < 0) return result; @@ -173,8 +137,7 @@ static int inv_mpu_probe(struct i2c_client *client, /* declare i2c auxiliary bus */ st->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE, - inv_mpu6050_select_bypass, - inv_mpu6050_deselect_bypass); + inv_mpu6050_select_bypass, NULL); if (!st->muxc) return -ENOMEM; st->muxc->priv = dev_get_drvdata(&client->dev); @@ -218,7 +181,11 @@ static const struct i2c_device_id inv_mpu_id[] = { {"mpu9250", INV_MPU9250}, {"mpu9255", INV_MPU9255}, {"icm20608", INV_ICM20608}, + {"icm20609", INV_ICM20609}, + {"icm20689", INV_ICM20689}, {"icm20602", INV_ICM20602}, + {"icm20690", INV_ICM20690}, + {"iam20680", INV_IAM20680}, {} }; @@ -254,9 +221,25 @@ static const struct of_device_id inv_of_match[] = { .data = (void *)INV_ICM20608 }, { + .compatible = "invensense,icm20609", + .data = (void *)INV_ICM20609 + }, + { + .compatible = "invensense,icm20689", + .data = (void *)INV_ICM20689 + }, + { .compatible = "invensense,icm20602", .data = (void *)INV_ICM20602 }, + { + .compatible = "invensense,icm20690", + .data = (void *)INV_ICM20690 + }, + { + .compatible = "invensense,iam20680", + .data = (void *)INV_IAM20680 + }, { } }; MODULE_DEVICE_TABLE(of, inv_of_match); |