mirror of
https://github.com/torvalds/linux.git
synced 2025-11-01 09:09:47 +02:00
hwmon: (amc6821) Add PWM polarity configuration with OF
Add support to configure the PWM-Out pin polarity based on the device tree. The binding would allow also to configure the PWM period, this is currently not implemented by the driver. The driver has a module option to set the PWM polarity (normal=0, inverted=1), when specified it always takes the precedence over the DT. Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com> Link: https://lore.kernel.org/r/20250402102146.65406-3-francesco@dolcini.it Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
ce66422118
commit
cd17587272
1 changed files with 45 additions and 5 deletions
|
|
@ -23,9 +23,12 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/pwm/pwm.h>
|
||||
|
||||
/*
|
||||
* Addresses to scan.
|
||||
*/
|
||||
|
|
@ -37,7 +40,7 @@ static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
|
|||
* Insmod parameters
|
||||
*/
|
||||
|
||||
static int pwminv; /*Inverted PWM output. */
|
||||
static int pwminv = -1; /*Inverted PWM output. */
|
||||
module_param(pwminv, int, 0444);
|
||||
|
||||
static int init = 1; /*Power-on initialization.*/
|
||||
|
|
@ -845,9 +848,43 @@ static int amc6821_detect(struct i2c_client *client, struct i2c_board_info *info
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amc6821_init_client(struct amc6821_data *data)
|
||||
static enum pwm_polarity amc6821_pwm_polarity(struct i2c_client *client)
|
||||
{
|
||||
enum pwm_polarity polarity = PWM_POLARITY_NORMAL;
|
||||
struct of_phandle_args args;
|
||||
struct device_node *fan_np;
|
||||
|
||||
/*
|
||||
* For backward compatibility, the pwminv module parameter takes
|
||||
* always the precedence over any other device description
|
||||
*/
|
||||
if (pwminv == 0)
|
||||
return PWM_POLARITY_NORMAL;
|
||||
if (pwminv > 0)
|
||||
return PWM_POLARITY_INVERSED;
|
||||
|
||||
fan_np = of_get_child_by_name(client->dev.of_node, "fan");
|
||||
if (!fan_np)
|
||||
return PWM_POLARITY_NORMAL;
|
||||
|
||||
if (of_parse_phandle_with_args(fan_np, "pwms", "#pwm-cells", 0, &args))
|
||||
goto out;
|
||||
of_node_put(args.np);
|
||||
|
||||
if (args.args_count != 2)
|
||||
goto out;
|
||||
|
||||
if (args.args[1] & PWM_POLARITY_INVERTED)
|
||||
polarity = PWM_POLARITY_INVERSED;
|
||||
out:
|
||||
of_node_put(fan_np);
|
||||
return polarity;
|
||||
}
|
||||
|
||||
static int amc6821_init_client(struct i2c_client *client, struct amc6821_data *data)
|
||||
{
|
||||
struct regmap *regmap = data->regmap;
|
||||
u32 regval;
|
||||
int err;
|
||||
|
||||
if (init) {
|
||||
|
|
@ -864,11 +901,14 @@ static int amc6821_init_client(struct amc6821_data *data)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
regval = AMC6821_CONF1_START;
|
||||
if (amc6821_pwm_polarity(client) == PWM_POLARITY_INVERSED)
|
||||
regval |= AMC6821_CONF1_PWMINV;
|
||||
|
||||
err = regmap_update_bits(regmap, AMC6821_REG_CONF1,
|
||||
AMC6821_CONF1_THERMOVIE | AMC6821_CONF1_FANIE |
|
||||
AMC6821_CONF1_START | AMC6821_CONF1_PWMINV,
|
||||
AMC6821_CONF1_START |
|
||||
(pwminv ? AMC6821_CONF1_PWMINV : 0));
|
||||
regval);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
|
@ -916,7 +956,7 @@ static int amc6821_probe(struct i2c_client *client)
|
|||
"Failed to initialize regmap\n");
|
||||
data->regmap = regmap;
|
||||
|
||||
err = amc6821_init_client(data);
|
||||
err = amc6821_init_client(client, data);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue