aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-sunxi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-sunxi.c')
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.c77
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
275static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, 275static 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}