2022-03-24 07:34:23

by Chris Packham

[permalink] [raw]
Subject: [PATCH v3 2/3] hwmon: (adt7475) Add support for pin configuration

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 <[email protected]>
---

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))
--
2.35.1


2022-04-24 19:05:55

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH v3 2/3] hwmon: (adt7475) Add support for pin configuration

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 <[email protected]>

For my reference:

Reviewed-by: Guenter Roeck <[email protected]>

> ---
>
> 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))

2022-05-03 00:49:04

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH v3 2/3] hwmon: (adt7475) Add support for pin configuration

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 <[email protected]>
> Reviewed-by: Guenter Roeck <[email protected]>

Applied to hwmon-next.

Thanks,
Guenter

> ---
>
> 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))