From 37acfdf97d1ebddb431e2ed9a9aa4482ac1a474a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 28 Feb 2014 13:29:35 +0100 Subject: PWM: Add functions for getting/setting period/duty cycle Signed-off-by: Sascha Hauer --- include/pwm.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/pwm.h b/include/pwm.h index bdc2fdd858..5ca9fa056b 100644 --- a/include/pwm.h +++ b/include/pwm.h @@ -29,6 +29,11 @@ int pwm_enable(struct pwm_device *pwm); */ void pwm_disable(struct pwm_device *pwm); +void pwm_set_period(struct pwm_device *pwm, unsigned int period); +unsigned int pwm_get_period(struct pwm_device *pwm); +void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty); +unsigned int pwm_get_duty_cycle(struct pwm_device *pwm); + struct pwm_chip; /** -- cgit v1.2.3 From ea0ed157863b7b650e3eff485a49cbc0925f5265 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 28 Feb 2014 13:29:06 +0100 Subject: PWM: Implement devicetree support This implements of_pwm_request() for PWM client drivers. Signed-off-by: Sascha Hauer --- drivers/pwm/core.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++------ include/pwm.h | 2 ++ 2 files changed, 66 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 7f307244f9..cc33dec363 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -143,6 +143,24 @@ int pwmchip_remove(struct pwm_chip *chip) } EXPORT_SYMBOL_GPL(pwmchip_remove); +static int __pwm_request(struct pwm_device *pwm) +{ + int ret; + + if (test_bit(FLAG_REQUESTED, &pwm->flags)) + return -EBUSY; + + if (pwm->chip->ops->request) { + ret = pwm->chip->ops->request(pwm->chip); + if (ret) + return ret; + } + + set_bit(FLAG_REQUESTED, &pwm->flags); + + return 0; +} + /* * pwm_request - request a PWM device */ @@ -155,20 +173,59 @@ struct pwm_device *pwm_request(const char *devname) if (!pwm) return NULL; - if (test_bit(FLAG_REQUESTED, &pwm->flags)) + ret = __pwm_request(pwm); + if (ret) return NULL; - if (pwm->chip->ops->request) { - ret = pwm->chip->ops->request(pwm->chip); - if (ret) - return NULL; + return pwm; +} +EXPORT_SYMBOL_GPL(pwm_request); + +static struct pwm_device *of_node_to_pwm_device(struct device_node *np) +{ + struct pwm_device *pwm; + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->hwdev && pwm->hwdev->device_node == np) + return pwm; } - set_bit(FLAG_REQUESTED, &pwm->flags); + return ERR_PTR(-ENODEV); +} + +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; + int ret; + + if (con_id) + return ERR_PTR(-EINVAL); + + ret = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index, + &args); + if (ret) { + pr_debug("%s(): can't parse \"pwms\" property\n", __func__); + return ERR_PTR(ret); + } + + pwm = of_node_to_pwm_device(args.np); + if (IS_ERR(pwm)) { + pr_debug("%s(): PWM chip not found\n", __func__); + return pwm; + } + + if (args.args_count > 1) + pwm_set_period(pwm, args.args[1]); + + ret = __pwm_request(pwm); + if (ret) + return ERR_PTR(-ret); return pwm; } -EXPORT_SYMBOL_GPL(pwm_request); +EXPORT_SYMBOL_GPL(of_pwm_request); /* * pwm_free - free a PWM device diff --git a/include/pwm.h b/include/pwm.h index 5ca9fa056b..59d86d497d 100644 --- a/include/pwm.h +++ b/include/pwm.h @@ -9,6 +9,8 @@ struct device_d; */ struct pwm_device *pwm_request(const char *pwmname); +struct pwm_device *of_pwm_request(struct device_node *np, const char *con_id); + /* * pwm_free - free a PWM device */ -- cgit v1.2.3 From e390a8e2b42b2063760ce127f2eacacb2e3a962f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 28 Feb 2014 13:28:06 +0100 Subject: led: move led_of_parse_trigger to core So that other LED drivers can use it. Signed-off-by: Sascha Hauer --- drivers/led/core.c | 34 ++++++++++++++++++++++++++++++++++ drivers/led/led-gpio.c | 35 ----------------------------------- include/led.h | 2 ++ 3 files changed, 36 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/drivers/led/core.c b/drivers/led/core.c index 8537aa15ea..422c0ad614 100644 --- a/drivers/led/core.c +++ b/drivers/led/core.c @@ -153,3 +153,37 @@ void led_unregister(struct led *led) { list_del(&led->list); } + +struct led_trg { + const char *str; + enum led_trigger trg; +}; + +static struct led_trg triggers[] = { + { .str = "heartbeat", LED_TRIGGER_HEARTBEAT, }, + { .str = "panic", LED_TRIGGER_PANIC, }, + { .str = "net", LED_TRIGGER_NET_TXRX, }, +}; + +void led_of_parse_trigger(struct led *led, struct device_node *np) +{ + const char *trigger; + int i; + + trigger = of_get_property(np, "linux,default-trigger", NULL); + if (!trigger) + trigger = of_get_property(np, "barebox,default-trigger", NULL); + + if (!trigger) + return; + + for (i = 0; i < ARRAY_SIZE(triggers); i++) { + struct led_trg *trg = &triggers[i]; + if (!strcmp(trg->str, trigger)) { + /* disable LED before installing trigger */ + led_set(led, 0); + led_set_trigger(trg->trg, led); + return; + } + } +} diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c index 7a5ef473e6..7bb3b49953 100644 --- a/drivers/led/led-gpio.c +++ b/drivers/led/led-gpio.c @@ -198,41 +198,6 @@ void led_gpio_rgb_unregister(struct gpio_led *led) #endif /* CONFIG_LED_GPIO_RGB */ #ifdef CONFIG_LED_GPIO_OF - -struct led_trg { - const char *str; - enum led_trigger trg; -}; - -static struct led_trg triggers[] = { - { .str = "heartbeat", LED_TRIGGER_HEARTBEAT, }, - { .str = "panic", LED_TRIGGER_PANIC, }, - { .str = "net", LED_TRIGGER_NET_TXRX, }, -}; - -static void led_of_parse_trigger(struct led *led, struct device_node *np) -{ - const char *trigger; - int i; - - trigger = of_get_property(np, "linux,default-trigger", NULL); - if (!trigger) - trigger = of_get_property(np, "barebox,default-trigger", NULL); - - if (!trigger) - return; - - for (i = 0; i < ARRAY_SIZE(triggers); i++) { - struct led_trg *trg = &triggers[i]; - if (!strcmp(trg->str, trigger)) { - /* disable LED before installing trigger */ - led_set(led, 0); - led_set_trigger(trg->trg, led); - return; - } - } -} - static int led_gpio_of_probe(struct device_d *dev) { struct device_node *child; diff --git a/include/led.h b/include/led.h index dd551fe161..0217f4b3a5 100644 --- a/include/led.h +++ b/include/led.h @@ -58,6 +58,8 @@ static inline void led_trigger(enum led_trigger trigger, enum trigger_type type) int led_get_trigger(enum led_trigger trigger); +void led_of_parse_trigger(struct led *led, struct device_node *np); + /* gpio LED support */ struct gpio_led { int gpio; -- cgit v1.2.3 From 767c6b4a814a2a000f3bedff44ab028699c15b55 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 28 Feb 2014 13:30:09 +0100 Subject: led: Add default-on trigger Signed-off-by: Sascha Hauer --- drivers/led/core.c | 1 + drivers/led/led-triggers.c | 3 +++ include/led.h | 1 + 3 files changed, 5 insertions(+) (limited to 'include') diff --git a/drivers/led/core.c b/drivers/led/core.c index 422c0ad614..30b016bb34 100644 --- a/drivers/led/core.c +++ b/drivers/led/core.c @@ -163,6 +163,7 @@ static struct led_trg triggers[] = { { .str = "heartbeat", LED_TRIGGER_HEARTBEAT, }, { .str = "panic", LED_TRIGGER_PANIC, }, { .str = "net", LED_TRIGGER_NET_TXRX, }, + { .str = "default-on", LED_TRIGGER_DEFAULT_ON, }, }; void led_of_parse_trigger(struct led *led, struct device_node *np) diff --git a/drivers/led/led-triggers.c b/drivers/led/led-triggers.c index 7555eee3af..5eaf732764 100644 --- a/drivers/led/led-triggers.c +++ b/drivers/led/led-triggers.c @@ -124,6 +124,9 @@ int led_set_trigger(enum led_trigger trigger, struct led *led) triggers[trigger].led = led; + if (trigger == LED_TRIGGER_DEFAULT_ON) + led_set(triggers[trigger].led, triggers[trigger].led->max_value); + return 0; } diff --git a/include/led.h b/include/led.h index 0217f4b3a5..f17621e164 100644 --- a/include/led.h +++ b/include/led.h @@ -33,6 +33,7 @@ enum led_trigger { LED_TRIGGER_NET_RX, LED_TRIGGER_NET_TX, LED_TRIGGER_NET_TXRX, + LED_TRIGGER_DEFAULT_ON, LED_TRIGGER_MAX, }; -- cgit v1.2.3