On Wed, Mar 23, 2022 at 04:40:55PM +1300, Chris Packham wrote: > The adt7473, adt7475, adt7476 and adt7490 have pins that can be used for > different functions. On the adt7473 and adt7475 this is pins 5 and 9. > On the adt7476 and adt7490 this is pins 10 and 14. > > The first pin can either be PWM2(default) or SMBALERT#. The second pin > can be TACH4(default), THERM#, SMBALERT# or GPIO. > > The adt7475 driver has always been able to detect the configuration if > it had been done by an earlier boot stage. Add support for configuring > the pins based on the hardware description in the device tree. > > Signed-off-by: Chris Packham <chris.packham@xxxxxxxxxxxxxxxxxxx> For my reference: Reviewed-by: Guenter Roeck <linux@xxxxxxxxxxxx> > --- > > Notes: > Changes in v3: > - None > Changes in v2: > - Use load_config{3,4} instead of load_pin{10,14}_config > - Handle errors from adt7475_read() > - Remove obsolete check on chip type > - Use enum chips instead of int > - Update error messages > > drivers/hwmon/adt7475.c | 96 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 96 insertions(+) > > diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c > index 9d5b019651f2..6de501de41b2 100644 > --- a/drivers/hwmon/adt7475.c > +++ b/drivers/hwmon/adt7475.c > @@ -112,6 +112,8 @@ > #define CONFIG3_THERM 0x02 > > #define CONFIG4_PINFUNC 0x03 > +#define CONFIG4_THERM 0x01 > +#define CONFIG4_SMBALERT 0x02 > #define CONFIG4_MAXDUTY 0x08 > #define CONFIG4_ATTN_IN10 0x30 > #define CONFIG4_ATTN_IN43 0xC0 > @@ -1460,6 +1462,96 @@ static int adt7475_update_limits(struct i2c_client *client) > return 0; > } > > +static int load_config3(const struct i2c_client *client, const char *propname) > +{ > + const char *function; > + u8 config3; > + int ret; > + > + ret = of_property_read_string(client->dev.of_node, propname, &function); > + if (!ret) { > + ret = adt7475_read(REG_CONFIG3); > + if (ret < 0) > + return ret; > + > + config3 = ret & ~CONFIG3_SMBALERT; > + if (!strcmp("pwm2", function)) > + ; > + else if (!strcmp("smbalert#", function)) > + config3 |= CONFIG3_SMBALERT; > + else > + return -EINVAL; > + > + return i2c_smbus_write_byte_data(client, REG_CONFIG3, config3); > + } > + > + return 0; > +} > + > +static int load_config4(const struct i2c_client *client, const char *propname) > +{ > + const char *function; > + u8 config4; > + int ret; > + > + ret = of_property_read_string(client->dev.of_node, propname, &function); > + if (!ret) { > + ret = adt7475_read(REG_CONFIG4); > + if (ret < 0) > + return ret; > + > + config4 = ret & ~CONFIG4_PINFUNC; > + > + if (!strcmp("tach4", function)) > + ; > + else if (!strcmp("therm#", function)) > + config4 |= CONFIG4_THERM; > + else if (!strcmp("smbalert#", function)) > + config4 |= CONFIG4_SMBALERT; > + else if (!strcmp("gpio", function)) > + config4 |= CONFIG4_PINFUNC; > + else > + return -EINVAL; > + > + return i2c_smbus_write_byte_data(client, REG_CONFIG4, config4); > + } > + > + return 0; > +} > + > +static int load_config(const struct i2c_client *client, enum chips chip) > +{ > + int err; > + const char *prop1, *prop2; > + > + switch (chip) { > + case adt7473: > + case adt7475: > + prop1 = "adi,pin5-function"; > + prop2 = "adi,pin9-function"; > + break; > + case adt7476: > + case adt7490: > + prop1 = "adi,pin10-function"; > + prop2 = "adi,pin14-function"; > + break; > + } > + > + err = load_config3(client, prop1); > + if (err) { > + dev_err(&client->dev, "failed to configure %s\n", prop1); > + return err; > + } > + > + err = load_config4(client, prop2); > + if (err) { > + dev_err(&client->dev, "failed to configure %s\n", prop2); > + return err; > + } > + > + return 0; > +} > + > static int set_property_bit(const struct i2c_client *client, char *property, > u8 *config, u8 bit_index) > { > @@ -1585,6 +1677,10 @@ static int adt7475_probe(struct i2c_client *client) > revision = adt7475_read(REG_DEVID2) & 0x07; > } > > + ret = load_config(client, chip); > + if (ret) > + return ret; > + > config3 = adt7475_read(REG_CONFIG3); > /* Pin PWM2 may alternatively be used for ALERT output */ > if (!(config3 & CONFIG3_SMBALERT))