diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-10 12:30:25 -0400 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-04-02 21:30:36 -0400 |
commit | e3c470510babd8ed385f1e09ec616787022b77b1 (patch) | |
tree | e45369241c4a8f4182fe82fe65a0ddb24822eb67 /drivers/pinctrl | |
parent | ceef91dcc0bca0a39c54d2f0071848b6d5c66b88 (diff) |
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>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/sh-pfc/core.c | 37 | ||||
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 11 |
2 files changed, 27 insertions, 21 deletions
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 97e6ea3147e0..ced9a95aa1fc 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c | |||
@@ -268,7 +268,7 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | |||
268 | int ret; | 268 | int ret; |
269 | 269 | ||
270 | switch (pinmux_type) { | 270 | switch (pinmux_type) { |
271 | 271 | case PINMUX_TYPE_GPIO: | |
272 | case PINMUX_TYPE_FUNCTION: | 272 | case PINMUX_TYPE_FUNCTION: |
273 | range = NULL; | 273 | range = NULL; |
274 | break; | 274 | break; |
@@ -297,6 +297,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | |||
297 | enum_id = 0; | 297 | enum_id = 0; |
298 | field = 0; | 298 | field = 0; |
299 | value = 0; | 299 | value = 0; |
300 | |||
301 | /* Iterate over all the configuration fields we need to update. */ | ||
300 | while (1) { | 302 | while (1) { |
301 | pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); | 303 | pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); |
302 | if (pos < 0) | 304 | if (pos < 0) |
@@ -305,18 +307,20 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | |||
305 | if (!enum_id) | 307 | if (!enum_id) |
306 | break; | 308 | break; |
307 | 309 | ||
308 | /* first check if this is a function enum */ | 310 | /* Check if the configuration field selects a function. If it |
311 | * doesn't, skip the field if it's not applicable to the | ||
312 | * requested pinmux type. | ||
313 | */ | ||
309 | in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function); | 314 | in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function); |
310 | if (!in_range) { | 315 | if (!in_range) { |
311 | /* not a function enum */ | 316 | if (pinmux_type == PINMUX_TYPE_FUNCTION) { |
312 | if (range) { | 317 | /* Functions are allowed to modify all |
313 | /* | 318 | * fields. |
314 | * other range exists, so this pin is | 319 | */ |
315 | * a regular GPIO pin that now is being | 320 | in_range = 1; |
316 | * bound to a specific direction. | 321 | } else if (pinmux_type != PINMUX_TYPE_GPIO) { |
317 | * | 322 | /* Input/output types can only modify fields |
318 | * for this case we only allow function enums | 323 | * that correspond to their respective ranges. |
319 | * and the enums that match the other range. | ||
320 | */ | 324 | */ |
321 | in_range = sh_pfc_enum_in_range(enum_id, range); | 325 | in_range = sh_pfc_enum_in_range(enum_id, range); |
322 | 326 | ||
@@ -327,17 +331,8 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | |||
327 | */ | 331 | */ |
328 | if (in_range && enum_id == range->force) | 332 | if (in_range && enum_id == range->force) |
329 | continue; | 333 | continue; |
330 | } else { | ||
331 | /* | ||
332 | * no other range exists, so this pin | ||
333 | * must then be of the function type. | ||
334 | * | ||
335 | * allow function type pins to select | ||
336 | * any combination of function/in/out | ||
337 | * in their MARK lists. | ||
338 | */ | ||
339 | in_range = 1; | ||
340 | } | 334 | } |
335 | /* GPIOs are only allowed to modify function fields. */ | ||
341 | } | 336 | } |
342 | 337 | ||
343 | if (!in_range) | 338 | if (!in_range) |
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index aef268bc17ba..3492ec9a33b7 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c | |||
@@ -182,6 +182,17 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
182 | goto done; | 182 | goto done; |
183 | } | 183 | } |
184 | 184 | ||
185 | if (!pfc->gpio) { | ||
186 | /* If GPIOs are handled externally the pin mux type need to be | ||
187 | * set to GPIO here. | ||
188 | */ | ||
189 | const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; | ||
190 | |||
191 | ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO); | ||
192 | if (ret < 0) | ||
193 | goto done; | ||
194 | } | ||
195 | |||
185 | cfg->type = PINMUX_TYPE_GPIO; | 196 | cfg->type = PINMUX_TYPE_GPIO; |
186 | 197 | ||
187 | ret = 0; | 198 | ret = 0; |