[PATCH v3 03/10] of: Add PWM support.
Arnd Bergmann
arnd at arndb.de
Wed Feb 22 11:15:11 EST 2012
On Wednesday 22 February 2012, Thierry Reding wrote:
> This patch adds helpers to support device tree bindings for the generic
> PWM API. Device tree binding documentation for PWM controllers is also
> provided.
>
> Signed-off-by: Thierry Reding <thierry.reding at avionic-design.de>
>
> Documentation/devicetree/bindings/pwm/pwm.txt | 48 +++++++++
> drivers/of/Kconfig | 6 +
> drivers/of/Makefile | 1 +
> drivers/of/pwm.c | 130 +++++++++++++++++++++++++
> include/linux/of_pwm.h | 51 ++++++++++
> include/linux/pwm.h | 17 +++
I think it would make more sense to stick the device tree specific parts
into drivers/pwm/of.c instead of drivers/of/pwm.c, but it's not a strong
preference on my part.
> @@ -0,0 +1,48 @@
> +Specifying PWM information for devices
> +======================================
> +
> +1) PWM user nodes
> +-----------------
> +
> +PWM users should specify a list of PWM devices that they want to use
> +with a property containing a 'pwm-list':
> +
> + pwm-list ::= <single-pwm> [pwm-list]
> + single-pwm ::= <pwm-phandle> <pwm-specifier>
> + pwm-phandle : phandle to PWM controller node
> + pwm-specifier : array of #pwm-cells specifying the given PWM
> + (controller specific)
> +
> +PWM properties should be named "[<name>-]pwms". Exact meaning of each
> +pwms property must be documented in the device tree binding for each
> +device.
> +
> +The following example could be used to describe a PWM-based backlight
> +device:
> +
> + pwm: pwm {
> + #pwm-cells = <2>;
> + };
> +
> + [...]
> +
> + bl: backlight {
> + pwms = <&pwm 0 5000000>;
> + };
> +
> +pwm-specifier typically encodes the chip-relative PWM number and the PWM
> +period in nanoseconds.
I like these bindings, this looks very straightforward to use while also
able to describe all possible cases.
> +/**
> + * of_node_to_pwmchip() - finds the PWM chip associated with a device node
> + * @np: device node of the PWM chip
> + *
> + * Returns a pointer to the PWM chip associated with the specified device
> + * node or NULL if the device node doesn't represent a PWM chip.
> + */
> +struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
> +{
> + return pwmchip_find(np, of_pwmchip_is_match);
> +}
> +
> +int of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args,
> + struct pwm_spec *spec)
> +{
> + if (pc->of_pwm_n_cells < 2)
> + return -EINVAL;
> +
> + if (args->args_count < pc->of_pwm_n_cells)
> + return -EINVAL;
> +
> + if (args->args[0] >= pc->npwm)
> + return -EINVAL;
> +
> + if (spec)
> + spec->period = args->args[1];
> +
> + return args->args[0];
> +}
I'm not sure why these functions are global. They are clearly marked
so in your header file, but it seems that these are an implementation
detail that neither a pwm controller driver not a driver using one
would need to use directly.
> +/**
> + * of_get_named_pwm() - get a PWM number and period to use with the PWM API
> + * @np: device node to get the PWM from
> + * @propname: property name containing PWM specifier(s)
> + * @index: index of the PWM
> + * @spec: a pointer to a struct pwm_spec to fill in
> + *
> + * Returns PWM number to use with the Linux generic PWM API or a negative
> + * error code on failure. If @spec is not NULL the function fills in the
> + * values parsed from the device tree.
> + */
> +int of_get_named_pwm(struct device_node *np, const char *propname,
> + int index, struct pwm_spec *spec)
> +{
This interface does not feel right to me, in multiple ways:
* I would expect to pass a struct device in, not a device_node.
* Why not include the pwm_request() call in this and return the
pwm_device directly? You said that you want to get rid of the
pwm_id eventually, which is a good idea, but this interface still
forces one to use it.
* It is not clear what a pwm_spec is used for, or why a device
driver would need to be bothered by this. Maybe it just needs
more explanation, but it seems to me that if you do the previous
change, the pwm_spec would not be needed either.
> +EXPORT_SYMBOL(of_get_named_pwm);
EXPORT_SYMBOL_GPL?
> +static inline int of_get_named_pwm(struct device_node *np,
> + const char *propname, int index,
> + unsigned int *period_ns)
> +{
The function prototype does not match.
Arnd
More information about the linux-arm-kernel
mailing list