Hello Masahiro, On Wed, 15 Jul 2015 17:16:16 +0900, Masahiro Yamada <yamada.masah...@socionext.com> wrote:
> Now, a simple pinctrl patch is being proposed by Simon. > http://patchwork.ozlabs.org/patch/487801/ > > In the design above, as you see, the uclass is just like a wrapper layer > to invoke .request and .get_periph_id of low-level drivers. > In other words, it is Do-It-Yourself thing, so it is up to you how to identify > which peripheral is being handled in your .get_periph_id(). > > And here is one example for how a low-level pinctrl driver could be > implemented. > http://patchwork.ozlabs.org/patch/487874/ > > As you see in the thread, honestly, I do not like this approach. > > It is true that you can implement .get_periph_id in your driver > better than parsing "interrupts" properties, but I guess > many drivers would follow the rockchip implmentation because > no helpful infrastructure is provided by the uclass (at least now). > > Device trees describe hardwares in a way independent of software > that they are used with. So, identical device trees can be (should be) > used with U-Boot as well as Linux or whatever. > > Thus, I want the pinctrl can be controllable by device trees in the same way > of Linux, that is, by parsing "pinctrl-names" and "pinctrl-<N>" properties. > > Of course, it would be possible to do it in my own .get_periph_id, > but "pinctrl-names" and "pinctrl-<N>" are too generic to be done in each > low-level driver. > > In this series, I'd like to propose to support it in the uclass, so that > we can easily reuse device trees for pinctrl. > Please put it on the table for discussion. > > Let me explain how it works. > > The basic idea is pretty much like Linux, but it has been much simplified > because full-support of the Linux's pinctrl is too much a burden for a > boot-loader. > > Device Tree > ----------- > > To use pinctrl from each peripheral, add some properties in the device node. > > "pinctrl-names" is a list of pin states. The "default" state is mandatory, > and it would probably be enough for U-Boot. But, in order to show how it > works, > say the example device supports two states: "default" and "sleep". > In this case, the properties should be like this. > > pinctrl-names = "default", "sleep"; > > And then, add as many "pinctrl-<N>" properties as the number of states. > > pinctrl-0 = <phandle to default config node>; > pinctrl-1 = <phandle to sleep config node>; > > Here, pinctrl-0, pinctrl-1 corresponds to "default", "sleep", respectively. > > The config nodes are (direct or indirect) children of a pinctrl device. > > To sum up, the device tree would be like this: > > foo { > compatible = "..."; > reg = <...>; > pinctrl-names = "default", "sleep"; > pinctrl-0 = <&foo_default_pin>; > pinctrl-1 = <&foo_sleep_pin>; > ... > }; > > pinctrl { > compatible = "..."; > reg = <...>; > foo_default_pin: foo_default { > groups = "..."; > functions = "..."; > }; > foo_sleep_pin: foo_sleep { > groups = "..."; > functions = "..."; > }; > }; > > API > --- > > > To set a device into a particular pin state, call > int pinctrl_set_state(struct udevice *dev, const char *state_name). > > For example, if you want to set the foo device into the sleep state, > you can do like this: > > struct udevice *foo_dev; > > (device_get or whatever) > > pinctrl_set_state(foo_dev, "sleep"); > > When each device is probed, pinctrl_init() is invoked, > which initializes some pinctrl-specific parameters and set it into "default" > pin state. Because it is automatically done by the core of driver model, > when a device is probed, its pins are in the "default" state. > > Implementation of low-level driver > ---------------------------------- > > Currently, two methods are supported in the pinctrl operation: > struct pinctrl_ops { > int (*pinmux_set) (struct udevice *dev, const char *group, > const char *function); > int (*pinconf_set) (struct udevice *dev, const char *group, > const char *conf_param, unsigned conf_arg); > }; > > They are used to change pin-mux, pin-conf, respectively. > > If the pin-config node for the target pin-state is like this, > i2c_default_pin: i2c_default { > groups = "i2c-0a"; > functions = "i2c-0"; > }; > > Your pinmux_set() is called with "i2c-0a" for the group and "i2c-0" > for the function. > > It is totally up to you what you do for each group & function. > > Difference from Linux pinctrl (limitation) > ----------------------------------------- > > As you can see in pinctrl drivers in Linux (drivers/pinctrl/*), > the drivers usually contain huge tables for pins, groups, functions,... > But I do not want to force that for U-Boot. > > In Linux, "group" represents a group of pins although a group sometimes > consists of a signle pin (like GPIO). Pin-muxing is available only against > groups, while pin-conf is supported for both pins and groups. > > In contrast, in U-Boot, "pins" and "groups" are handled exactly in the same > way, > so you can use either to specify the target of pin-mux or pin-conf. > > Pin/group tables are not required for U-boot pinctrl drivers, so > we never know which pins belong to which group, function, that is, > we can not avoid conflicts on pins. > > For example, let's say some pins are shared between UART0 and I2C0. > In this case, Linux pinctrl does not allow to use them simultaneously, > while U-boot pinctrl does not (can not) care about it. > > If you want to use multiple functions that share the same pins, > you must make sure pin-muxing is correctly set with pinctrl_set_state(). > > TODO > ---- > > [1] Pinctrl drivers are usually used with device trees (or ACPI), but > not all the boards in U-boot support device tree. > I will add board file support (plat data) later. > (we will need some function to register pin settings array) > > [2] SPL support is not completed. Tweak Kconfig and Makefile a little. > This should be easy. > > [3] Currently, properties other than "function" are assumed > as pin-conf parameters. Perhaps, should we filter out > unsupported properties? A table for supported properties > such "bias-pull-up", "driver-strength", etc. ? > > [4] For "function", "groups" should be able to be omitted. > > Comments are welcome. A very general comment for now: the above is absolutely too long for a commit message. It should be a patman commit or series note, or better yet, a cover letter, or, better still, rewritten into a doc/README.* file (except for the comparison with Simon's patch, which should not be in a README but remain a commit note). Amicalement, -- Albert. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot