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

Configure Feed

Select the types of activity you want to include in your feed.

iio: mcp9600: Add support for thermocouple-type

dt-bindings documentation for this driver claims to support
thermocouple-type, but the driver does not actually make use of
the property.

Implement usage of the property to configure the chip for the
selected thermocouple-type.

Signed-off-by: Ben Collins <bcollins@watter.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20250822-upstream-changes-v8-5-40bb1739e3e2@watter.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Ben Collins and committed by
Jonathan Cameron
46809b9f 5efd60c9

+70 -1
+70 -1
drivers/iio/temperature/mcp9600.c
··· 22 22 #include <linux/iio/events.h> 23 23 #include <linux/iio/iio.h> 24 24 25 + #include <dt-bindings/iio/temperature/thermocouple.h> 26 + 25 27 /* MCP9600 registers */ 26 28 #define MCP9600_HOT_JUNCTION 0x00 27 29 #define MCP9600_COLD_JUNCTION 0x02 28 30 #define MCP9600_STATUS 0x04 29 31 #define MCP9600_STATUS_ALERT(x) BIT(x) 32 + #define MCP9600_SENSOR_CFG 0x05 33 + #define MCP9600_SENSOR_TYPE_MASK GENMASK(6, 4) 30 34 #define MCP9600_ALERT_CFG1 0x08 31 35 #define MCP9600_ALERT_CFG(x) (MCP9600_ALERT_CFG1 + (x - 1)) 32 36 #define MCP9600_ALERT_CFG_ENABLE BIT(0) ··· 70 66 [MCP9600_ALERT4] = "alert4", 71 67 }; 72 68 69 + /* Map between dt-bindings enum and the chip's type value */ 70 + static const unsigned int mcp9600_type_map[] = { 71 + [THERMOCOUPLE_TYPE_K] = 0, 72 + [THERMOCOUPLE_TYPE_J] = 1, 73 + [THERMOCOUPLE_TYPE_T] = 2, 74 + [THERMOCOUPLE_TYPE_N] = 3, 75 + [THERMOCOUPLE_TYPE_S] = 4, 76 + [THERMOCOUPLE_TYPE_E] = 5, 77 + [THERMOCOUPLE_TYPE_B] = 6, 78 + [THERMOCOUPLE_TYPE_R] = 7, 79 + }; 80 + 81 + /* Map thermocouple type to a char for iio info in sysfs */ 82 + static const int mcp9600_tc_types[] = { 83 + [THERMOCOUPLE_TYPE_K] = 'K', 84 + [THERMOCOUPLE_TYPE_J] = 'J', 85 + [THERMOCOUPLE_TYPE_T] = 'T', 86 + [THERMOCOUPLE_TYPE_N] = 'N', 87 + [THERMOCOUPLE_TYPE_S] = 'S', 88 + [THERMOCOUPLE_TYPE_E] = 'E', 89 + [THERMOCOUPLE_TYPE_B] = 'B', 90 + [THERMOCOUPLE_TYPE_R] = 'R', 91 + }; 92 + 73 93 static const struct iio_event_spec mcp9600_events[] = { 74 94 { 75 95 .type = IIO_EV_TYPE_THRESH, ··· 118 90 119 91 struct mcp9600_data { 120 92 struct i2c_client *client; 93 + u32 thermocouple_type; 121 94 }; 95 + 96 + static int mcp9600_config(struct mcp9600_data *data) 97 + { 98 + struct i2c_client *client = data->client; 99 + int ret; 100 + u8 cfg; 101 + 102 + cfg = FIELD_PREP(MCP9600_SENSOR_TYPE_MASK, 103 + mcp9600_type_map[data->thermocouple_type]); 104 + 105 + ret = i2c_smbus_write_byte_data(client, MCP9600_SENSOR_CFG, cfg); 106 + if (ret < 0) { 107 + dev_err(&client->dev, "Failed to set sensor configuration\n"); 108 + return ret; 109 + } 110 + 111 + return 0; 112 + } 122 113 123 114 #define MCP9600_CHANNELS(hj_num_ev, hj_ev_spec_off, cj_num_ev, cj_ev_spec_off) \ 124 115 { \ ··· 145 98 .type = IIO_TEMP, \ 146 99 .address = MCP9600_HOT_JUNCTION, \ 147 100 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 101 + BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE) | \ 148 102 BIT(IIO_CHAN_INFO_SCALE), \ 149 103 .event_spec = &mcp9600_events[hj_ev_spec_off], \ 150 104 .num_event_specs = hj_num_ev, \ ··· 213 165 *val = 62; 214 166 *val2 = 500000; 215 167 return IIO_VAL_INT_PLUS_MICRO; 168 + case IIO_CHAN_INFO_THERMOCOUPLE_TYPE: 169 + *val = mcp9600_tc_types[data->thermocouple_type]; 170 + return IIO_VAL_CHAR; 216 171 default: 217 172 return -EINVAL; 218 173 } ··· 477 426 const struct mcp_chip_info *chip_info; 478 427 struct iio_dev *indio_dev; 479 428 struct mcp9600_data *data; 480 - int ch_sel, dev_id; 429 + int ch_sel, dev_id, ret; 481 430 482 431 chip_info = i2c_get_match_data(client); 483 432 if (!chip_info) ··· 508 457 509 458 data = iio_priv(indio_dev); 510 459 data->client = client; 460 + 461 + /* Accept type from dt with default of Type-K. */ 462 + data->thermocouple_type = THERMOCOUPLE_TYPE_K; 463 + ret = device_property_read_u32(dev, "thermocouple-type", 464 + &data->thermocouple_type); 465 + if (ret && ret != -EINVAL) 466 + return dev_err_probe(dev, ret, 467 + "Error reading thermocouple-type property\n"); 468 + 469 + if (data->thermocouple_type >= ARRAY_SIZE(mcp9600_type_map)) 470 + return dev_err_probe(dev, -EINVAL, 471 + "Invalid thermocouple-type property %u.\n", 472 + data->thermocouple_type); 473 + 474 + /* Set initial config. */ 475 + ret = mcp9600_config(data); 476 + if (ret) 477 + return ret; 511 478 512 479 ch_sel = mcp9600_probe_alerts(indio_dev); 513 480 if (ch_sel < 0)