Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio:accel:bmc150-accel: Use the chip ID to detect sensor variant

Instead of using the I2C or ACPI ID to determine which variant of
the chipset to use, determine that from the chip ID.

Under Windows, the same driver is used for those variants and, despite
incorrect ACPI data, it is able to load and operate the accelerometer.

Fixes the accelerometer failing with:
bmc150_accel i2c-BMA250E:00: Invalid chip f8
on the WinBook TW100

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Bastien Nocera and committed by
Jonathan Cameron
0ad4bf37 c4eaab79

+19 -27
+19 -27
drivers/iio/accel/bmc150-accel.c
··· 151 151 }; 152 152 153 153 struct bmc150_accel_chip_info { 154 + const char *name; 154 155 u8 chip_id; 155 156 const struct iio_chan_spec *channels; 156 157 int num_channels; ··· 1063 1062 1064 1063 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = { 1065 1064 [bmc150] = { 1065 + .name = "BMC150A", 1066 1066 .chip_id = 0xFA, 1067 1067 .channels = bmc150_accel_channels, 1068 1068 .num_channels = ARRAY_SIZE(bmc150_accel_channels), ··· 1073 1071 {76590, BMC150_ACCEL_DEF_RANGE_16G} }, 1074 1072 }, 1075 1073 [bmi055] = { 1074 + .name = "BMI055A", 1076 1075 .chip_id = 0xFA, 1077 1076 .channels = bmc150_accel_channels, 1078 1077 .num_channels = ARRAY_SIZE(bmc150_accel_channels), ··· 1083 1080 {76590, BMC150_ACCEL_DEF_RANGE_16G} }, 1084 1081 }, 1085 1082 [bma255] = { 1083 + .name = "BMA0255", 1086 1084 .chip_id = 0xFA, 1087 1085 .channels = bmc150_accel_channels, 1088 1086 .num_channels = ARRAY_SIZE(bmc150_accel_channels), ··· 1093 1089 {76590, BMC150_ACCEL_DEF_RANGE_16G} }, 1094 1090 }, 1095 1091 [bma250e] = { 1092 + .name = "BMA250E", 1096 1093 .chip_id = 0xF9, 1097 1094 .channels = bma250e_accel_channels, 1098 1095 .num_channels = ARRAY_SIZE(bma250e_accel_channels), ··· 1103 1098 {306457, BMC150_ACCEL_DEF_RANGE_16G} }, 1104 1099 }, 1105 1100 [bma222e] = { 1101 + .name = "BMA222E", 1106 1102 .chip_id = 0xF8, 1107 1103 .channels = bma222e_accel_channels, 1108 1104 .num_channels = ARRAY_SIZE(bma222e_accel_channels), ··· 1113 1107 {1225831, BMC150_ACCEL_DEF_RANGE_16G} }, 1114 1108 }, 1115 1109 [bma280] = { 1110 + .name = "BMA0280", 1116 1111 .chip_id = 0xFB, 1117 1112 .channels = bma280_accel_channels, 1118 1113 .num_channels = ARRAY_SIZE(bma280_accel_channels), ··· 1360 1353 return IRQ_NONE; 1361 1354 } 1362 1355 1363 - static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data) 1364 - { 1365 - const struct acpi_device_id *id; 1366 - 1367 - id = acpi_match_device(dev->driver->acpi_match_table, dev); 1368 - 1369 - if (!id) 1370 - return NULL; 1371 - 1372 - *data = (int)id->driver_data; 1373 - 1374 - return dev_name(dev); 1375 - } 1376 - 1377 1356 static int bmc150_accel_gpio_probe(struct i2c_client *client, 1378 1357 struct bmc150_accel_data *data) 1379 1358 { ··· 1556 1563 1557 1564 static int bmc150_accel_chip_init(struct bmc150_accel_data *data) 1558 1565 { 1559 - int ret; 1566 + int ret, i; 1560 1567 1561 1568 ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID); 1562 1569 if (ret < 0) { ··· 1565 1572 } 1566 1573 1567 1574 dev_dbg(&data->client->dev, "Chip Id %x\n", ret); 1568 - if (ret != data->chip_info->chip_id) { 1569 - dev_err(&data->client->dev, "Invalid chip %x\n", ret); 1575 + for (i = 0; i < ARRAY_SIZE(bmc150_accel_chip_info_tbl); i++) { 1576 + if (bmc150_accel_chip_info_tbl[i].chip_id == ret) { 1577 + data->chip_info = &bmc150_accel_chip_info_tbl[i]; 1578 + break; 1579 + } 1580 + } 1581 + 1582 + if (!data->chip_info) { 1583 + dev_err(&data->client->dev, "Unsupported chip %x\n", ret); 1570 1584 return -ENODEV; 1571 1585 } 1572 1586 ··· 1625 1625 struct iio_dev *indio_dev; 1626 1626 int ret; 1627 1627 const char *name = NULL; 1628 - int chip_id = 0; 1629 1628 1630 1629 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 1631 1630 if (!indio_dev) ··· 1634 1635 i2c_set_clientdata(client, indio_dev); 1635 1636 data->client = client; 1636 1637 1637 - if (id) { 1638 + if (id) 1638 1639 name = id->name; 1639 - chip_id = id->driver_data; 1640 - } 1641 - 1642 - if (ACPI_HANDLE(&client->dev)) 1643 - name = bmc150_accel_match_acpi_device(&client->dev, &chip_id); 1644 - 1645 - data->chip_info = &bmc150_accel_chip_info_tbl[chip_id]; 1646 1640 1647 1641 ret = bmc150_accel_chip_init(data); 1648 1642 if (ret < 0) ··· 1646 1654 indio_dev->dev.parent = &client->dev; 1647 1655 indio_dev->channels = data->chip_info->channels; 1648 1656 indio_dev->num_channels = data->chip_info->num_channels; 1649 - indio_dev->name = name; 1657 + indio_dev->name = name ? name : data->chip_info->name; 1650 1658 indio_dev->modes = INDIO_DIRECT_MODE; 1651 1659 indio_dev->info = &bmc150_accel_info; 1652 1660