mirror of
https://github.com/torvalds/linux.git
synced 2025-11-03 18:20:25 +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/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/pwm.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <dt-bindings/pwm/pwm.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Addresses to scan.
|
* Addresses to scan.
|
||||||
*/
|
*/
|
||||||
|
|
@ -37,7 +40,7 @@ static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
|
||||||
* Insmod parameters
|
* Insmod parameters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int pwminv; /*Inverted PWM output. */
|
static int pwminv = -1; /*Inverted PWM output. */
|
||||||
module_param(pwminv, int, 0444);
|
module_param(pwminv, int, 0444);
|
||||||
|
|
||||||
static int init = 1; /*Power-on initialization.*/
|
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;
|
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;
|
struct regmap *regmap = data->regmap;
|
||||||
|
u32 regval;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (init) {
|
if (init) {
|
||||||
|
|
@ -864,11 +901,14 @@ static int amc6821_init_client(struct amc6821_data *data)
|
||||||
if (err)
|
if (err)
|
||||||
return 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,
|
err = regmap_update_bits(regmap, AMC6821_REG_CONF1,
|
||||||
AMC6821_CONF1_THERMOVIE | AMC6821_CONF1_FANIE |
|
AMC6821_CONF1_THERMOVIE | AMC6821_CONF1_FANIE |
|
||||||
AMC6821_CONF1_START | AMC6821_CONF1_PWMINV,
|
AMC6821_CONF1_START | AMC6821_CONF1_PWMINV,
|
||||||
AMC6821_CONF1_START |
|
regval);
|
||||||
(pwminv ? AMC6821_CONF1_PWMINV : 0));
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
@ -916,7 +956,7 @@ static int amc6821_probe(struct i2c_client *client)
|
||||||
"Failed to initialize regmap\n");
|
"Failed to initialize regmap\n");
|
||||||
data->regmap = regmap;
|
data->regmap = regmap;
|
||||||
|
|
||||||
err = amc6821_init_client(data);
|
err = amc6821_init_client(client, data);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue