aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-imx.c
diff options
context:
space:
mode:
authorJingchang Lu <b35083@freescale.com>2013-05-28 05:32:07 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-16 05:56:51 -0400
commitbf5a530971afbe959348af4d84d17636108e6abf (patch)
treea40a88483b1d5210d8401636a83443b4b59a2c82 /drivers/pinctrl/pinctrl-imx.c
parent7bbc87b801fcaa817d828fdaa0ca8c6d223a1347 (diff)
pinctrl: imx: add VF610 support to imx pinctrl framework
On some platforms such as VF610, offset of mux and pad ctrl register may be zero, and the mux_mode and config_val are in one 32-bit register. This patch adds support to imx core pinctrl framework to handle these cases. Signed-off-by: Jingchang Lu <b35083@freescale.com> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-imx.c')
-rw-r--r--drivers/pinctrl/pinctrl-imx.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c
index 4fcfff9243be..57a4eb0add2e 100644
--- a/drivers/pinctrl/pinctrl-imx.c
+++ b/drivers/pinctrl/pinctrl-imx.c
@@ -221,13 +221,21 @@ static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
221 pin_id = pins[i]; 221 pin_id = pins[i];
222 pin_reg = &info->pin_regs[pin_id]; 222 pin_reg = &info->pin_regs[pin_id];
223 223
224 if (!pin_reg->mux_reg) { 224 if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->mux_reg) {
225 dev_err(ipctl->dev, "Pin(%s) does not support mux function\n", 225 dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
226 info->pins[pin_id].name); 226 info->pins[pin_id].name);
227 return -EINVAL; 227 return -EINVAL;
228 } 228 }
229 229
230 writel(mux[i], ipctl->base + pin_reg->mux_reg); 230 if (info->flags & SHARE_MUX_CONF_REG) {
231 u32 reg;
232 reg = readl(ipctl->base + pin_reg->mux_reg);
233 reg &= ~(0x7 << 20);
234 reg |= (mux[i] << 20);
235 writel(reg, ipctl->base + pin_reg->mux_reg);
236 } else {
237 writel(mux[i], ipctl->base + pin_reg->mux_reg);
238 }
231 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n", 239 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
232 pin_reg->mux_reg, mux[i]); 240 pin_reg->mux_reg, mux[i]);
233 241
@@ -287,7 +295,7 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
287 const struct imx_pinctrl_soc_info *info = ipctl->info; 295 const struct imx_pinctrl_soc_info *info = ipctl->info;
288 const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; 296 const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
289 297
290 if (!pin_reg->conf_reg) { 298 if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
291 dev_err(info->dev, "Pin(%s) does not support config function\n", 299 dev_err(info->dev, "Pin(%s) does not support config function\n",
292 info->pins[pin_id].name); 300 info->pins[pin_id].name);
293 return -EINVAL; 301 return -EINVAL;
@@ -295,6 +303,9 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
295 303
296 *config = readl(ipctl->base + pin_reg->conf_reg); 304 *config = readl(ipctl->base + pin_reg->conf_reg);
297 305
306 if (info->flags & SHARE_MUX_CONF_REG)
307 *config &= 0xffff;
308
298 return 0; 309 return 0;
299} 310}
300 311
@@ -305,7 +316,7 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
305 const struct imx_pinctrl_soc_info *info = ipctl->info; 316 const struct imx_pinctrl_soc_info *info = ipctl->info;
306 const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; 317 const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
307 318
308 if (!pin_reg->conf_reg) { 319 if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
309 dev_err(info->dev, "Pin(%s) does not support config function\n", 320 dev_err(info->dev, "Pin(%s) does not support config function\n",
310 info->pins[pin_id].name); 321 info->pins[pin_id].name);
311 return -EINVAL; 322 return -EINVAL;
@@ -314,7 +325,15 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
314 dev_dbg(ipctl->dev, "pinconf set pin %s\n", 325 dev_dbg(ipctl->dev, "pinconf set pin %s\n",
315 info->pins[pin_id].name); 326 info->pins[pin_id].name);
316 327
317 writel(config, ipctl->base + pin_reg->conf_reg); 328 if (info->flags & SHARE_MUX_CONF_REG) {
329 u32 reg;
330 reg = readl(ipctl->base + pin_reg->conf_reg);
331 reg &= ~0xffff;
332 reg |= config;
333 writel(reg, ipctl->base + pin_reg->conf_reg);
334 } else {
335 writel(config, ipctl->base + pin_reg->conf_reg);
336 }
318 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", 337 dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
319 pin_reg->conf_reg, config); 338 pin_reg->conf_reg, config);
320 339
@@ -381,19 +400,24 @@ static struct pinctrl_desc imx_pinctrl_desc = {
381 * 1 u32 CONFIG, so 24 types in total for each pin. 400 * 1 u32 CONFIG, so 24 types in total for each pin.
382 */ 401 */
383#define FSL_PIN_SIZE 24 402#define FSL_PIN_SIZE 24
403#define SHARE_FSL_PIN_SIZE 20
384 404
385static int imx_pinctrl_parse_groups(struct device_node *np, 405static int imx_pinctrl_parse_groups(struct device_node *np,
386 struct imx_pin_group *grp, 406 struct imx_pin_group *grp,
387 struct imx_pinctrl_soc_info *info, 407 struct imx_pinctrl_soc_info *info,
388 u32 index) 408 u32 index)
389{ 409{
390 int size; 410 int size, pin_size;
391 const __be32 *list; 411 const __be32 *list;
392 int i; 412 int i;
393 u32 config; 413 u32 config;
394 414
395 dev_dbg(info->dev, "group(%d): %s\n", index, np->name); 415 dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
396 416
417 if (info->flags & SHARE_MUX_CONF_REG)
418 pin_size = SHARE_FSL_PIN_SIZE;
419 else
420 pin_size = FSL_PIN_SIZE;
397 /* Initialise group */ 421 /* Initialise group */
398 grp->name = np->name; 422 grp->name = np->name;
399 423
@@ -403,12 +427,12 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
403 */ 427 */
404 list = of_get_property(np, "fsl,pins", &size); 428 list = of_get_property(np, "fsl,pins", &size);
405 /* we do not check return since it's safe node passed down */ 429 /* we do not check return since it's safe node passed down */
406 if (!size || size % FSL_PIN_SIZE) { 430 if (!size || size % pin_size) {
407 dev_err(info->dev, "Invalid fsl,pins property\n"); 431 dev_err(info->dev, "Invalid fsl,pins property\n");
408 return -EINVAL; 432 return -EINVAL;
409 } 433 }
410 434
411 grp->npins = size / FSL_PIN_SIZE; 435 grp->npins = size / pin_size;
412 grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 436 grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
413 GFP_KERNEL); 437 GFP_KERNEL);
414 grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 438 grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
@@ -421,10 +445,17 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
421 GFP_KERNEL); 445 GFP_KERNEL);
422 for (i = 0; i < grp->npins; i++) { 446 for (i = 0; i < grp->npins; i++) {
423 u32 mux_reg = be32_to_cpu(*list++); 447 u32 mux_reg = be32_to_cpu(*list++);
424 u32 conf_reg = be32_to_cpu(*list++); 448 u32 conf_reg;
425 unsigned int pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4; 449 unsigned int pin_id;
426 struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; 450 struct imx_pin_reg *pin_reg;
427 451
452 if (info->flags & SHARE_MUX_CONF_REG)
453 conf_reg = mux_reg;
454 else
455 conf_reg = be32_to_cpu(*list++);
456
457 pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
458 pin_reg = &info->pin_regs[pin_id];
428 grp->pins[i] = pin_id; 459 grp->pins[i] = pin_id;
429 pin_reg->mux_reg = mux_reg; 460 pin_reg->mux_reg = mux_reg;
430 pin_reg->conf_reg = conf_reg; 461 pin_reg->conf_reg = conf_reg;