summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2020-03-30 16:57:15 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-03-31 09:48:34 +0200
commitc5e8deaeebd5e223fc77df6aa8daa25f5b7f3ea9 (patch)
tree46256819e94257f98eb724921f093cca7df81042
parent83affc1a6c5e13349d7ea34bd787568aa1c872ff (diff)
downloadbarebox-c5e8deaeebd5e223fc77df6aa8daa25f5b7f3ea9.tar.gz
barebox-c5e8deaeebd5e223fc77df6aa8daa25f5b7f3ea9.tar.xz
PWM: core: add apply API support for polarity
Some PWM chips support outputting an inverted PWM signal. Add API support for this. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/pwm/core.c21
-rw-r--r--include/pwm.h6
2 files changed, 23 insertions, 4 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 9206fc0b9e..05dad93e5c 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -23,6 +23,7 @@
/**
* struct pwm_args - board-dependent PWM arguments
* @period_ns: reference period
+ * @polarity: reference polarity
*
* This structure describes board-dependent arguments attached to a PWM
* device. These arguments are usually retrieved from the PWM lookup table or
@@ -35,6 +36,7 @@
struct pwm_args {
unsigned int period_ns;
+ unsigned int polarity;
};
struct pwm_device {
@@ -63,7 +65,7 @@ static struct pwm_device *_find_pwm(const char *devname)
return NULL;
}
-static int set_duty_period_ns(struct param_d *p, void *priv)
+static int apply_params(struct param_d *p, void *priv)
{
struct pwm_device *pwm = priv;
@@ -112,12 +114,12 @@ int pwmchip_add(struct pwm_chip *chip, struct device_d *dev)
list_add_tail(&pwm->node, &pwm_list);
- p = dev_add_param_uint32(&pwm->dev, "duty_ns", set_duty_period_ns,
+ p = dev_add_param_uint32(&pwm->dev, "duty_ns", apply_params,
NULL, &pwm->params.duty_ns, "%u", pwm);
if (IS_ERR(p))
return PTR_ERR(p);
- p = dev_add_param_uint32(&pwm->dev, "period_ns", set_duty_period_ns,
+ p = dev_add_param_uint32(&pwm->dev, "period_ns", apply_params,
NULL, &pwm->params.period_ns, "%u", pwm);
if (IS_ERR(p))
return PTR_ERR(p);
@@ -127,6 +129,11 @@ int pwmchip_add(struct pwm_chip *chip, struct device_d *dev)
if (IS_ERR(p))
return PTR_ERR(p);
+ p = dev_add_param_bool(&pwm->dev, "inverted", apply_params,
+ NULL, &pwm->params.polarity, pwm);
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+
return 0;
}
EXPORT_SYMBOL_GPL(pwmchip_add);
@@ -234,6 +241,11 @@ struct pwm_device *of_pwm_request(struct device_node *np, const char *con_id)
if (args.args_count > 1)
pwm->args.period_ns = args.args[1];
+ pwm->args.polarity = PWM_POLARITY_NORMAL;
+
+ if (args.args_count > 2 && args.args[2] & PWM_POLARITY_INVERTED)
+ pwm->args.polarity = PWM_POLARITY_INVERTED;
+
ret = __pwm_request(pwm);
if (ret)
return ERR_PTR(ret);
@@ -277,7 +289,7 @@ static void pwm_get_args(const struct pwm_device *pwm, struct pwm_args *args)
* This functions prepares a state that can later be tweaked and applied
* to the PWM device with pwm_apply_state(). This is a convenient function
* that first retrieves the current PWM state and the replaces the period
- * with the reference values defined in pwm->args.
+ * and polarity fields with the reference values defined in pwm->args.
* Once the function returns, you can adjust the ->enabled and ->duty_cycle
* fields according to your needs before calling pwm_apply_state().
*
@@ -298,6 +310,7 @@ void pwm_init_state(const struct pwm_device *pwm,
pwm_get_args(pwm, &args);
state->period_ns = args.period_ns;
+ state->polarity = args.polarity;
state->duty_ns = 0;
}
EXPORT_SYMBOL_GPL(pwm_init_state);
diff --git a/include/pwm.h b/include/pwm.h
index 67ea0f9bcb..b67ab13d2e 100644
--- a/include/pwm.h
+++ b/include/pwm.h
@@ -2,18 +2,24 @@
#ifndef __PWM_H
#define __PWM_H
+#include <dt-bindings/pwm/pwm.h>
+
struct pwm_device;
struct device_d;
+#define PWM_POLARITY_NORMAL 0
+
/*
* struct pwm_state - state of a PWM channel
* @period_ns: PWM period (in nanoseconds)
* @duty_ns: PWM duty cycle (in nanoseconds)
+ * @polarity: PWM polarity
* @p_enable: PWM enabled status
*/
struct pwm_state {
unsigned int period_ns;
unsigned int duty_ns;
+ unsigned int polarity;
unsigned int p_enable;
};