[PATCH v2 1/2] pinctrl: single: Parse gpio details from dt

From: Bharat Gooty bharat.gooty@broadcom.com
Parse different gpio properties from dt as part of probe function. This detail is required to enable pinctrl pad later when gpio lines are requested.
Signed-off-by: Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com Signed-off-by: Bharat Gooty bharat.gooty@broadcom.com Acked-by: Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com Signed-off-by: Roman Bacik roman.bacik@broadcom.com ---
- modified comment before struct single_fpiofunc_range - add pinctrl-single binding from Linux - return error from single-probe() - there is no test to be updated
.../pinctrl/pinctrl-single.txt | 255 ++++++++++++++++++ drivers/pinctrl/pinctrl-single.c | 56 ++++ 2 files changed, 311 insertions(+) create mode 100644 doc/device-tree-bindings/pinctrl/pinctrl-single.txt
diff --git a/doc/device-tree-bindings/pinctrl/pinctrl-single.txt b/doc/device-tree-bindings/pinctrl/pinctrl-single.txt new file mode 100644 index 000000000000..e705acd3612c --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/pinctrl-single.txt @@ -0,0 +1,255 @@ +One-register-per-pin type device tree based pinctrl driver + +Required properties: +- compatible : "pinctrl-single" or "pinconf-single". + "pinctrl-single" means that pinconf isn't supported. + "pinconf-single" means that generic pinconf is supported. + +- reg : offset and length of the register set for the mux registers + +- #pinctrl-cells : number of cells in addition to the index, set to 1 + for pinctrl-single,pins and 2 for pinctrl-single,bits + +- pinctrl-single,register-width : pinmux register access width in bits + +- pinctrl-single,function-mask : mask of allowed pinmux function bits + in the pinmux register + +Optional properties: +- pinctrl-single,function-off : function off mode for disabled state if + available and same for all registers; if not specified, disabling of + pin functions is ignored + +- pinctrl-single,bit-per-mux : boolean to indicate that one register controls + more than one pin, for which "pinctrl-single,function-mask" property specifies + position mask of pin. + +- pinctrl-single,drive-strength : array of value that are used to configure + drive strength in the pinmux register. They're value of drive strength + current and drive strength mask. + + /* drive strength current, mask */ + pinctrl-single,power-source = <0x30 0xf0>; + +- pinctrl-single,bias-pullup : array of value that are used to configure the + input bias pullup in the pinmux register. + + /* input, enabled pullup bits, disabled pullup bits, mask */ + pinctrl-single,bias-pullup = <0 1 0 1>; + +- pinctrl-single,bias-pulldown : array of value that are used to configure the + input bias pulldown in the pinmux register. + + /* input, enabled pulldown bits, disabled pulldown bits, mask */ + pinctrl-single,bias-pulldown = <2 2 0 2>; + + * Two bits to control input bias pullup and pulldown: User should use + pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. One bit means + pullup, and the other one bit means pulldown. + * Three bits to control input bias enable, pullup and pulldown. User should + use pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. Input bias + enable bit should be included in pullup or pulldown bits. + * Although driver could set PIN_CONFIG_BIAS_DISABLE, there's no property as + pinctrl-single,bias-disable. Because pinctrl single driver could implement + it by calling pulldown, pullup disabled. + +- pinctrl-single,input-schmitt : array of value that are used to configure + input schmitt in the pinmux register. In some silicons, there're two input + schmitt value (rising-edge & falling-edge) in the pinmux register. + + /* input schmitt value, mask */ + pinctrl-single,input-schmitt = <0x30 0x70>; + +- pinctrl-single,input-schmitt-enable : array of value that are used to + configure input schmitt enable or disable in the pinmux register. + + /* input, enable bits, disable bits, mask */ + pinctrl-single,input-schmitt-enable = <0x30 0x40 0 0x70>; + +- pinctrl-single,low-power-mode : array of value that are used to configure + low power mode of this pin. For some silicons, the low power mode will + control the output of the pin when the pad including the pin enter low + power mode. + /* low power mode value, mask */ + pinctrl-single,low-power-mode = <0x288 0x388>; + +- pinctrl-single,gpio-range : list of value that are used to configure a GPIO + range. They're value of subnode phandle, pin base in pinctrl device, pin + number in this range, GPIO function value of this GPIO range. + The number of parameters is depend on #pinctrl-single,gpio-range-cells + property. + + /* pin base, nr pins & gpio function */ + pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>; + +- interrupt-controller : standard interrupt controller binding if using + interrupts for wake-up events for example. In this case pinctrl-single + is set up as a chained interrupt controller and the wake-up interrupts + can be requested by the drivers using request_irq(). + +- #interrupt-cells : standard interrupt binding if using interrupts + +This driver assumes that there is only one register for each pin (unless the +pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as +specified in the pinctrl-bindings.txt document in this directory. + +The pin configuration nodes for pinctrl-single are specified as pinctrl +register offset and value pairs using pinctrl-single,pins. Only the bits +specified in pinctrl-single,function-mask are updated. For example, setting +a pin for a device could be done with: + + pinctrl-single,pins = <0xdc 0x118>; + +Where 0xdc is the offset from the pinctrl register base address for the +device pinctrl register, and 0x118 contains the desired value of the +pinctrl register. See the device example and static board pins example +below for more information. + +In case when one register changes more than one pin's mux the +pinctrl-single,bits need to be used which takes three parameters: + + pinctrl-single,bits = <0xdc 0x18 0xff>; + +Where 0xdc is the offset from the pinctrl register base address for the +device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to +be used when applying this change to the register. + + +Optional sub-node: In case some pins could be configured as GPIO in the pinmux +register, those pins could be defined as a GPIO range. This sub-node is required +by pinctrl-single,gpio-range property. + +Required properties in sub-node: +- #pinctrl-single,gpio-range-cells : the number of parameters after phandle in + pinctrl-single,gpio-range property. + + range: gpio-range { + #pinctrl-single,gpio-range-cells = <3>; + }; + + +Example: + +/* SoC common file */ + +/* first controller instance for pins in core domain */ +pmx_core: pinmux@4a100040 { + compatible = "pinctrl-single"; + reg = <0x4a100040 0x0196>; + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + pinctrl-single,register-width = <16>; + pinctrl-single,function-mask = <0xffff>; +}; + +/* second controller instance for pins in wkup domain */ +pmx_wkup: pinmux@4a31e040 { + compatible = "pinctrl-single"; + reg = <0x4a31e040 0x0038>; + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + pinctrl-single,register-width = <16>; + pinctrl-single,function-mask = <0xffff>; +}; + +control_devconf0: pinmux@48002274 { + compatible = "pinctrl-single"; + reg = <0x48002274 4>; /* Single register */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-single,bit-per-mux; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0x5F>; +}; + +/* third controller instance for pins in gpio domain */ +pmx_gpio: pinmux@d401e000 { + compatible = "pinconf-single"; + reg = <0xd401e000 0x0330>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <7>; + + /* sparse GPIO range could be supported */ + pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1 + &range 12 1 0 &range 13 29 1 + &range 43 1 0 &range 44 49 1 + &range 94 1 1 &range 96 2 1>; + + range: gpio-range { + #pinctrl-single,gpio-range-cells = <3>; + }; +}; + + +/* board specific .dts file */ + +&pmx_core { + + /* + * map all board specific static pins enabled by the pinctrl driver + * itself during the boot (or just set them up in the bootloader) + */ + pinctrl-names = "default"; + pinctrl-0 = <&board_pins>; + + board_pins: pinmux_board_pins { + pinctrl-single,pins = < + 0x6c 0xf + 0x6e 0xf + 0x70 0xf + 0x72 0xf + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x208 0 /* UART0_RXD (IOCFG138) */ + 0x20c 0 /* UART0_TXD (IOCFG139) */ + >; + pinctrl-single,bias-pulldown = <0 2 2>; + pinctrl-single,bias-pullup = <0 1 1>; + }; + + /* map uart2 pins */ + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0xd8 0x118 + 0xda 0 + 0xdc 0x118 + 0xde 0 + >; + }; +}; + +&control_devconf0 { + mcbsp1_pins: pinmux_mcbsp1_pins { + pinctrl-single,bits = < + 0x00 0x18 0x18 /* FSR/CLKR signal from FSX/CLKX pin */ + >; + }; + + mcbsp2_clks_pins: pinmux_mcbsp2_clks_pins { + pinctrl-single,bits = < + 0x00 0x40 0x40 /* McBSP2 CLKS from McBSP_CLKS pin */ + >; + }; + +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 7af6c5f0b037..c68d48d7fbcc 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -8,6 +8,7 @@ #include <dm.h> #include <dm/device_compat.h> #include <dm/devres.h> +#include <dm/of_access.h> #include <dm/pinctrl.h> #include <linux/libfdt.h> #include <linux/list.h> @@ -44,11 +45,27 @@ struct single_func { unsigned int *pins; };
+/** + * struct single_gpiofunc_range - pin ranges with same mux value + * @offset: offset base of pins + * @npins: number pins with the same mux value of gpio function + * @gpiofunc: mux value of gpio function + * @node: list node + */ +struct single_gpiofunc_range { + u32 offset; + u32 npins; + u32 gpiofunc; + struct list_head node; +}; + /** * struct single_priv - private data * @bits_per_pin: number of bits per pin * @npins: number of selectable pins * @pin_name: temporary buffer to store the pin name + * @functions: list pin functions + * @gpiofuncs: list gpio functions */ struct single_priv { #if (IS_ENABLED(CONFIG_SANDBOX)) @@ -58,6 +75,7 @@ struct single_priv { unsigned int npins; char pin_name[PINNAME_SIZE]; struct list_head functions; + struct list_head gpiofuncs; };
/** @@ -454,13 +472,45 @@ static int single_get_pins_count(struct udevice *dev) return priv->npins; }
+static int single_add_gpio_func(struct udevice *dev) +{ + struct single_priv *priv = dev_get_priv(dev); + const char *propname = "pinctrl-single,gpio-range"; + const char *cellname = "#pinctrl-single,gpio-range-cells"; + struct single_gpiofunc_range *range; + struct ofnode_phandle_args gpiospec; + int ret, i; + + for (i = 0; ; i++) { + ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), propname, + cellname, 0, i, &gpiospec); + /* Do not treat it as error. Only treat it as end condition. */ + if (ret) { + ret = 0; + break; + } + range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL); + if (!range) { + ret = -ENOMEM; + break; + } + range->offset = gpiospec.args[0]; + range->npins = gpiospec.args[1]; + range->gpiofunc = gpiospec.args[2]; + list_add_tail(&range->node, &priv->gpiofuncs); + } + return ret; +} + static int single_probe(struct udevice *dev) { struct single_pdata *pdata = dev_get_plat(dev); struct single_priv *priv = dev_get_priv(dev); u32 size; + int ret;
INIT_LIST_HEAD(&priv->functions); + INIT_LIST_HEAD(&priv->gpiofuncs);
size = pdata->offset + pdata->width / BITS_PER_BYTE; #if (CONFIG_IS_ENABLED(SANDBOX)) @@ -482,6 +532,12 @@ static int single_probe(struct udevice *dev) priv->npins *= (pdata->width / priv->bits_per_pin); }
+ ret = single_add_gpio_func(dev); + if (ret) { + dev_dbg(dev, "gpio functions are not added\n"); + return ret; + } + dev_dbg(dev, "%d pins\n", priv->npins); return 0; }

From: Bharat Gooty bharat.gooty@broadcom.com
Add pinctrl_ops->request api to configure pctrl pad register in gpio mode.
Signed-off-by: Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com Signed-off-by: Bharat Gooty bharat.gooty@broadcom.com Acked-by: Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com Reviewed-by: Simon Glass sjg@chromium.org
Signed-off-by: Roman Bacik roman.bacik@broadcom.com ---
(no changes since v1)
drivers/pinctrl/pinctrl-single.c | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index c68d48d7fbcc..1c250add1d73 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -250,6 +250,39 @@ static int single_get_pin_muxing(struct udevice *dev, unsigned int pin, return 0; }
+static int single_request(struct udevice *dev, int pin, int flags) +{ + struct single_priv *priv = dev_get_priv(dev); + struct single_pdata *pdata = dev_get_plat(dev); + struct single_gpiofunc_range *frange = NULL; + struct list_head *pos, *tmp; + phys_addr_t reg; + int mux_bytes = 0; + u32 data; + + /* If function mask is null, needn't enable it. */ + if (!pdata->mask) + return -ENOTSUPP; + + list_for_each_safe(pos, tmp, &priv->gpiofuncs) { + frange = list_entry(pos, struct single_gpiofunc_range, node); + if ((pin >= frange->offset + frange->npins) || + pin < frange->offset) + continue; + + mux_bytes = pdata->width / BITS_PER_BYTE; + reg = pdata->base + pin * mux_bytes; + + data = single_read(dev, reg); + data &= ~pdata->mask; + data |= frange->gpiofunc; + single_write(dev, data, reg); + break; + } + + return 0; +} + static struct single_func *single_allocate_function(struct udevice *dev, unsigned int group_pins) { @@ -590,6 +623,7 @@ const struct pinctrl_ops single_pinctrl_ops = { .get_pin_name = single_get_pin_name, .set_state = single_set_state, .get_pin_muxing = single_get_pin_muxing, + .request = single_request, };
static const struct udevice_id single_pinctrl_match[] = {

-----Original Message----- From: Roman Bacik roman.bacik@broadcom.com Sent: Friday, October 1, 2021 3:40 PM To: U-Boot Mailing List u-boot@lists.denx.de Cc: Bharat Gooty bharat.gooty@broadcom.com; Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com; Roman Bacik roman.bacik@broadcom.com; Dario Binacchi dariobin@libero.it; Pratyush Yadav p.yadav@ti.com; Simon Glass sjg@chromium.org; Vignesh Raghavendra vigneshr@ti.com Subject: [PATCH v2 1/2] pinctrl: single: Parse gpio details from dt
From: Bharat Gooty bharat.gooty@broadcom.com
Parse different gpio properties from dt as part of probe function. This detail is required to enable pinctrl pad later when gpio lines are requested.
Signed-off-by: Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com Signed-off-by: Bharat Gooty bharat.gooty@broadcom.com Acked-by: Rayagonda Kokatanur rayagonda.kokatanur@broadcom.com Signed-off-by: Roman Bacik roman.bacik@broadcom.com
- modified comment before struct single_fpiofunc_range
- add pinctrl-single binding from Linux
- return error from single-probe()
- there is no test to be updated
I will add tests to dm_test_pinctrl_single() in test/dm/pinmux.c and add a test node to arch/sandbox/dts/test.dts in version 3.
.../pinctrl/pinctrl-single.txt | 255 ++++++++++++++++++ drivers/pinctrl/pinctrl-single.c | 56 ++++ 2 files changed, 311 insertions(+) create mode 100644 doc/device-tree-bindings/pinctrl/pinctrl-single.txt
diff --git a/doc/device-tree-bindings/pinctrl/pinctrl-single.txt
b/doc/device-
tree-bindings/pinctrl/pinctrl-single.txt new file mode 100644 index 000000000000..e705acd3612c --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/pinctrl-single.txt @@ -0,0 +1,255 @@ +One-register-per-pin type device tree based pinctrl driver
+Required properties: +- compatible : "pinctrl-single" or "pinconf-single".
- "pinctrl-single" means that pinconf isn't supported.
- "pinconf-single" means that generic pinconf is supported.
+- reg : offset and length of the register set for the mux registers
+- #pinctrl-cells : number of cells in addition to the index, set to 1
- for pinctrl-single,pins and 2 for pinctrl-single,bits
+- pinctrl-single,register-width : pinmux register access width in bits
+- pinctrl-single,function-mask : mask of allowed pinmux function bits
- in the pinmux register
+Optional properties: +- pinctrl-single,function-off : function off mode for disabled state if
- available and same for all registers; if not specified, disabling of
- pin functions is ignored
+- pinctrl-single,bit-per-mux : boolean to indicate that one register
controls
- more than one pin, for which "pinctrl-single,function-mask" property
specifies
- position mask of pin.
+- pinctrl-single,drive-strength : array of value that are used to
configure
- drive strength in the pinmux register. They're value of drive
strength
- current and drive strength mask.
/* drive strength current, mask */
pinctrl-single,power-source = <0x30 0xf0>;
+- pinctrl-single,bias-pullup : array of value that are used to
configure the
- input bias pullup in the pinmux register.
/* input, enabled pullup bits, disabled pullup bits, mask
*/
pinctrl-single,bias-pullup = <0 1 0 1>;
+- pinctrl-single,bias-pulldown : array of value that are used to
configure the
- input bias pulldown in the pinmux register.
/* input, enabled pulldown bits, disabled pulldown bits,
mask
*/
pinctrl-single,bias-pulldown = <2 2 0 2>;
- Two bits to control input bias pullup and pulldown: User should use
- pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown. One bit
means
- pullup, and the other one bit means pulldown.
- Three bits to control input bias enable, pullup and pulldown. User
should
- use pinctrl-single,bias-pullup & pinctrl-single,bias-pulldown.
Input bias
- enable bit should be included in pullup or pulldown bits.
- Although driver could set PIN_CONFIG_BIAS_DISABLE, there's no
property as
- pinctrl-single,bias-disable. Because pinctrl single driver could
implement
- it by calling pulldown, pullup disabled.
+- pinctrl-single,input-schmitt : array of value that are used to
configure
- input schmitt in the pinmux register. In some silicons, there're two
input
- schmitt value (rising-edge & falling-edge) in the pinmux register.
/* input schmitt value, mask */
pinctrl-single,input-schmitt = <0x30 0x70>;
+- pinctrl-single,input-schmitt-enable : array of value that are used to
- configure input schmitt enable or disable in the pinmux register.
/* input, enable bits, disable bits, mask */
pinctrl-single,input-schmitt-enable = <0x30 0x40 0 0x70>;
+- pinctrl-single,low-power-mode : array of value that are used to
configure
- low power mode of this pin. For some silicons, the low power mode
will
- control the output of the pin when the pad including the pin enter
low
- power mode.
/* low power mode value, mask */
pinctrl-single,low-power-mode = <0x288 0x388>;
+- pinctrl-single,gpio-range : list of value that are used to configure
a GPIO
- range. They're value of subnode phandle, pin base in pinctrl device,
pin
- number in this range, GPIO function value of this GPIO range.
- The number of parameters is depend on
#pinctrl-single,gpio-range-cells
- property.
/* pin base, nr pins & gpio function */
pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>;
+- interrupt-controller : standard interrupt controller binding if using
- interrupts for wake-up events for example. In this case
pinctrl-single
- is set up as a chained interrupt controller and the wake-up
interrupts
- can be requested by the drivers using request_irq().
+- #interrupt-cells : standard interrupt binding if using interrupts
+This driver assumes that there is only one register for each pin
(unless the
+pinctrl-single,bit-per-mux is set), and uses the common pinctrl
bindings as
+specified in the pinctrl-bindings.txt document in this directory.
+The pin configuration nodes for pinctrl-single are specified as pinctrl +register offset and value pairs using pinctrl-single,pins. Only the
bits
+specified in pinctrl-single,function-mask are updated. For example,
setting
+a pin for a device could be done with:
- pinctrl-single,pins = <0xdc 0x118>;
+Where 0xdc is the offset from the pinctrl register base address for the +device pinctrl register, and 0x118 contains the desired value of the +pinctrl register. See the device example and static board pins example +below for more information.
+In case when one register changes more than one pin's mux the +pinctrl-single,bits need to be used which takes three parameters:
- pinctrl-single,bits = <0xdc 0x18 0xff>;
+Where 0xdc is the offset from the pinctrl register base address for the +device pinctrl register, 0x18 is the desired value, and 0xff is the sub
mask to
+be used when applying this change to the register.
+Optional sub-node: In case some pins could be configured as GPIO in the pinmux +register, those pins could be defined as a GPIO range. This sub-node is required +by pinctrl-single,gpio-range property.
+Required properties in sub-node: +- #pinctrl-single,gpio-range-cells : the number of parameters after
phandle
in
- pinctrl-single,gpio-range property.
- range: gpio-range {
#pinctrl-single,gpio-range-cells = <3>;
- };
+Example:
+/* SoC common file */
+/* first controller instance for pins in core domain */ +pmx_core: pinmux@4a100040 {
- compatible = "pinctrl-single";
- reg = <0x4a100040 0x0196>;
- #address-cells = <1>;
- #size-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-controller;
- pinctrl-single,register-width = <16>;
- pinctrl-single,function-mask = <0xffff>;
+};
+/* second controller instance for pins in wkup domain */ +pmx_wkup: pinmux@4a31e040 {
- compatible = "pinctrl-single";
- reg = <0x4a31e040 0x0038>;
- #address-cells = <1>;
- #size-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-controller;
- pinctrl-single,register-width = <16>;
- pinctrl-single,function-mask = <0xffff>;
+};
+control_devconf0: pinmux@48002274 {
- compatible = "pinctrl-single";
- reg = <0x48002274 4>; /* Single register */
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-single,bit-per-mux;
- pinctrl-single,register-width = <32>;
- pinctrl-single,function-mask = <0x5F>;
+};
+/* third controller instance for pins in gpio domain */ +pmx_gpio: pinmux@d401e000 {
- compatible = "pinconf-single";
- reg = <0xd401e000 0x0330>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
- pinctrl-single,register-width = <32>;
- pinctrl-single,function-mask = <7>;
- /* sparse GPIO range could be supported */
- pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
&range 12 1 0 &range 13 29 1
&range 43 1 0 &range 44 49 1
&range 94 1 1 &range 96 2 1>;
- range: gpio-range {
#pinctrl-single,gpio-range-cells = <3>;
- };
+};
+/* board specific .dts file */
+&pmx_core {
- /*
* map all board specific static pins enabled by the pinctrl
driver
* itself during the boot (or just set them up in the bootloader)
*/
- pinctrl-names = "default";
- pinctrl-0 = <&board_pins>;
- board_pins: pinmux_board_pins {
pinctrl-single,pins = <
0x6c 0xf
0x6e 0xf
0x70 0xf
0x72 0xf
>;
- };
- uart0_pins: pinmux_uart0_pins {
pinctrl-single,pins = <
0x208 0 /* UART0_RXD (IOCFG138) */
0x20c 0 /* UART0_TXD (IOCFG139) */
>;
pinctrl-single,bias-pulldown = <0 2 2>;
pinctrl-single,bias-pullup = <0 1 1>;
- };
- /* map uart2 pins */
- uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
0xd8 0x118
0xda 0
0xdc 0x118
0xde 0
>;
- };
+};
+&control_devconf0 {
- mcbsp1_pins: pinmux_mcbsp1_pins {
pinctrl-single,bits = <
0x00 0x18 0x18 /* FSR/CLKR signal from FSX/CLKX
pin
*/
>;
- };
- mcbsp2_clks_pins: pinmux_mcbsp2_clks_pins {
pinctrl-single,bits = <
0x00 0x40 0x40 /* McBSP2 CLKS from McBSP_CLKS
pin */
>;
- };
+};
+&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
+};
+&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
+}; diff --git a/drivers/pinctrl/pinctrl-single.c
b/drivers/pinctrl/pinctrl-single.c
index 7af6c5f0b037..c68d48d7fbcc 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -8,6 +8,7 @@ #include <dm.h> #include <dm/device_compat.h> #include <dm/devres.h> +#include <dm/of_access.h> #include <dm/pinctrl.h> #include <linux/libfdt.h> #include <linux/list.h> @@ -44,11 +45,27 @@ struct single_func { unsigned int *pins; };
+/**
- struct single_gpiofunc_range - pin ranges with same mux value
- @offset: offset base of pins
- @npins: number pins with the same mux value of gpio function
- @gpiofunc: mux value of gpio function
- @node: list node
- */
+struct single_gpiofunc_range {
- u32 offset;
- u32 npins;
- u32 gpiofunc;
- struct list_head node;
+};
/**
- struct single_priv - private data
- @bits_per_pin: number of bits per pin
- @npins: number of selectable pins
- @pin_name: temporary buffer to store the pin name
- @functions: list pin functions
*/
- @gpiofuncs: list gpio functions
struct single_priv { #if (IS_ENABLED(CONFIG_SANDBOX)) @@ -58,6 +75,7 @@ struct single_priv { unsigned int npins; char pin_name[PINNAME_SIZE]; struct list_head functions;
- struct list_head gpiofuncs;
};
/** @@ -454,13 +472,45 @@ static int single_get_pins_count(struct udevice *dev) return priv->npins; }
+static int single_add_gpio_func(struct udevice *dev) +{
- struct single_priv *priv = dev_get_priv(dev);
- const char *propname = "pinctrl-single,gpio-range";
- const char *cellname = "#pinctrl-single,gpio-range-cells";
- struct single_gpiofunc_range *range;
- struct ofnode_phandle_args gpiospec;
- int ret, i;
- for (i = 0; ; i++) {
ret = ofnode_parse_phandle_with_args(dev_ofnode(dev),
propname,
cellname, 0, i,
&gpiospec);
/* Do not treat it as error. Only treat it as end
condition. */
if (ret) {
ret = 0;
break;
}
range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
if (!range) {
ret = -ENOMEM;
break;
}
range->offset = gpiospec.args[0];
range->npins = gpiospec.args[1];
range->gpiofunc = gpiospec.args[2];
list_add_tail(&range->node, &priv->gpiofuncs);
- }
- return ret;
+}
static int single_probe(struct udevice *dev) { struct single_pdata *pdata = dev_get_plat(dev); struct single_priv *priv = dev_get_priv(dev); u32 size;
int ret;
INIT_LIST_HEAD(&priv->functions);
INIT_LIST_HEAD(&priv->gpiofuncs);
size = pdata->offset + pdata->width / BITS_PER_BYTE; #if (CONFIG_IS_ENABLED(SANDBOX))
@@ -482,6 +532,12 @@ static int single_probe(struct udevice *dev) priv->npins *= (pdata->width / priv->bits_per_pin); }
- ret = single_add_gpio_func(dev);
- if (ret) {
dev_dbg(dev, "gpio functions are not added\n");
return ret;
- }
- dev_dbg(dev, "%d pins\n", priv->npins); return 0;
}
2.17.1
participants (1)
-
Roman Bacik