提交 e3c47051 编写于 作者: L Laurent Pinchart 提交者: Simon Horman

sh-pfc: Configure pins as GPIOs at request time when handled externally

When a GPIO is handled by a separate driver the pinmux
gpio_set_direction() handler won't be called. The pin mux type then need
to be configured to GPIO at request time.
Signed-off-by: NLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: NSimon Horman <horms+renesas@verge.net.au>
上级 ceef91dc
...@@ -268,7 +268,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) ...@@ -268,7 +268,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
int ret; int ret;
switch (pinmux_type) { switch (pinmux_type) {
case PINMUX_TYPE_GPIO:
case PINMUX_TYPE_FUNCTION: case PINMUX_TYPE_FUNCTION:
range = NULL; range = NULL;
break; break;
...@@ -297,6 +297,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) ...@@ -297,6 +297,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
enum_id = 0; enum_id = 0;
field = 0; field = 0;
value = 0; value = 0;
/* Iterate over all the configuration fields we need to update. */
while (1) { while (1) {
pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
if (pos < 0) if (pos < 0)
...@@ -305,18 +307,20 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) ...@@ -305,18 +307,20 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
if (!enum_id) if (!enum_id)
break; break;
/* first check if this is a function enum */ /* Check if the configuration field selects a function. If it
* doesn't, skip the field if it's not applicable to the
* requested pinmux type.
*/
in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function); in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function);
if (!in_range) { if (!in_range) {
/* not a function enum */ if (pinmux_type == PINMUX_TYPE_FUNCTION) {
if (range) { /* Functions are allowed to modify all
/* * fields.
* other range exists, so this pin is */
* a regular GPIO pin that now is being in_range = 1;
* bound to a specific direction. } else if (pinmux_type != PINMUX_TYPE_GPIO) {
* /* Input/output types can only modify fields
* for this case we only allow function enums * that correspond to their respective ranges.
* and the enums that match the other range.
*/ */
in_range = sh_pfc_enum_in_range(enum_id, range); in_range = sh_pfc_enum_in_range(enum_id, range);
...@@ -327,17 +331,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) ...@@ -327,17 +331,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
*/ */
if (in_range && enum_id == range->force) if (in_range && enum_id == range->force)
continue; continue;
} else {
/*
* no other range exists, so this pin
* must then be of the function type.
*
* allow function type pins to select
* any combination of function/in/out
* in their MARK lists.
*/
in_range = 1;
} }
/* GPIOs are only allowed to modify function fields. */
} }
if (!in_range) if (!in_range)
......
...@@ -182,6 +182,17 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, ...@@ -182,6 +182,17 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
goto done; goto done;
} }
if (!pfc->gpio) {
/* If GPIOs are handled externally the pin mux type need to be
* set to GPIO here.
*/
const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
if (ret < 0)
goto done;
}
cfg->type = PINMUX_TYPE_GPIO; cfg->type = PINMUX_TYPE_GPIO;
ret = 0; ret = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册