[PATCH 07/12] PWM: core: apply initial state in of_pwm_request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
Once the function returns, you can adjust the ->enabled and ->duty_cycle
fields according to your needs before calling pwm_apply_state().

Signed-off-by: Ahmad Fatoum <ahmad@xxxxxx>
---
 drivers/pwm/core.c | 70 +++++++++++++++++++++++++++++++++++++++++++---
 include/pwm.h      |  6 ++++
 2 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index b42b3092a3f8..9206fc0b9eda 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -20,6 +20,23 @@
 #include <linux/list.h>
 #include <linux/err.h>
 
+/**
+ * struct pwm_args - board-dependent PWM arguments
+ * @period_ns: reference period
+ *
+ * This structure describes board-dependent arguments attached to a PWM
+ * device. These arguments are usually retrieved from the PWM lookup table or
+ * device tree.
+ *
+ * Do not confuse this with the PWM state: PWM arguments represent the initial
+ * configuration that users want to use on this PWM device rather than the
+ * current PWM hardware state.
+ */
+
+struct pwm_args {
+	unsigned int period_ns;
+};
+
 struct pwm_device {
 	struct			pwm_chip *chip;
 	unsigned long		flags;
@@ -29,6 +46,7 @@ struct pwm_device {
 	struct device_d		dev;
 
 	struct pwm_state	params;
+	struct pwm_args		args;
 };
 
 static LIST_HEAD(pwm_list);
@@ -194,6 +212,7 @@ struct pwm_device *of_pwm_request(struct device_node *np, const char *con_id)
 	struct of_phandle_args args;
 	int index = 0;
 	struct pwm_device *pwm;
+	struct pwm_state state;
 	int ret;
 
 	if (con_id)
@@ -213,11 +232,17 @@ struct pwm_device *of_pwm_request(struct device_node *np, const char *con_id)
 	}
 
 	if (args.args_count > 1)
-		pwm->chip->state.period_ns = args.args[1];
+		pwm->args.period_ns = args.args[1];
 
 	ret = __pwm_request(pwm);
 	if (ret)
-		return ERR_PTR(-ret);
+		return ERR_PTR(ret);
+
+	pwm_init_state(pwm, &state);
+
+	ret = pwm_apply_state(pwm, &state);
+	if (ret)
+		return ERR_PTR(ret);
 
 	return pwm;
 }
@@ -233,13 +258,50 @@ void pwm_free(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_free);
 
-void pwm_get_state(const struct pwm_device *pwm,
-		   struct pwm_state *state)
+void pwm_get_state(const struct pwm_device *pwm, struct pwm_state *state)
 {
 	*state = pwm->chip->state;
 }
 EXPORT_SYMBOL_GPL(pwm_get_state);
 
+static void pwm_get_args(const struct pwm_device *pwm, struct pwm_args *args)
+{
+	*args = pwm->args;
+}
+
+/**
+ * pwm_init_state() - prepare a new state to be applied with pwm_apply_state()
+ * @pwm: PWM device
+ * @state: state to fill with the prepared PWM state
+ *
+ * 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.
+ * Once the function returns, you can adjust the ->enabled and ->duty_cycle
+ * fields according to your needs before calling pwm_apply_state().
+ *
+ * ->duty_cycle is initially set to zero to avoid cases where the current
+ * ->duty_cycle value exceed the pwm_args->period one, which would trigger
+ * an error if the user calls pwm_apply_state() without adjusting ->duty_cycle
+ * first.
+ */
+void pwm_init_state(const struct pwm_device *pwm,
+		    struct pwm_state *state)
+{
+	struct pwm_args args;
+
+	/* First get the current state. */
+	pwm_get_state(pwm, state);
+
+	/* Then fill it with the reference config */
+	pwm_get_args(pwm, &args);
+
+	state->period_ns = args.period_ns;
+	state->duty_ns = 0;
+}
+EXPORT_SYMBOL_GPL(pwm_init_state);
+
 int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
 {
 	struct pwm_chip *chip = pwm->chip;
diff --git a/include/pwm.h b/include/pwm.h
index 36b1eb8131fb..67ea0f9bcb05 100644
--- a/include/pwm.h
+++ b/include/pwm.h
@@ -29,6 +29,12 @@ struct pwm_device *of_pwm_request(struct device_node *np, const char *con_id);
  */
 void pwm_free(struct pwm_device *pwm);
 
+/*
+ * pwm_init_state - prepare a new state from device tree args
+ */
+void pwm_init_state(const struct pwm_device *pwm,
+		    struct pwm_state *state);
+
 /*
  * pwm_config - change a PWM device configuration
  */
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux