EMC1438 is similar to EMC14x4, but supports four more external temperature sensors. Signed-off-by: Lars Petter Mostad <lars.petter.mostad@xxxxxxxxxx> --- drivers/hwmon/emc1403.c | 119 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index d370efd6f986..1ce01baf7a1e 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c @@ -24,12 +24,12 @@ #define THERMAL_SMSC_ID_REG 0xfe #define THERMAL_REVISION_REG 0xff -enum emc1403_chip { emc1402, emc1403, emc1404 }; +enum emc1403_chip { emc1402, emc1403, emc1404, emc1408 }; struct thermal_data { struct regmap *regmap; struct mutex mutex; - const struct attribute_group *groups[4]; + const struct attribute_group *groups[5]; }; static ssize_t temp_show(struct device *dev, struct device_attribute *attr, @@ -209,6 +209,54 @@ static SENSOR_DEVICE_ATTR_RO(temp4_min_hyst, min_hyst, 0x2D); static SENSOR_DEVICE_ATTR_RO(temp4_max_hyst, hyst, 0x2C); static SENSOR_DEVICE_ATTR_RO(temp4_crit_hyst, hyst, 0x30); +static SENSOR_DEVICE_ATTR_RW(temp5_min, temp, 0x51); +static SENSOR_DEVICE_ATTR_RW(temp5_max, temp, 0x50); +static SENSOR_DEVICE_ATTR_RW(temp5_crit, temp, 0x64); +static SENSOR_DEVICE_ATTR_RO(temp5_input, temp, 0x41); +static SENSOR_DEVICE_ATTR_2_RO(temp5_fault, bit, 0x1b, 0x10); +static SENSOR_DEVICE_ATTR_2_RO(temp5_min_alarm, bit, 0x36, 0x10); +static SENSOR_DEVICE_ATTR_2_RO(temp5_max_alarm, bit, 0x35, 0x10); +static SENSOR_DEVICE_ATTR_2_RO(temp5_crit_alarm, bit, 0x37, 0x10); +static SENSOR_DEVICE_ATTR_RO(temp5_min_hyst, min_hyst, 0x51); +static SENSOR_DEVICE_ATTR_RO(temp5_max_hyst, hyst, 0x50); +static SENSOR_DEVICE_ATTR_RO(temp5_crit_hyst, hyst, 0x64); + +static SENSOR_DEVICE_ATTR_RW(temp6_min, temp, 0x55); +static SENSOR_DEVICE_ATTR_RW(temp6_max, temp, 0x54); +static SENSOR_DEVICE_ATTR_RW(temp6_crit, temp, 0x65); +static SENSOR_DEVICE_ATTR_RO(temp6_input, temp, 0x43); +static SENSOR_DEVICE_ATTR_2_RO(temp6_fault, bit, 0x1b, 0x20); +static SENSOR_DEVICE_ATTR_2_RO(temp6_min_alarm, bit, 0x36, 0x20); +static SENSOR_DEVICE_ATTR_2_RO(temp6_max_alarm, bit, 0x35, 0x20); +static SENSOR_DEVICE_ATTR_2_RO(temp6_crit_alarm, bit, 0x37, 0x20); +static SENSOR_DEVICE_ATTR_RO(temp6_min_hyst, min_hyst, 0x55); +static SENSOR_DEVICE_ATTR_RO(temp6_max_hyst, hyst, 0x54); +static SENSOR_DEVICE_ATTR_RO(temp6_crit_hyst, hyst, 0x65); + +static SENSOR_DEVICE_ATTR_RW(temp7_min, temp, 0x59); +static SENSOR_DEVICE_ATTR_RW(temp7_max, temp, 0x58); +static SENSOR_DEVICE_ATTR_RW(temp7_crit, temp, 0x66); +static SENSOR_DEVICE_ATTR_RO(temp7_input, temp, 0x45); +static SENSOR_DEVICE_ATTR_2_RO(temp7_fault, bit, 0x1b, 0x40); +static SENSOR_DEVICE_ATTR_2_RO(temp7_min_alarm, bit, 0x36, 0x40); +static SENSOR_DEVICE_ATTR_2_RO(temp7_max_alarm, bit, 0x35, 0x40); +static SENSOR_DEVICE_ATTR_2_RO(temp7_crit_alarm, bit, 0x37, 0x40); +static SENSOR_DEVICE_ATTR_RO(temp7_min_hyst, min_hyst, 0x59); +static SENSOR_DEVICE_ATTR_RO(temp7_max_hyst, hyst, 0x58); +static SENSOR_DEVICE_ATTR_RO(temp7_crit_hyst, hyst, 0x66); + +static SENSOR_DEVICE_ATTR_RW(temp8_min, temp, 0x5D); +static SENSOR_DEVICE_ATTR_RW(temp8_max, temp, 0x5C); +static SENSOR_DEVICE_ATTR_RW(temp8_crit, temp, 0x67); +static SENSOR_DEVICE_ATTR_RO(temp8_input, temp, 0x47); +static SENSOR_DEVICE_ATTR_2_RO(temp8_fault, bit, 0x1b, 0x80); +static SENSOR_DEVICE_ATTR_2_RO(temp8_min_alarm, bit, 0x36, 0x80); +static SENSOR_DEVICE_ATTR_2_RO(temp8_max_alarm, bit, 0x35, 0x80); +static SENSOR_DEVICE_ATTR_2_RO(temp8_crit_alarm, bit, 0x37, 0x80); +static SENSOR_DEVICE_ATTR_RO(temp8_min_hyst, min_hyst, 0x5D); +static SENSOR_DEVICE_ATTR_RO(temp8_max_hyst, hyst, 0x5C); +static SENSOR_DEVICE_ATTR_RO(temp8_crit_hyst, hyst, 0x67); + static SENSOR_DEVICE_ATTR_2_RW(power_state, bit, 0x03, 0x40); static struct attribute *emc1402_attrs[] = { @@ -283,6 +331,58 @@ static const struct attribute_group emc1404_group = { .attrs = emc1404_attrs, }; +static struct attribute *emc1408_attrs[] = { + &sensor_dev_attr_temp5_min.dev_attr.attr, + &sensor_dev_attr_temp5_max.dev_attr.attr, + &sensor_dev_attr_temp5_crit.dev_attr.attr, + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp5_fault.dev_attr.attr, + &sensor_dev_attr_temp5_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp5_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp6_min.dev_attr.attr, + &sensor_dev_attr_temp6_max.dev_attr.attr, + &sensor_dev_attr_temp6_crit.dev_attr.attr, + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp6_fault.dev_attr.attr, + &sensor_dev_attr_temp6_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp6_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp6_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp6_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp6_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp7_min.dev_attr.attr, + &sensor_dev_attr_temp7_max.dev_attr.attr, + &sensor_dev_attr_temp7_crit.dev_attr.attr, + &sensor_dev_attr_temp7_input.dev_attr.attr, + &sensor_dev_attr_temp7_fault.dev_attr.attr, + &sensor_dev_attr_temp7_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp7_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp7_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp7_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp7_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp7_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp8_min.dev_attr.attr, + &sensor_dev_attr_temp8_max.dev_attr.attr, + &sensor_dev_attr_temp8_crit.dev_attr.attr, + &sensor_dev_attr_temp8_input.dev_attr.attr, + &sensor_dev_attr_temp8_fault.dev_attr.attr, + &sensor_dev_attr_temp8_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp8_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp8_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp8_min_hyst.dev_attr.attr, + &sensor_dev_attr_temp8_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp8_crit_hyst.dev_attr.attr, + NULL +}; + +static const struct attribute_group emc1408_group = { + .attrs = emc1408_attrs, +}; + /* * EMC14x2 uses a different register and different bits to report alarm and * fault status. For simplicity, provide a separate attribute group for this @@ -346,6 +446,9 @@ static int emc1403_detect(struct i2c_client *client, case 0x27: strscpy(info->type, "emc1424", I2C_NAME_SIZE); break; + case 0x59: + strscpy(info->type, "emc1438", I2C_NAME_SIZE); + break; case 0x60: strscpy(info->type, "emc1442", I2C_NAME_SIZE); break; @@ -376,6 +479,14 @@ static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg) case 0x35: /* high limit status */ case 0x36: /* low limit status */ case 0x37: /* therm limit status */ + case 0x41: /* external diode 4 high byte */ + case 0x42: /* external diode 4 low byte */ + case 0x43: /* external diode 5 high byte */ + case 0x44: /* external diode 5 low byte */ + case 0x45: /* external diode 6 high byte */ + case 0x46: /* external diode 6 low byte */ + case 0x47: /* external diode 7 high byte */ + case 0x48: /* external diode 7 low byte */ return true; default: return false; @@ -409,6 +520,9 @@ static int emc1403_probe(struct i2c_client *client) mutex_init(&data->mutex); switch (id->driver_data) { + case emc1408: + data->groups[3] = &emc1408_group; + fallthrough; case emc1404: data->groups[2] = &emc1404_group; fallthrough; @@ -447,6 +561,7 @@ static const struct i2c_device_id emc1403_idtable[] = { { "emc1422", emc1402 }, { "emc1423", emc1403 }, { "emc1424", emc1404 }, + { "emc1438", emc1408 }, { "emc1442", emc1402 }, { } }; base-commit: e723f6ca39fb54ae31f79b5af74fe8496308d4de -- 2.44.0