iio: mcp9600: Recognize chip id for mcp9601

The current driver works with mcp9601, but emits a warning because it
does not recognize the chip id.

MCP9601 is a superset of MCP9600. The drivers works without changes
on this chipset.

However, the 9601 chip supports open/closed-circuit detection if wired
properly, so we'll need to be able to differentiate between them.

Moved "struct mcp9600_data" up in the file since a later patch will
need it and chip_info before the declarations.

Signed-off-by: Ben Collins <bcollins@watter.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250822-upstream-changes-v8-4-40bb1739e3e2@watter.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Ben Collins 2025-08-22 09:23:53 -04:00 committed by Jonathan Cameron
parent 74cae3eb72
commit 5efd60c974
2 changed files with 57 additions and 19 deletions

View file

@ -173,11 +173,13 @@ config MAX31865
will be called max31865.
config MCP9600
tristate "MCP9600 thermocouple EMF converter"
tristate "MCP9600 and similar thermocouple EMF converters"
depends on I2C
help
If you say yes here you get support for MCP9600
thermocouple EMF converter connected via I2C.
If you say yes here you get support for...
- MCP9600
- MCP9601
...thermocouple EMF converters connected via I2C.
This driver can also be built as a module. If so, the module
will be called mcp9600.

View file

@ -42,6 +42,7 @@
/* MCP9600 device id value */
#define MCP9600_DEVICE_ID_MCP9600 0x40
#define MCP9600_DEVICE_ID_MCP9601 0x41
#define MCP9600_ALERT_COUNT 4
@ -82,6 +83,15 @@ static const struct iio_event_spec mcp9600_events[] = {
},
};
struct mcp_chip_info {
u8 chip_id;
const char *chip_name;
};
struct mcp9600_data {
struct i2c_client *client;
};
#define MCP9600_CHANNELS(hj_num_ev, hj_ev_spec_off, cj_num_ev, cj_ev_spec_off) \
{ \
{ \
@ -123,10 +133,6 @@ static const struct iio_chan_spec mcp9600_channels[][2] = {
MCP9600_CHANNELS(2, 0, 2, 0), /* Alerts: 1 2 3 4 */
};
struct mcp9600_data {
struct i2c_client *client;
};
static int mcp9600_read(struct mcp9600_data *data,
struct iio_chan_spec const *chan, int *val)
{
@ -416,18 +422,36 @@ static int mcp9600_probe_alerts(struct iio_dev *indio_dev)
static int mcp9600_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
const struct mcp_chip_info *chip_info;
struct iio_dev *indio_dev;
struct mcp9600_data *data;
int ret, ch_sel;
int ch_sel, dev_id;
ret = i2c_smbus_read_byte_data(client, MCP9600_DEVICE_ID);
if (ret < 0)
return dev_err_probe(&client->dev, ret, "Failed to read device ID\n");
if (ret != MCP9600_DEVICE_ID_MCP9600)
dev_warn(&client->dev, "Expected ID %x, got %x\n",
MCP9600_DEVICE_ID_MCP9600, ret);
chip_info = i2c_get_match_data(client);
if (!chip_info)
return dev_err_probe(dev, -ENODEV,
"No chip-info found for device\n");
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
dev_id = i2c_smbus_read_byte_data(client, MCP9600_DEVICE_ID);
if (dev_id < 0)
return dev_err_probe(dev, dev_id, "Failed to read device ID\n");
switch (dev_id) {
case MCP9600_DEVICE_ID_MCP9600:
case MCP9600_DEVICE_ID_MCP9601:
if (dev_id != chip_info->chip_id)
dev_warn(dev,
"Expected id %02x, but device responded with %02x\n",
chip_info->chip_id, dev_id);
break;
default:
dev_warn(dev, "Unknown id %x, using %x\n", dev_id,
chip_info->chip_id);
}
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@ -439,22 +463,34 @@ static int mcp9600_probe(struct i2c_client *client)
return ch_sel;
indio_dev->info = &mcp9600_info;
indio_dev->name = "mcp9600";
indio_dev->name = chip_info->chip_name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = mcp9600_channels[ch_sel];
indio_dev->num_channels = ARRAY_SIZE(mcp9600_channels[ch_sel]);
return devm_iio_device_register(&client->dev, indio_dev);
return devm_iio_device_register(dev, indio_dev);
}
static const struct mcp_chip_info mcp9600_chip_info = {
.chip_id = MCP9600_DEVICE_ID_MCP9600,
.chip_name = "mcp9600",
};
static const struct mcp_chip_info mcp9601_chip_info = {
.chip_id = MCP9600_DEVICE_ID_MCP9601,
.chip_name = "mcp9601",
};
static const struct i2c_device_id mcp9600_id[] = {
{ "mcp9600" },
{ "mcp9600", .driver_data = (kernel_ulong_t)&mcp9600_chip_info },
{ "mcp9601", .driver_data = (kernel_ulong_t)&mcp9601_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp9600_id);
static const struct of_device_id mcp9600_of_match[] = {
{ .compatible = "microchip,mcp9600" },
{ .compatible = "microchip,mcp9600", .data = &mcp9600_chip_info },
{ .compatible = "microchip,mcp9601", .data = &mcp9601_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, mcp9600_of_match);