Message ID | 1417131990-17954-2-git-send-email-rjui@broadcom.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Nov 28, 2014 at 12:46 AM, Ray Jui <rjui@broadcom.com> wrote: > Device tree binding documentation for Broadcom Cygnus pinctrl driver > > Signed-off-by: Ray Jui <rjui@broadcom.com> > Reviewed-by: Scott Branden <sbranden@broadcom.com> > --- > .../bindings/pinctrl/brcm,cygnus-pinctrl.txt | 92 ++++++++++++++++++++ > 1 file changed, 92 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt > > diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt > new file mode 100644 > index 0000000..86e4579 > --- /dev/null > +++ b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt > @@ -0,0 +1,92 @@ > +Broadcom Cygnus Pin Controller > + > +The Cygnus pin controller supports setting the alternate functions of groups > +of pins. Pinmux configuration on individual pins is not supported by the > +Cygnus A0 SoC. > + > +Required properties: > + > +- compatible: > + Must be "brcm,cygnus-pinctrl" > + > +- reg: > + Define the base and range of the I/O address space that contain the Cygnus > +pin control registers The following is subnodes. Indicate clearly in the binding that these are *not* properties of the main node, but individual subnodes. > +- brcm,groups: > + This can be strings of one or more group names. This defines the group(s) > +that one wants to configure > + > +- brcm,function: > + This is the alternate function that one wants to configure to. Valid > +alternate functions are "alt1", "alt2", "alt3", "alt4" NAK. We have standardized bindings for groups and functions, and there are pending patches from Sören Brinkmann adding this to the pinctrl DT parsing core. Just use "groups" and "function" and refer to Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt Then "alt1", "alt2" etc are non-functional names of functions. Use the real function names, like "spi0" or so. This alt-business seems to be just a shortcut to make it simple, don't do that. Then you use e.g. "spi0" as a group name. I prefer you call that "spi0_grp" or something to say it is a group of pins associated with spi0, as spi0 is actually the function. If unsure of the definitions of group and function, refer to Documentation/pinctrl.txt Yours, Linus Walleij
On 1/9/2015 2:12 AM, Linus Walleij wrote: > On Fri, Nov 28, 2014 at 12:46 AM, Ray Jui <rjui@broadcom.com> wrote: > >> Device tree binding documentation for Broadcom Cygnus pinctrl driver >> >> Signed-off-by: Ray Jui <rjui@broadcom.com> >> Reviewed-by: Scott Branden <sbranden@broadcom.com> >> --- >> .../bindings/pinctrl/brcm,cygnus-pinctrl.txt | 92 ++++++++++++++++++++ >> 1 file changed, 92 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt >> >> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt >> new file mode 100644 >> index 0000000..86e4579 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt >> @@ -0,0 +1,92 @@ >> +Broadcom Cygnus Pin Controller >> + >> +The Cygnus pin controller supports setting the alternate functions of groups >> +of pins. Pinmux configuration on individual pins is not supported by the >> +Cygnus A0 SoC. >> + >> +Required properties: >> + >> +- compatible: >> + Must be "brcm,cygnus-pinctrl" >> + >> +- reg: >> + Define the base and range of the I/O address space that contain the Cygnus >> +pin control registers > > The following is subnodes. Indicate clearly in the binding that these are > *not* properties of the main node, but individual subnodes. > Right. I'll fix the document. >> +- brcm,groups: >> + This can be strings of one or more group names. This defines the group(s) >> +that one wants to configure >> + >> +- brcm,function: >> + This is the alternate function that one wants to configure to. Valid >> +alternate functions are "alt1", "alt2", "alt3", "alt4" > > NAK. We have standardized bindings for groups and functions, > and there are pending patches from Sören Brinkmann adding > this to the pinctrl DT parsing core. > > Just use "groups" and "function" and refer to > Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > Then "alt1", "alt2" etc are non-functional names of functions. > Use the real function names, like "spi0" or so. This > alt-business seems to be just a shortcut to make it > simple, don't do that. > > Then you use e.g. "spi0" as a group name. I prefer you > call that "spi0_grp" or something to say it is a group of > pins associated with spi0, as spi0 is actually the > function. > Hmmm, I did this by following brcm,bcm11351-pinctrl.txt: - function: String. Specifies the pin mux selection. Values must be one of: "alt1", "alt2", "alt3", "alt4" But you are right, in the pinctrl binding document it describes the generic pin multiplexing nodes use "function" and "group". Let me try to explain how the Cygnus pinctrl controller works and maybe you can help to comment whether or not it's suitable for what's described in pinctrl-binding.txt for the usage of "function" and "group". The Cygnus pinctrl contoller has a limitation that the mux configuration can only be group based. "group" here is a real configuration in the Cygnus pinctrl controller registers. One can configure a "group" to alternate function 1, 2, 3, or 4. For example, the group "lcd" covers 30 pins. When I configure "lcd" to alternate function 1, all 30 pins are muxed to LCD function. When configured to function 2, all pins are muxed to SRAM function. Now, here comes the issue, when configured to function 3, pins 1-15 and 20-30 become GPIO function, but pins 16-19 becomes SPI5 function. When it's configured to function 4, all 30 pins become GPIO. In some other cases, when I configure a group to other functions, there could be spare pins which become unused (not brought out to the pad). Or, the spare pins may also become a separate function. Based on the LCD example, I'd assume I would do the following for the default LCD function: lcd_node { group = "lcd_grp"; function = "lcd"; }; And in the case of function 3, I would call the function "spi5" and assume the rest of pins become either GPIO (or unused)? spi5_node { group = "lcd_grp"; function = "spi5"; }; > If unsure of the definitions of group and function, refer > to Documentation/pinctrl.txt > > Yours, > Linus Walleij >
On Fri, Jan 9, 2015 at 7:26 PM, Ray Jui <rjui@broadcom.com> wrote: > On 1/9/2015 2:12 AM, Linus Walleij wrote: >> Just use "groups" and "function" and refer to >> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt >> >> Then "alt1", "alt2" etc are non-functional names of functions. >> Use the real function names, like "spi0" or so. This >> alt-business seems to be just a shortcut to make it >> simple, don't do that. >> >> Then you use e.g. "spi0" as a group name. I prefer you >> call that "spi0_grp" or something to say it is a group of >> pins associated with spi0, as spi0 is actually the >> function. >> > Hmmm, I did this by following brcm,bcm11351-pinctrl.txt: > - function: String. Specifies the pin mux selection. Values must be one > of: "alt1", "alt2", "alt3", "alt4" > > But you are right, in the pinctrl binding document it describes the > generic pin multiplexing nodes use "function" and "group". Note "function" and "groups". Note groups is pluralis. You can select multiple groups for a single function. > For example, the group "lcd" covers 30 pins. When I configure "lcd" to > alternate function 1, all 30 pins are muxed to LCD function. When > configured to function 2, all pins are muxed to SRAM function. Now, here > comes the issue, when configured to function 3, pins 1-15 and 20-30 > become GPIO function, but pins 16-19 becomes SPI5 function. When it's > configured to function 4, all 30 pins become GPIO. I would split the use case in two groups for LCD and SRAM, and three groups for GPIO: "lcd_grp", "sram_grp", "gpio-1-15_grp", "gpio-16-19_grp", "gpio-20-30_grp", "spi5_grp" Valid combinations become function = "lcd" groups = "lcd_grp"; function = "sram" groups = "sram_grp" For all GPIO only this: function = "gpio" groups = "gpio-1-16_grp", "gpio-16-19_grp", "gpio-20-30_grp" For a combined GPIO+SPI: function = "gpio" groups = "gpio-1-16_grp", "gpio-20-30_grp" function = "spi5" groups = "spi5_grp" The pinctrl runtile will protest if you try to combine spi5_grp with gpio-16-19_grp. > In some other cases, when I configure a group to other functions, there > could be spare pins which become unused (not brought out to the pad). > Or, the spare pins may also become a separate function. That's cool. > Based on the LCD example, I'd assume I would do the following for the > default LCD function: > > lcd_node { > group = "lcd_grp"; > function = "lcd"; > }; > > And in the case of function 3, I would call the function "spi5" and > assume the rest of pins become either GPIO (or unused)? > > spi5_node { > group = "lcd_grp"; > function = "spi5"; > }; Looks cool per above. You need some clever code in the driver to handle double-configuration of registers and so on, but I think it can be done. Using pin control as a GPIO backend can be a bit tricky and will need some testing and elaboration, but the subsystem will block collisions. Yours, Linus Walleij
On 1/13/2015 12:20 AM, Linus Walleij wrote: > On Fri, Jan 9, 2015 at 7:26 PM, Ray Jui <rjui@broadcom.com> wrote: >> On 1/9/2015 2:12 AM, Linus Walleij wrote: > >>> Just use "groups" and "function" and refer to >>> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt >>> >>> Then "alt1", "alt2" etc are non-functional names of functions. >>> Use the real function names, like "spi0" or so. This >>> alt-business seems to be just a shortcut to make it >>> simple, don't do that. >>> >>> Then you use e.g. "spi0" as a group name. I prefer you >>> call that "spi0_grp" or something to say it is a group of >>> pins associated with spi0, as spi0 is actually the >>> function. >>> >> Hmmm, I did this by following brcm,bcm11351-pinctrl.txt: >> - function: String. Specifies the pin mux selection. Values must be one >> of: "alt1", "alt2", "alt3", "alt4" >> >> But you are right, in the pinctrl binding document it describes the >> generic pin multiplexing nodes use "function" and "group". > > Note "function" and "groups". Note groups is pluralis. You can > select multiple groups for a single function. > >> For example, the group "lcd" covers 30 pins. When I configure "lcd" to >> alternate function 1, all 30 pins are muxed to LCD function. When >> configured to function 2, all pins are muxed to SRAM function. Now, here >> comes the issue, when configured to function 3, pins 1-15 and 20-30 >> become GPIO function, but pins 16-19 becomes SPI5 function. When it's >> configured to function 4, all 30 pins become GPIO. > > I would split the use case in two groups for LCD and SRAM, > and three groups for GPIO: > "lcd_grp", "sram_grp", "gpio-1-15_grp", > "gpio-16-19_grp", "gpio-20-30_grp", "spi5_grp" > > Valid combinations become > > function = "lcd" > groups = "lcd_grp"; > > function = "sram" > groups = "sram_grp" > > For all GPIO only this: > > function = "gpio" > groups = "gpio-1-16_grp", "gpio-16-19_grp", "gpio-20-30_grp" > > For a combined GPIO+SPI: > > function = "gpio" > groups = "gpio-1-16_grp", "gpio-20-30_grp" > > function = "spi5" > groups = "spi5_grp" > > The pinctrl runtile will protest if you try to combine spi5_grp > with gpio-16-19_grp. > Okay this makes sense. Thanks. >> In some other cases, when I configure a group to other functions, there >> could be spare pins which become unused (not brought out to the pad). >> Or, the spare pins may also become a separate function. > > That's cool. > >> Based on the LCD example, I'd assume I would do the following for the >> default LCD function: >> >> lcd_node { >> group = "lcd_grp"; >> function = "lcd"; >> }; >> >> And in the case of function 3, I would call the function "spi5" and >> assume the rest of pins become either GPIO (or unused)? >> >> spi5_node { >> group = "lcd_grp"; >> function = "spi5"; >> }; > > Looks cool per above. > > You need some clever code in the driver to handle double-configuration > of registers and so on, but I think it can be done. Let me see what I can come up with. > > Using pin control as a GPIO backend can be a bit tricky and will need > some testing and elaboration, but the subsystem will block collisions. > > Yours, > Linus Walleij >
On 1/13/2015 12:20 AM, Linus Walleij wrote: > On Fri, Jan 9, 2015 at 7:26 PM, Ray Jui <rjui@broadcom.com> wrote: >> On 1/9/2015 2:12 AM, Linus Walleij wrote: > >>> Just use "groups" and "function" and refer to >>> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt >>> >>> Then "alt1", "alt2" etc are non-functional names of functions. >>> Use the real function names, like "spi0" or so. This >>> alt-business seems to be just a shortcut to make it >>> simple, don't do that. >>> >>> Then you use e.g. "spi0" as a group name. I prefer you >>> call that "spi0_grp" or something to say it is a group of >>> pins associated with spi0, as spi0 is actually the >>> function. >>> >> Hmmm, I did this by following brcm,bcm11351-pinctrl.txt: >> - function: String. Specifies the pin mux selection. Values must be one >> of: "alt1", "alt2", "alt3", "alt4" >> >> But you are right, in the pinctrl binding document it describes the >> generic pin multiplexing nodes use "function" and "group". > > Note "function" and "groups". Note groups is pluralis. You can > select multiple groups for a single function. > >> For example, the group "lcd" covers 30 pins. When I configure "lcd" to >> alternate function 1, all 30 pins are muxed to LCD function. When >> configured to function 2, all pins are muxed to SRAM function. Now, here >> comes the issue, when configured to function 3, pins 1-15 and 20-30 >> become GPIO function, but pins 16-19 becomes SPI5 function. When it's >> configured to function 4, all 30 pins become GPIO. > > I would split the use case in two groups for LCD and SRAM, > and three groups for GPIO: > "lcd_grp", "sram_grp", "gpio-1-15_grp", > "gpio-16-19_grp", "gpio-20-30_grp", "spi5_grp" > > Valid combinations become > > function = "lcd" > groups = "lcd_grp"; > > function = "sram" > groups = "sram_grp" > > For all GPIO only this: > > function = "gpio" > groups = "gpio-1-16_grp", "gpio-16-19_grp", "gpio-20-30_grp" > > For a combined GPIO+SPI: > > function = "gpio" > groups = "gpio-1-16_grp", "gpio-20-30_grp" > > function = "spi5" > groups = "spi5_grp" > > The pinctrl runtile will protest if you try to combine spi5_grp > with gpio-16-19_grp. > >> In some other cases, when I configure a group to other functions, there >> could be spare pins which become unused (not brought out to the pad). >> Or, the spare pins may also become a separate function. > > That's cool. > >> Based on the LCD example, I'd assume I would do the following for the >> default LCD function: >> >> lcd_node { >> group = "lcd_grp"; >> function = "lcd"; >> }; >> >> And in the case of function 3, I would call the function "spi5" and >> assume the rest of pins become either GPIO (or unused)? >> >> spi5_node { >> group = "lcd_grp"; >> function = "spi5"; >> }; > > Looks cool per above. > > You need some clever code in the driver to handle double-configuration > of registers and so on, but I think it can be done. > > Using pin control as a GPIO backend can be a bit tricky and will need > some testing and elaboration, but the subsystem will block collisions. > > Yours, > Linus Walleij > Hi Linus, I have another question here. In the B0 revision of our Cygnus chip, the ASIC team added a feature to allow individual pins to be muxed to GPIO. The pinmux controller can still only do group-based muxing in general, but at the same time, you can override most (but not all) individual pins to GPIO. I believe this HW design actually forces us to mix use "groups" and "pins" in DT. For example, assuming we mux pins 1 - 10 as MMC (one cmd line, one clk line, and 8 data lines). One might make the decision that he only needs 4 data lines instead of 8 data lines, and he wants to free up the 4 data lines and uses as GPIO. Based on this example, is the following DT configuration valid? sd_node { function = "sd"; groups = "sd_grps"; }; gpio_node { function = "gpio"; pins = "gpio_7", "gpio_8", "gpio_9", "gpio_10"; /* assuming 1:1 mapping between gpio and pin number to make this example simple */ }; Thanks, Ray
On 1/22/2015 6:14 PM, Ray Jui wrote: > > > On 1/13/2015 12:20 AM, Linus Walleij wrote: >> On Fri, Jan 9, 2015 at 7:26 PM, Ray Jui <rjui@broadcom.com> wrote: >>> On 1/9/2015 2:12 AM, Linus Walleij wrote: >> >>>> Just use "groups" and "function" and refer to >>>> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt >>>> >>>> Then "alt1", "alt2" etc are non-functional names of functions. >>>> Use the real function names, like "spi0" or so. This >>>> alt-business seems to be just a shortcut to make it >>>> simple, don't do that. >>>> >>>> Then you use e.g. "spi0" as a group name. I prefer you >>>> call that "spi0_grp" or something to say it is a group of >>>> pins associated with spi0, as spi0 is actually the >>>> function. >>>> >>> Hmmm, I did this by following brcm,bcm11351-pinctrl.txt: >>> - function: String. Specifies the pin mux selection. Values must be one >>> of: "alt1", "alt2", "alt3", "alt4" >>> >>> But you are right, in the pinctrl binding document it describes the >>> generic pin multiplexing nodes use "function" and "group". >> >> Note "function" and "groups". Note groups is pluralis. You can >> select multiple groups for a single function. >> >>> For example, the group "lcd" covers 30 pins. When I configure "lcd" to >>> alternate function 1, all 30 pins are muxed to LCD function. When >>> configured to function 2, all pins are muxed to SRAM function. Now, here >>> comes the issue, when configured to function 3, pins 1-15 and 20-30 >>> become GPIO function, but pins 16-19 becomes SPI5 function. When it's >>> configured to function 4, all 30 pins become GPIO. >> >> I would split the use case in two groups for LCD and SRAM, >> and three groups for GPIO: >> "lcd_grp", "sram_grp", "gpio-1-15_grp", >> "gpio-16-19_grp", "gpio-20-30_grp", "spi5_grp" >> >> Valid combinations become >> >> function = "lcd" >> groups = "lcd_grp"; >> >> function = "sram" >> groups = "sram_grp" >> >> For all GPIO only this: >> >> function = "gpio" >> groups = "gpio-1-16_grp", "gpio-16-19_grp", "gpio-20-30_grp" >> >> For a combined GPIO+SPI: >> >> function = "gpio" >> groups = "gpio-1-16_grp", "gpio-20-30_grp" >> >> function = "spi5" >> groups = "spi5_grp" >> >> The pinctrl runtile will protest if you try to combine spi5_grp >> with gpio-16-19_grp. >> >>> In some other cases, when I configure a group to other functions, there >>> could be spare pins which become unused (not brought out to the pad). >>> Or, the spare pins may also become a separate function. >> >> That's cool. >> >>> Based on the LCD example, I'd assume I would do the following for the >>> default LCD function: >>> >>> lcd_node { >>> group = "lcd_grp"; >>> function = "lcd"; >>> }; >>> >>> And in the case of function 3, I would call the function "spi5" and >>> assume the rest of pins become either GPIO (or unused)? >>> >>> spi5_node { >>> group = "lcd_grp"; >>> function = "spi5"; >>> }; >> >> Looks cool per above. >> >> You need some clever code in the driver to handle double-configuration >> of registers and so on, but I think it can be done. >> >> Using pin control as a GPIO backend can be a bit tricky and will need >> some testing and elaboration, but the subsystem will block collisions. >> >> Yours, >> Linus Walleij >> > > Hi Linus, > > I have another question here. In the B0 revision of our Cygnus chip, the > ASIC team added a feature to allow individual pins to be muxed to GPIO. > The pinmux controller can still only do group-based muxing in general, > but at the same time, you can override most (but not all) individual > pins to GPIO. > > I believe this HW design actually forces us to mix use "groups" and > "pins" in DT. > > For example, assuming we mux pins 1 - 10 as MMC (one cmd line, one clk > line, and 8 data lines). One might make the decision that he only needs > 4 data lines instead of 8 data lines, and he wants to free up the 4 data > lines and uses as GPIO. Based on this example, is the following DT > configuration valid? > > sd_node { > function = "sd"; > groups = "sd_grps"; > }; > > gpio_node { > function = "gpio"; > pins = "gpio_7", "gpio_8", "gpio_9", "gpio_10"; /* assuming 1:1 > mapping between gpio and pin number to make this example simple */ > }; > > Thanks, > > Ray > I dig into the pinctrl framework code a bit more and found that I can use pinctrl_request_gpio from the GPIO driver and implement gpio_request_enable in the pinctrl driver. The only problem I see now is that these APIs seem to expect the use of global GPIO numbers? And all pinctrl drivers I checked seem to be hard coding the GPIO to pin mapping when declaring the struct pinctrl_gpio_range array. How would this work in a system like ours that have 3 GPIO controllers and was required to use a dynamic GPIO number (i.e., we use gpio->base = -1, so it derives the base from CONFIG_ARCH_NR_GPIO and goes backwards)? I guess I can do some runtime calculation in my pinctrl driver to figure out the GPIO->pin mapping based on CONFIG_ARCH_NR_GPIO, but this is assuming that we always fix the order of the device nodes of the 3 GPIO controllers. I hope I'm not missing something here? Thanks, Ray
On Fri, Jan 23, 2015 at 3:14 AM, Ray Jui <rjui@broadcom.com> wrote: > I have another question here. In the B0 revision of our Cygnus chip, the > ASIC team added a feature to allow individual pins to be muxed to GPIO. > The pinmux controller can still only do group-based muxing in general, > but at the same time, you can override most (but not all) individual > pins to GPIO. > > I believe this HW design actually forces us to mix use "groups" and > "pins" in DT. > > For example, assuming we mux pins 1 - 10 as MMC (one cmd line, one clk > line, and 8 data lines). One might make the decision that he only needs > 4 data lines instead of 8 data lines, and he wants to free up the 4 data > lines and uses as GPIO. I would split the 8 available data lines in two groups, like "data-1-4" and "data-5-8" since the use case is such that either you use four or eight lines, not 6 or 7, either just "data-1-4" or both "data-1-4" and "data-5-8". > Based on this example, is the following DT > configuration valid? > sd_node { > function = "sd"; > groups = "sd_grps"; > }; > > gpio_node { > function = "gpio"; > pins = "gpio_7", "gpio_8", "gpio_9", "gpio_10"; /* assuming 1:1 > mapping between gpio and pin number to make this example simple */ > }; Muxing an individual GPIO from the device tree is seldom a good idea as you realized in your follow-up mail ;) But this: sd_node { function = "sd"; groups = "data-1-4", "data-5-8", "other-pin-group"; }; Is perfectly fine. One function, several groups. Yours, Linus Walleij
On Fri, Jan 23, 2015 at 7:49 AM, Ray Jui <rjui@broadcom.com> wrote: > I dig into the pinctrl framework code a bit more and found that I can > use pinctrl_request_gpio from the GPIO driver and implement > gpio_request_enable in the pinctrl driver. Yep :) ain't it nice. > The only problem I see now is that these APIs seem to expect the use of > global GPIO numbers? No they don't, only if you use the deprecated pinctrl_add_gpio_range(). Instead, when you register your struct gpio_chip, use gpiochip_add_pin_range() and this will use relative offsets without relying on global GPIO numbers. This latter call replaces pinctrl_add_gpio_range(). > I hope I'm not missing something here? You're missing gpiochip_add_pin_range() ;) Yours, Linus Walleij
On 1/30/2015 6:18 AM, Linus Walleij wrote: > On Fri, Jan 23, 2015 at 7:49 AM, Ray Jui <rjui@broadcom.com> wrote: > >> I dig into the pinctrl framework code a bit more and found that I can >> use pinctrl_request_gpio from the GPIO driver and implement >> gpio_request_enable in the pinctrl driver. > > Yep :) ain't it nice. > >> The only problem I see now is that these APIs seem to expect the use of >> global GPIO numbers? > > No they don't, only if you use the deprecated pinctrl_add_gpio_range(). > > Instead, when you register your struct gpio_chip, use > gpiochip_add_pin_range() and this will use relative offsets > without relying on global GPIO numbers. > > This latter call replaces pinctrl_add_gpio_range(). > >> I hope I'm not missing something here? > > You're missing gpiochip_add_pin_range() ;) > > Yours, > Linus Walleij > Yeah, I realized this while implementing the driver, :) I'm now in the final testing/cleaning phase of both Cygnus pinmux and gpio/pinconf driver. I really appreciate that the pinctrl framework allows the two to work seamlessly with each other and at the same time provides the necessary interface to bridge the two, :) I should be able to send out the patches of the two drivers for review sometime next week. Thanks for the help! Ray
diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt new file mode 100644 index 0000000..86e4579 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt @@ -0,0 +1,92 @@ +Broadcom Cygnus Pin Controller + +The Cygnus pin controller supports setting the alternate functions of groups +of pins. Pinmux configuration on individual pins is not supported by the +Cygnus A0 SoC. + +Required properties: + +- compatible: + Must be "brcm,cygnus-pinctrl" + +- reg: + Define the base and range of the I/O address space that contain the Cygnus +pin control registers + +- brcm,groups: + This can be strings of one or more group names. This defines the group(s) +that one wants to configure + +- brcm,function: + This is the alternate function that one wants to configure to. Valid +alternate functions are "alt1", "alt2", "alt3", "alt4" + +Each child node represents a configuration. Client devices reference the the +child node to enable the mux configuration. + +For example: + + pinctrl: pinctrl@0x0301d0c8 { + compatible = "brcm,cygnus-pinctrl"; + reg = <0x0301d0c8 0x2c>; + + i2s_0: i2s_0 { + brcm,groups = "smart_card0", "smart_card0_fcb"; + brcm,function = "alt2"; + }; + + i2s_1: i2s_1 { + brcm,groups = "smart_card1", "smart_card1_fcb"; + brcm,function = "alt2"; + }; + + spi_0: spi_0 { + brcm,groups = "spi0"; + brcm,function = "alt1"; + }; + } + + spi0@18028000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x18028000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-0 = <&spi_0>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + }; + +Consider the following snapshot of Cygnus pinmux table: + +number pin group alt1 alt2 alt3 alt4 +------ --- ---- ---- ---- ---- ---- +42 sc0_clk smart_card0 SMART CARD0 I2S_0 N/A chip_gpio24 +43 sc0_cmdvcc_l smart_card0 SMART CARD0 I2S_0 N/A STRAP +44 sc0_detect smart_card0 SMART CARD0 I2S_0 N/A chip_gpio25 +45 sc0_fcb smart_card0_fcb SMART CARD0_FCB I2S_0 N/A chip_gpio26 +46 sc0_io smart_card0 SMART CARD0 I2S_0 N/A chip_gpio27 +47 sc0_rst_l smart_card0 SMART CARD0 SPDIF N/A STRAP + +Note due to limitation of the Cygnus hardware, pinmux configuration can only +be group based. To enable I2S_0 function, one needs the following child node +configuration: + + i2s_0: i2s_0 { + brcm,groups = "smart_card0", "smart_card0_fcb"; + brcm,function = "alt2"; + }; + +This tells the Cygnus pin controller to configure groups "smart_card0" and +"smart_card0_fcb" to I2S_0. With this configuration, pins 42, 43, 44, 45, 46 +become I2C_0, and pin 47 becomes SPDIF + +Consider another example, that one wants to configure the above pins as GPIO: + + gpio_24_27: gpio_24_27 { + brcm,groups = "smart_card0", "smart_card0_fcb"; + brcm,function = "alt4"; + }; + +With the above configuration, pins 42, 44, 45, 46 become GPIO, and 43 and 47 +become reserved for STRAP