PWMOUT pins on MAX31790 can be configured as a tachometer input pin by setting bit[0] in the Configuration Register. When the bit[0] of a channel is set, the PWMOUT pin becomes the tach input pin for the channel plus six. This commit allows the kernel to set those pins when necessary if the maxim,pwmout-pin-as-tach-input DT property exists. Signed-off-by: Chanh Nguyen <chanh@xxxxxxxxxxxxxxxxxxxxxx> --- Changes in v2: - Update the vendor property name to "maxim,pwmout-pin-as-tach-input" [Rob] --- drivers/hwmon/max31790.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c index 3dc95196b229..ac0a8099acf6 100644 --- a/drivers/hwmon/max31790.c +++ b/drivers/hwmon/max31790.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/jiffies.h> #include <linux/module.h> +#include <linux/property.h> #include <linux/slab.h> /* MAX31790 registers */ @@ -506,9 +507,12 @@ static int max31790_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; struct device *dev = &client->dev; + u8 pwmout_to_tach[NR_CHANNEL]; struct max31790_data *data; struct device *hwmon_dev; int err; + u8 tmp; + int i; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) @@ -528,6 +532,33 @@ static int max31790_probe(struct i2c_client *client) if (err) return err; + if (device_property_present(dev, "maxim,pwmout-pin-as-tach-input")) { + err = device_property_read_u8_array(dev, "maxim,pwmout-pin-as-tach-input", + pwmout_to_tach, NR_CHANNEL); + if (err) { + /* The maxim,pwmout-pin-as-tach-input is an array of six values */ + dev_warn(dev, "The maxim,pwmout-pin-as-tach-input property exist but malform"); + } else { + for (i = 0; i < NR_CHANNEL; i++) { + tmp = data->fan_config[i]; + if (pwmout_to_tach[i]) + data->fan_config[i] |= MAX31790_FAN_CFG_TACH_INPUT; + else + data->fan_config[i] &= ~(MAX31790_FAN_CFG_TACH_INPUT); + + if (tmp != data->fan_config[i]) { + err = i2c_smbus_write_byte_data(client, + MAX31790_REG_FAN_CONFIG(i), + data->fan_config[i]); + if (err < 0) + dev_warn(dev, + "Fail to apply fan configuration at channel %d", + i); + } + } + } + } + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &max31790_chip_info, -- 2.17.1