]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
iio: imu: bmi270: Add support for BMI260
authorJustin Weiss <justin@justinweiss.com>
Sun, 27 Oct 2024 17:20:25 +0000 (10:20 -0700)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Fri, 1 Nov 2024 14:54:47 +0000 (14:54 +0000)
Adds support for the Bosch BMI260 6-axis IMU to the Bosch BMI270
driver. Setup and operation is nearly identical to the Bosch BMI270,
but has a different chip ID and requires different firmware.

Firmware is requested and loaded from userspace.

Adds ACPI ID BMI0160, used by several devices including the GPD Win
Mini, Aya Neo AIR Pro, and OXP Mini Pro.

GPD Win Mini:

Device (BMI2)
{
    Name (_ADR, Zero)  // _ADR: Address
    Name (_HID, "BMI0160")  // _HID: Hardware ID
    Name (_CID, "BMI0160")  // _CID: Compatible ID
    Name (_DDN, "Accelerometer")  // _DDN: DOS Device Name
    Name (_UID, One)  // _UID: Unique ID
    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
    {
        Name (RBUF, ResourceTemplate ()
        {
            I2cSerialBusV2 (0x0068, ControllerInitiated, 0x00061A80,
                AddressingMode7Bit, "\\_SB.I2CB",
                0x00, ResourceConsumer, , Exclusive,
                )
            GpioInt (Edge, ActiveLow, Exclusive, PullDefault, 0x0000,
                "\\_SB.GPIO", 0x00, ResourceConsumer, ,
                )
                {   // Pin list
                    0x008B
                }
        })
        Return (RBUF) /* \_SB_.I2CB.BMI2._CRS.RBUF */
    }
    ...
}

Signed-off-by: Justin Weiss <justin@justinweiss.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20241027172029.160134-5-justin@justinweiss.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/imu/bmi270/bmi270.h
drivers/iio/imu/bmi270/bmi270_core.c
drivers/iio/imu/bmi270/bmi270_i2c.c
drivers/iio/imu/bmi270/bmi270_spi.c

index 6173be929bac265606757106d7a79122cfdd8ca0..fdfad5784cc52043475b6816286619fac5824684 100644 (file)
@@ -29,6 +29,7 @@ struct bmi270_chip_info {
 };
 
 extern const struct regmap_config bmi270_regmap_config;
+extern const struct bmi270_chip_info bmi260_chip_info;
 extern const struct bmi270_chip_info bmi270_chip_info;
 
 int bmi270_core_probe(struct device *dev, struct regmap *regmap,
index 601178a2d0b6f8251363a7f7deab7ba9e666156c..70db83a202391dbc2303b25017d86427211360ef 100644 (file)
 #include "bmi270.h"
 
 #define BMI270_CHIP_ID_REG                             0x00
+
+/* Checked to prevent sending incompatible firmware to BMI160 devices */
+#define BMI160_CHIP_ID_VAL                             0xD1
+
+#define BMI260_CHIP_ID_VAL                             0x27
 #define BMI270_CHIP_ID_VAL                             0x24
 #define BMI270_CHIP_ID_MSK                             GENMASK(7, 0)
 
@@ -64,6 +69,7 @@
 #define BMI270_PWR_CTRL_ACCEL_EN_MSK                   BIT(2)
 #define BMI270_PWR_CTRL_TEMP_EN_MSK                    BIT(3)
 
+#define BMI260_INIT_DATA_FILE "bmi260-init-data.fw"
 #define BMI270_INIT_DATA_FILE "bmi270-init-data.fw"
 
 enum bmi270_scan {
@@ -86,6 +92,13 @@ static const unsigned long bmi270_avail_scan_masks[] = {
        0
 };
 
+const struct bmi270_chip_info bmi260_chip_info = {
+       .name = "bmi260",
+       .chip_id = BMI260_CHIP_ID_VAL,
+       .fw_name = BMI260_INIT_DATA_FILE,
+};
+EXPORT_SYMBOL_NS_GPL(bmi260_chip_info, IIO_BMI270);
+
 const struct bmi270_chip_info bmi270_chip_info = {
        .name = "bmi270",
        .chip_id = BMI270_CHIP_ID_VAL,
@@ -545,8 +558,21 @@ static int bmi270_validate_chip_id(struct bmi270_data *bmi270_device)
        if (ret)
                return dev_err_probe(dev, ret, "Failed to read chip id");
 
+       /*
+        * Some manufacturers use "BMI0160" for both the BMI160 and
+        * BMI260. If the device is actually a BMI160, the bmi160
+        * driver should handle it and this driver should not.
+        */
+       if (chip_id == BMI160_CHIP_ID_VAL)
+               return -ENODEV;
+
        if (chip_id != bmi270_device->chip_info->chip_id)
-               dev_info(dev, "Unknown chip id 0x%x", chip_id);
+               dev_info(dev, "Unexpected chip id 0x%x", chip_id);
+
+       if (chip_id == bmi260_chip_info.chip_id)
+               bmi270_device->chip_info = &bmi260_chip_info;
+       else if (chip_id == bmi270_chip_info.chip_id)
+               bmi270_device->chip_info = &bmi270_chip_info;
 
        return 0;
 }
index 394f279960593e877fdd316eab96ff1f85045eef..6bd82e4362ab1980cdfe1aae69290bd400de78a4 100644 (file)
@@ -32,11 +32,19 @@ static int bmi270_i2c_probe(struct i2c_client *client)
 }
 
 static const struct i2c_device_id bmi270_i2c_id[] = {
+       { "bmi260", (kernel_ulong_t)&bmi260_chip_info },
        { "bmi270", (kernel_ulong_t)&bmi270_chip_info },
        { }
 };
 
+static const struct acpi_device_id bmi270_acpi_match[] = {
+       /* GPD Win Mini, Aya Neo AIR Pro, OXP Mini Pro, etc. */
+       { "BMI0160",  (kernel_ulong_t)&bmi260_chip_info },
+       { }
+};
+
 static const struct of_device_id bmi270_of_match[] = {
+       { .compatible = "bosch,bmi260", .data = &bmi260_chip_info },
        { .compatible = "bosch,bmi270", .data = &bmi270_chip_info },
        { }
 };
@@ -44,6 +52,7 @@ static const struct of_device_id bmi270_of_match[] = {
 static struct i2c_driver bmi270_i2c_driver = {
        .driver = {
                .name = "bmi270_i2c",
+               .acpi_match_table = bmi270_acpi_match,
                .of_match_table = bmi270_of_match,
        },
        .probe = bmi270_i2c_probe,
index 7c2062c660d934101f933467e1ad7ccf676740d3..30b6d13a329c28be2bb68faad68a044d9e90bb7b 100644 (file)
@@ -65,11 +65,13 @@ static int bmi270_spi_probe(struct spi_device *spi)
 }
 
 static const struct spi_device_id bmi270_spi_id[] = {
+       { "bmi260", (kernel_ulong_t)&bmi260_chip_info },
        { "bmi270", (kernel_ulong_t)&bmi270_chip_info },
        { }
 };
 
 static const struct of_device_id bmi270_of_match[] = {
+       { .compatible = "bosch,bmi260", .data = &bmi260_chip_info },
        { .compatible = "bosch,bmi270", .data = &bmi270_chip_info },
        { }
 };