iio: imu: inv_mpu6050: disable i2c mux for MPU925x

Disable i2c mux for supported 9xxx chips. This is a
pre-requesite for controling 9xxx magnetometer using the
i2c master of the chip.

Check in device-tree that there is no i2c-gate device declared
for ensuring backward compatibility with existing setups.

Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Jean-Baptiste Maneyrol 2019-09-16 09:41:58 +00:00 committed by Jonathan Cameron
parent 348eb0b2c4
commit ca4a649694
3 changed files with 58 additions and 11 deletions

View File

@ -1156,9 +1156,6 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
return result;
}
if (inv_mpu_bus_setup)
inv_mpu_bus_setup(indio_dev);
dev_set_drvdata(dev, indio_dev);
indio_dev->dev.parent = dev;
/* name will be NULL when enumerated via ACPI */
@ -1167,6 +1164,10 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
else
indio_dev->name = dev_name(dev);
/* requires parent device set in indio_dev */
if (inv_mpu_bus_setup)
inv_mpu_bus_setup(indio_dev);
if (chip_type == INV_ICM20602) {
indio_dev->channels = inv_icm20602_channels;
indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels);

View File

@ -68,6 +68,56 @@ static const char *inv_mpu_match_acpi_device(struct device *dev,
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_ICM20602:
/* no i2c auxiliary bus on the chip */
return false;
case INV_MPU9250:
case INV_MPU9255:
if (st->magn_disabled)
return true;
else
return false;
default:
return true;
}
}
/*
* 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)
{
struct inv_mpu6050_state *st = iio_priv(indio_dev);
struct device *dev = indio_dev->dev.parent;
struct device_node *mux_node;
switch (st->chip_type) {
case INV_MPU9250:
case INV_MPU9255:
mux_node = of_get_child_by_name(dev->of_node, "i2c-gate");
if (mux_node != NULL) {
st->magn_disabled = true;
dev_warn(dev, "disable internal use of magnetometer\n");
}
of_node_put(mux_node);
break;
default:
break;
}
return 0;
}
/**
* inv_mpu_probe() - probe function.
* @client: i2c client.
@ -112,17 +162,12 @@ static int inv_mpu_probe(struct i2c_client *client,
}
result = inv_mpu_core_probe(regmap, client->irq, name,
NULL, chip_type);
inv_mpu_magn_disable, chip_type);
if (result < 0)
return result;
st = iio_priv(dev_get_drvdata(&client->dev));
switch (st->chip_type) {
case INV_ICM20608:
case INV_ICM20602:
/* no i2c auxiliary bus on the chip */
break;
default:
if (inv_mpu_i2c_aux_bus(&client->dev)) {
/* declare i2c auxiliary bus */
st->muxc = i2c_mux_alloc(client->adapter, &client->dev,
1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
@ -137,7 +182,6 @@ static int inv_mpu_probe(struct i2c_client *client,
result = inv_mpu_acpi_create_mux_client(client);
if (result)
goto out_del_mux;
break;
}
return 0;

View File

@ -125,6 +125,7 @@ struct inv_mpu6050_hw {
* @it_timestamp: timestamp from previous interrupt.
* @data_timestamp: timestamp for next data sample.
* @vddio_supply voltage regulator for the chip.
* @magn_disabled: magnetometer disabled for backward compatibility reason.
*/
struct inv_mpu6050_state {
struct mutex lock;
@ -146,6 +147,7 @@ struct inv_mpu6050_state {
s64 it_timestamp;
s64 data_timestamp;
struct regulator *vddio_supply;
bool magn_disabled;
};
/*register and associated bit definition*/