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: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
This commit is contained in:
parent
ceef91dcc0
commit
e3c470510b
|
@ -268,7 +268,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
|
|||
int ret;
|
||||
|
||||
switch (pinmux_type) {
|
||||
|
||||
case PINMUX_TYPE_GPIO:
|
||||
case PINMUX_TYPE_FUNCTION:
|
||||
range = NULL;
|
||||
break;
|
||||
|
@ -297,6 +297,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
|
|||
enum_id = 0;
|
||||
field = 0;
|
||||
value = 0;
|
||||
|
||||
/* Iterate over all the configuration fields we need to update. */
|
||||
while (1) {
|
||||
pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
|
||||
if (pos < 0)
|
||||
|
@ -305,18 +307,20 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
|
|||
if (!enum_id)
|
||||
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);
|
||||
if (!in_range) {
|
||||
/* not a function enum */
|
||||
if (range) {
|
||||
/*
|
||||
* other range exists, so this pin is
|
||||
* a regular GPIO pin that now is being
|
||||
* bound to a specific direction.
|
||||
*
|
||||
* for this case we only allow function enums
|
||||
* and the enums that match the other range.
|
||||
if (pinmux_type == PINMUX_TYPE_FUNCTION) {
|
||||
/* Functions are allowed to modify all
|
||||
* fields.
|
||||
*/
|
||||
in_range = 1;
|
||||
} else if (pinmux_type != PINMUX_TYPE_GPIO) {
|
||||
/* Input/output types can only modify fields
|
||||
* that correspond to their respective ranges.
|
||||
*/
|
||||
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)
|
|||
*/
|
||||
if (in_range && enum_id == range->force)
|
||||
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)
|
||||
|
|
|
@ -182,6 +182,17 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
|
|||
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;
|
||||
|
||||
ret = 0;
|
||||
|
|
Loading…
Reference in a new issue