diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-sunxi.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-sunxi.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index d251c76c2e62..8dbd465b01d3 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c | |||
@@ -274,50 +274,55 @@ static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev, | |||
274 | 274 | ||
275 | static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, | 275 | static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, |
276 | unsigned group, | 276 | unsigned group, |
277 | unsigned long config) | 277 | unsigned long *configs, |
278 | unsigned num_configs) | ||
278 | { | 279 | { |
279 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | 280 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
280 | struct sunxi_pinctrl_group *g = &pctl->groups[group]; | 281 | struct sunxi_pinctrl_group *g = &pctl->groups[group]; |
281 | u32 val, mask; | 282 | u32 val, mask; |
282 | u16 strength; | 283 | u16 strength; |
283 | u8 dlevel; | 284 | u8 dlevel; |
285 | int i; | ||
284 | 286 | ||
285 | switch (pinconf_to_config_param(config)) { | 287 | for (i = 0; i < num_configs; i++) { |
286 | case PIN_CONFIG_DRIVE_STRENGTH: | 288 | switch (pinconf_to_config_param(configs[i])) { |
287 | strength = pinconf_to_config_argument(config); | 289 | case PIN_CONFIG_DRIVE_STRENGTH: |
288 | if (strength > 40) | 290 | strength = pinconf_to_config_argument(configs[i]); |
289 | return -EINVAL; | 291 | if (strength > 40) |
290 | /* | 292 | return -EINVAL; |
291 | * We convert from mA to what the register expects: | 293 | /* |
292 | * 0: 10mA | 294 | * We convert from mA to what the register expects: |
293 | * 1: 20mA | 295 | * 0: 10mA |
294 | * 2: 30mA | 296 | * 1: 20mA |
295 | * 3: 40mA | 297 | * 2: 30mA |
296 | */ | 298 | * 3: 40mA |
297 | dlevel = strength / 10 - 1; | 299 | */ |
298 | val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); | 300 | dlevel = strength / 10 - 1; |
299 | mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); | 301 | val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); |
300 | writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin), | 302 | mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); |
301 | pctl->membase + sunxi_dlevel_reg(g->pin)); | 303 | writel((val & ~mask) |
302 | break; | 304 | | dlevel << sunxi_dlevel_offset(g->pin), |
303 | case PIN_CONFIG_BIAS_PULL_UP: | 305 | pctl->membase + sunxi_dlevel_reg(g->pin)); |
304 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); | 306 | break; |
305 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); | 307 | case PIN_CONFIG_BIAS_PULL_UP: |
306 | writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin), | 308 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); |
307 | pctl->membase + sunxi_pull_reg(g->pin)); | 309 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); |
308 | break; | 310 | writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin), |
309 | case PIN_CONFIG_BIAS_PULL_DOWN: | 311 | pctl->membase + sunxi_pull_reg(g->pin)); |
310 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); | 312 | break; |
311 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); | 313 | case PIN_CONFIG_BIAS_PULL_DOWN: |
312 | writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin), | 314 | val = readl(pctl->membase + sunxi_pull_reg(g->pin)); |
313 | pctl->membase + sunxi_pull_reg(g->pin)); | 315 | mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); |
314 | break; | 316 | writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin), |
315 | default: | 317 | pctl->membase + sunxi_pull_reg(g->pin)); |
316 | break; | 318 | break; |
317 | } | 319 | default: |
320 | break; | ||
321 | } | ||
318 | 322 | ||
319 | /* cache the config value */ | 323 | /* cache the config value */ |
320 | g->config = config; | 324 | g->config = configs[i]; |
325 | } /* for each config */ | ||
321 | 326 | ||
322 | return 0; | 327 | return 0; |
323 | } | 328 | } |