0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/platform_device.h>
0010 #include <linux/slab.h>
0011 #include <linux/io.h>
0012 #include <linux/of.h>
0013 #include <linux/of_address.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/err.h>
0016 #include <linux/gpio/driver.h>
0017 #include <linux/pinctrl/machine.h>
0018 #include <linux/pinctrl/pinconf.h>
0019 #include <linux/pinctrl/pinctrl.h>
0020 #include <linux/pinctrl/pinmux.h>
0021 #include <linux/mfd/syscon.h>
0022 #include <linux/regmap.h>
0023
0024 #include "pinctrl-mvebu.h"
0025
0026 #define MPPS_PER_REG 8
0027 #define MPP_BITS 4
0028 #define MPP_MASK 0xf
0029
0030 struct mvebu_pinctrl_function {
0031 const char *name;
0032 const char **groups;
0033 unsigned num_groups;
0034 };
0035
0036 struct mvebu_pinctrl_group {
0037 const char *name;
0038 const struct mvebu_mpp_ctrl *ctrl;
0039 struct mvebu_mpp_ctrl_data *data;
0040 struct mvebu_mpp_ctrl_setting *settings;
0041 unsigned num_settings;
0042 unsigned gid;
0043 unsigned *pins;
0044 unsigned npins;
0045 };
0046
0047 struct mvebu_pinctrl {
0048 struct device *dev;
0049 struct pinctrl_dev *pctldev;
0050 struct pinctrl_desc desc;
0051 struct mvebu_pinctrl_group *groups;
0052 unsigned num_groups;
0053 struct mvebu_pinctrl_function *functions;
0054 unsigned num_functions;
0055 u8 variant;
0056 };
0057
0058 int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
0059 unsigned int pid, unsigned long *config)
0060 {
0061 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0062 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0063
0064 *config = (readl(data->base + off) >> shift) & MVEBU_MPP_MASK;
0065
0066 return 0;
0067 }
0068
0069 int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
0070 unsigned int pid, unsigned long config)
0071 {
0072 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0073 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0074 unsigned long reg;
0075
0076 reg = readl(data->base + off) & ~(MVEBU_MPP_MASK << shift);
0077 writel(reg | (config << shift), data->base + off);
0078
0079 return 0;
0080 }
0081
0082 static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
0083 struct mvebu_pinctrl *pctl, unsigned pid)
0084 {
0085 unsigned n;
0086 for (n = 0; n < pctl->num_groups; n++) {
0087 if (pid >= pctl->groups[n].pins[0] &&
0088 pid < pctl->groups[n].pins[0] +
0089 pctl->groups[n].npins)
0090 return &pctl->groups[n];
0091 }
0092 return NULL;
0093 }
0094
0095 static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name(
0096 struct mvebu_pinctrl *pctl, const char *name)
0097 {
0098 unsigned n;
0099
0100 for (n = 0; n < pctl->num_groups; n++) {
0101 if (strcmp(name, pctl->groups[n].name) == 0)
0102 return &pctl->groups[n];
0103 }
0104
0105 return NULL;
0106 }
0107
0108 static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val(
0109 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
0110 unsigned long config)
0111 {
0112 unsigned n;
0113
0114 for (n = 0; n < grp->num_settings; n++) {
0115 if (config == grp->settings[n].val) {
0116 if (!pctl->variant || (pctl->variant &
0117 grp->settings[n].variant))
0118 return &grp->settings[n];
0119 }
0120 }
0121
0122 return NULL;
0123 }
0124
0125 static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name(
0126 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
0127 const char *name)
0128 {
0129 unsigned n;
0130
0131 for (n = 0; n < grp->num_settings; n++) {
0132 if (strcmp(name, grp->settings[n].name) == 0) {
0133 if (!pctl->variant || (pctl->variant &
0134 grp->settings[n].variant))
0135 return &grp->settings[n];
0136 }
0137 }
0138
0139 return NULL;
0140 }
0141
0142 static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting(
0143 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp)
0144 {
0145 unsigned n;
0146
0147 for (n = 0; n < grp->num_settings; n++) {
0148 if (grp->settings[n].flags &
0149 (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
0150 if (!pctl->variant || (pctl->variant &
0151 grp->settings[n].variant))
0152 return &grp->settings[n];
0153 }
0154 }
0155
0156 return NULL;
0157 }
0158
0159 static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
0160 struct mvebu_pinctrl *pctl, const char *name)
0161 {
0162 unsigned n;
0163
0164 for (n = 0; n < pctl->num_functions; n++) {
0165 if (strcmp(name, pctl->functions[n].name) == 0)
0166 return &pctl->functions[n];
0167 }
0168
0169 return NULL;
0170 }
0171
0172 static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
0173 unsigned gid, unsigned long *config)
0174 {
0175 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0176 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
0177
0178 if (!grp->ctrl)
0179 return -EINVAL;
0180
0181 return grp->ctrl->mpp_get(grp->data, grp->pins[0], config);
0182 }
0183
0184 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
0185 unsigned gid, unsigned long *configs,
0186 unsigned num_configs)
0187 {
0188 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0189 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
0190 int i, ret;
0191
0192 if (!grp->ctrl)
0193 return -EINVAL;
0194
0195 for (i = 0; i < num_configs; i++) {
0196 ret = grp->ctrl->mpp_set(grp->data, grp->pins[0], configs[i]);
0197 if (ret)
0198 return ret;
0199 }
0200
0201 return 0;
0202 }
0203
0204 static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
0205 struct seq_file *s, unsigned gid)
0206 {
0207 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0208 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
0209 struct mvebu_mpp_ctrl_setting *curr;
0210 unsigned long config;
0211 unsigned n;
0212
0213 if (mvebu_pinconf_group_get(pctldev, gid, &config))
0214 return;
0215
0216 curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config);
0217
0218 if (curr) {
0219 seq_printf(s, "current: %s", curr->name);
0220 if (curr->subname)
0221 seq_printf(s, "(%s)", curr->subname);
0222 if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
0223 seq_putc(s, '(');
0224 if (curr->flags & MVEBU_SETTING_GPI)
0225 seq_putc(s, 'i');
0226 if (curr->flags & MVEBU_SETTING_GPO)
0227 seq_putc(s, 'o');
0228 seq_putc(s, ')');
0229 }
0230 } else {
0231 seq_puts(s, "current: UNKNOWN");
0232 }
0233
0234 if (grp->num_settings > 1) {
0235 seq_puts(s, ", available = [");
0236 for (n = 0; n < grp->num_settings; n++) {
0237 if (curr == &grp->settings[n])
0238 continue;
0239
0240
0241 if (pctl->variant &&
0242 !(pctl->variant & grp->settings[n].variant))
0243 continue;
0244
0245 seq_printf(s, " %s", grp->settings[n].name);
0246 if (grp->settings[n].subname)
0247 seq_printf(s, "(%s)", grp->settings[n].subname);
0248 if (grp->settings[n].flags &
0249 (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
0250 seq_putc(s, '(');
0251 if (grp->settings[n].flags & MVEBU_SETTING_GPI)
0252 seq_putc(s, 'i');
0253 if (grp->settings[n].flags & MVEBU_SETTING_GPO)
0254 seq_putc(s, 'o');
0255 seq_putc(s, ')');
0256 }
0257 }
0258 seq_puts(s, " ]");
0259 }
0260 }
0261
0262 static const struct pinconf_ops mvebu_pinconf_ops = {
0263 .pin_config_group_get = mvebu_pinconf_group_get,
0264 .pin_config_group_set = mvebu_pinconf_group_set,
0265 .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show,
0266 };
0267
0268 static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
0269 {
0270 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0271
0272 return pctl->num_functions;
0273 }
0274
0275 static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev,
0276 unsigned fid)
0277 {
0278 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0279
0280 return pctl->functions[fid].name;
0281 }
0282
0283 static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid,
0284 const char * const **groups,
0285 unsigned * const num_groups)
0286 {
0287 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0288
0289 *groups = pctl->functions[fid].groups;
0290 *num_groups = pctl->functions[fid].num_groups;
0291 return 0;
0292 }
0293
0294 static int mvebu_pinmux_set(struct pinctrl_dev *pctldev, unsigned fid,
0295 unsigned gid)
0296 {
0297 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0298 struct mvebu_pinctrl_function *func = &pctl->functions[fid];
0299 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
0300 struct mvebu_mpp_ctrl_setting *setting;
0301 int ret;
0302 unsigned long config;
0303
0304 setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
0305 func->name);
0306 if (!setting) {
0307 dev_err(pctl->dev,
0308 "unable to find setting %s in group %s\n",
0309 func->name, func->groups[gid]);
0310 return -EINVAL;
0311 }
0312
0313 config = setting->val;
0314 ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
0315 if (ret) {
0316 dev_err(pctl->dev, "cannot set group %s to %s\n",
0317 func->groups[gid], func->name);
0318 return ret;
0319 }
0320
0321 return 0;
0322 }
0323
0324 static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
0325 struct pinctrl_gpio_range *range, unsigned offset)
0326 {
0327 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0328 struct mvebu_pinctrl_group *grp;
0329 struct mvebu_mpp_ctrl_setting *setting;
0330 unsigned long config;
0331
0332 grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
0333 if (!grp)
0334 return -EINVAL;
0335
0336 if (grp->ctrl->mpp_gpio_req)
0337 return grp->ctrl->mpp_gpio_req(grp->data, offset);
0338
0339 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
0340 if (!setting)
0341 return -ENOTSUPP;
0342
0343 config = setting->val;
0344
0345 return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
0346 }
0347
0348 static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
0349 struct pinctrl_gpio_range *range, unsigned offset, bool input)
0350 {
0351 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0352 struct mvebu_pinctrl_group *grp;
0353 struct mvebu_mpp_ctrl_setting *setting;
0354
0355 grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
0356 if (!grp)
0357 return -EINVAL;
0358
0359 if (grp->ctrl->mpp_gpio_dir)
0360 return grp->ctrl->mpp_gpio_dir(grp->data, offset, input);
0361
0362 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
0363 if (!setting)
0364 return -ENOTSUPP;
0365
0366 if ((input && (setting->flags & MVEBU_SETTING_GPI)) ||
0367 (!input && (setting->flags & MVEBU_SETTING_GPO)))
0368 return 0;
0369
0370 return -ENOTSUPP;
0371 }
0372
0373 static const struct pinmux_ops mvebu_pinmux_ops = {
0374 .get_functions_count = mvebu_pinmux_get_funcs_count,
0375 .get_function_name = mvebu_pinmux_get_func_name,
0376 .get_function_groups = mvebu_pinmux_get_groups,
0377 .gpio_request_enable = mvebu_pinmux_gpio_request_enable,
0378 .gpio_set_direction = mvebu_pinmux_gpio_set_direction,
0379 .set_mux = mvebu_pinmux_set,
0380 };
0381
0382 static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
0383 {
0384 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0385 return pctl->num_groups;
0386 }
0387
0388 static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
0389 unsigned gid)
0390 {
0391 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0392 return pctl->groups[gid].name;
0393 }
0394
0395 static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
0396 unsigned gid, const unsigned **pins,
0397 unsigned *num_pins)
0398 {
0399 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0400 *pins = pctl->groups[gid].pins;
0401 *num_pins = pctl->groups[gid].npins;
0402 return 0;
0403 }
0404
0405 static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
0406 struct device_node *np,
0407 struct pinctrl_map **map,
0408 unsigned *num_maps)
0409 {
0410 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
0411 struct property *prop;
0412 const char *function;
0413 const char *group;
0414 int ret, nmaps, n;
0415
0416 *map = NULL;
0417 *num_maps = 0;
0418
0419 ret = of_property_read_string(np, "marvell,function", &function);
0420 if (ret) {
0421 dev_err(pctl->dev,
0422 "missing marvell,function in node %pOFn\n", np);
0423 return 0;
0424 }
0425
0426 nmaps = of_property_count_strings(np, "marvell,pins");
0427 if (nmaps < 0) {
0428 dev_err(pctl->dev,
0429 "missing marvell,pins in node %pOFn\n", np);
0430 return 0;
0431 }
0432
0433 *map = kmalloc_array(nmaps, sizeof(**map), GFP_KERNEL);
0434 if (!*map)
0435 return -ENOMEM;
0436
0437 n = 0;
0438 of_property_for_each_string(np, "marvell,pins", prop, group) {
0439 struct mvebu_pinctrl_group *grp =
0440 mvebu_pinctrl_find_group_by_name(pctl, group);
0441
0442 if (!grp) {
0443 dev_err(pctl->dev, "unknown pin %s", group);
0444 continue;
0445 }
0446
0447 if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) {
0448 dev_err(pctl->dev, "unsupported function %s on pin %s",
0449 function, group);
0450 continue;
0451 }
0452
0453 (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP;
0454 (*map)[n].data.mux.group = group;
0455 (*map)[n].data.mux.function = function;
0456 n++;
0457 }
0458
0459 *num_maps = nmaps;
0460
0461 return 0;
0462 }
0463
0464 static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
0465 struct pinctrl_map *map, unsigned num_maps)
0466 {
0467 kfree(map);
0468 }
0469
0470 static const struct pinctrl_ops mvebu_pinctrl_ops = {
0471 .get_groups_count = mvebu_pinctrl_get_groups_count,
0472 .get_group_name = mvebu_pinctrl_get_group_name,
0473 .get_group_pins = mvebu_pinctrl_get_group_pins,
0474 .dt_node_to_map = mvebu_pinctrl_dt_node_to_map,
0475 .dt_free_map = mvebu_pinctrl_dt_free_map,
0476 };
0477
0478 static int _add_function(struct mvebu_pinctrl_function *funcs, int *funcsize,
0479 const char *name)
0480 {
0481 if (*funcsize <= 0)
0482 return -EOVERFLOW;
0483
0484 while (funcs->num_groups) {
0485
0486 if (strcmp(funcs->name, name) == 0) {
0487 funcs->num_groups++;
0488 return -EEXIST;
0489 }
0490 funcs++;
0491 }
0492
0493
0494 funcs->name = name;
0495 funcs->num_groups = 1;
0496 (*funcsize)--;
0497
0498 return 0;
0499 }
0500
0501 static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
0502 struct mvebu_pinctrl *pctl)
0503 {
0504 struct mvebu_pinctrl_function *funcs;
0505 int num = 0, funcsize = pctl->desc.npins;
0506 int n, s;
0507
0508
0509
0510 funcs = devm_kcalloc(&pdev->dev,
0511 funcsize, sizeof(struct mvebu_pinctrl_function),
0512 GFP_KERNEL);
0513 if (!funcs)
0514 return -ENOMEM;
0515
0516 for (n = 0; n < pctl->num_groups; n++) {
0517 struct mvebu_pinctrl_group *grp = &pctl->groups[n];
0518 for (s = 0; s < grp->num_settings; s++) {
0519 int ret;
0520
0521
0522 if (pctl->variant &&
0523 !(pctl->variant & grp->settings[s].variant))
0524 continue;
0525
0526
0527 ret = _add_function(funcs, &funcsize,
0528 grp->settings[s].name);
0529 if (ret == -EOVERFLOW)
0530 dev_err(&pdev->dev,
0531 "More functions than pins(%d)\n",
0532 pctl->desc.npins);
0533 if (ret < 0)
0534 continue;
0535
0536 num++;
0537 }
0538 }
0539
0540 pctl->num_functions = num;
0541 pctl->functions = funcs;
0542
0543 for (n = 0; n < pctl->num_groups; n++) {
0544 struct mvebu_pinctrl_group *grp = &pctl->groups[n];
0545 for (s = 0; s < grp->num_settings; s++) {
0546 struct mvebu_pinctrl_function *f;
0547 const char **groups;
0548
0549
0550 if (pctl->variant &&
0551 !(pctl->variant & grp->settings[s].variant))
0552 continue;
0553
0554 f = mvebu_pinctrl_find_function_by_name(pctl,
0555 grp->settings[s].name);
0556
0557
0558 if (!f->groups) {
0559 f->groups = devm_kcalloc(&pdev->dev,
0560 f->num_groups,
0561 sizeof(char *),
0562 GFP_KERNEL);
0563 if (!f->groups)
0564 return -ENOMEM;
0565 }
0566
0567
0568 groups = f->groups;
0569 while (*groups)
0570 groups++;
0571 *groups = grp->name;
0572 }
0573 }
0574
0575 return 0;
0576 }
0577
0578 int mvebu_pinctrl_probe(struct platform_device *pdev)
0579 {
0580 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
0581 struct mvebu_pinctrl *pctl;
0582 struct pinctrl_pin_desc *pdesc;
0583 unsigned gid, n, k;
0584 unsigned size, noname = 0;
0585 char *noname_buf;
0586 void *p;
0587 int ret;
0588
0589 if (!soc || !soc->controls || !soc->modes) {
0590 dev_err(&pdev->dev, "wrong pinctrl soc info\n");
0591 return -EINVAL;
0592 }
0593
0594 pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
0595 GFP_KERNEL);
0596 if (!pctl)
0597 return -ENOMEM;
0598
0599 pctl->desc.name = dev_name(&pdev->dev);
0600 pctl->desc.owner = THIS_MODULE;
0601 pctl->desc.pctlops = &mvebu_pinctrl_ops;
0602 pctl->desc.pmxops = &mvebu_pinmux_ops;
0603 pctl->desc.confops = &mvebu_pinconf_ops;
0604 pctl->variant = soc->variant;
0605 pctl->dev = &pdev->dev;
0606 platform_set_drvdata(pdev, pctl);
0607
0608
0609
0610 pctl->num_groups = 0;
0611 pctl->desc.npins = 0;
0612 for (n = 0; n < soc->ncontrols; n++) {
0613 const struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
0614
0615 pctl->desc.npins += ctrl->npins;
0616
0617 for (k = 0; k < ctrl->npins; k++)
0618 ctrl->pins[k] = ctrl->pid + k;
0619
0620
0621
0622
0623
0624
0625 if (!ctrl->name) {
0626 pctl->num_groups += ctrl->npins;
0627 noname += ctrl->npins;
0628 } else {
0629 pctl->num_groups += 1;
0630 }
0631 }
0632
0633 pdesc = devm_kcalloc(&pdev->dev,
0634 pctl->desc.npins,
0635 sizeof(struct pinctrl_pin_desc),
0636 GFP_KERNEL);
0637 if (!pdesc)
0638 return -ENOMEM;
0639
0640 for (n = 0; n < pctl->desc.npins; n++)
0641 pdesc[n].number = n;
0642 pctl->desc.pins = pdesc;
0643
0644
0645
0646
0647 size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
0648 p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
0649 if (!p)
0650 return -ENOMEM;
0651
0652 pctl->groups = p;
0653 noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
0654
0655
0656 gid = 0;
0657 for (n = 0; n < soc->ncontrols; n++) {
0658 const struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
0659 struct mvebu_mpp_ctrl_data *data = soc->control_data ?
0660 &soc->control_data[n] : NULL;
0661
0662 pctl->groups[gid].gid = gid;
0663 pctl->groups[gid].ctrl = ctrl;
0664 pctl->groups[gid].data = data;
0665 pctl->groups[gid].name = ctrl->name;
0666 pctl->groups[gid].pins = ctrl->pins;
0667 pctl->groups[gid].npins = ctrl->npins;
0668
0669
0670
0671
0672
0673
0674 if (!ctrl->name) {
0675 pctl->groups[gid].name = noname_buf;
0676 pctl->groups[gid].npins = 1;
0677 sprintf(noname_buf, "mpp%d", ctrl->pid+0);
0678 noname_buf += 8;
0679
0680 for (k = 1; k < ctrl->npins; k++) {
0681 gid++;
0682 pctl->groups[gid].gid = gid;
0683 pctl->groups[gid].ctrl = ctrl;
0684 pctl->groups[gid].data = data;
0685 pctl->groups[gid].name = noname_buf;
0686 pctl->groups[gid].pins = &ctrl->pins[k];
0687 pctl->groups[gid].npins = 1;
0688 sprintf(noname_buf, "mpp%d", ctrl->pid+k);
0689 noname_buf += 8;
0690 }
0691 }
0692 gid++;
0693 }
0694
0695
0696 for (n = 0; n < soc->nmodes; n++) {
0697 struct mvebu_mpp_mode *mode = &soc->modes[n];
0698 struct mvebu_mpp_ctrl_setting *set = &mode->settings[0];
0699 struct mvebu_pinctrl_group *grp;
0700 unsigned num_settings;
0701 unsigned supp_settings;
0702
0703 for (num_settings = 0, supp_settings = 0; ; set++) {
0704 if (!set->name)
0705 break;
0706
0707 num_settings++;
0708
0709
0710 if (pctl->variant && !(pctl->variant & set->variant))
0711 continue;
0712
0713 supp_settings++;
0714
0715
0716 if (strcmp(set->name, "gpio") == 0)
0717 set->flags = MVEBU_SETTING_GPI |
0718 MVEBU_SETTING_GPO;
0719 else if (strcmp(set->name, "gpo") == 0)
0720 set->flags = MVEBU_SETTING_GPO;
0721 else if (strcmp(set->name, "gpi") == 0)
0722 set->flags = MVEBU_SETTING_GPI;
0723 }
0724
0725
0726 if (!supp_settings)
0727 continue;
0728
0729 grp = mvebu_pinctrl_find_group_by_pid(pctl, mode->pid);
0730 if (!grp) {
0731 dev_warn(&pdev->dev, "unknown pinctrl group %d\n",
0732 mode->pid);
0733 continue;
0734 }
0735
0736 grp->settings = mode->settings;
0737 grp->num_settings = num_settings;
0738 }
0739
0740 ret = mvebu_pinctrl_build_functions(pdev, pctl);
0741 if (ret) {
0742 dev_err(&pdev->dev, "unable to build functions\n");
0743 return ret;
0744 }
0745
0746 pctl->pctldev = devm_pinctrl_register(&pdev->dev, &pctl->desc, pctl);
0747 if (IS_ERR(pctl->pctldev)) {
0748 dev_err(&pdev->dev, "unable to register pinctrl driver\n");
0749 return PTR_ERR(pctl->pctldev);
0750 }
0751
0752 dev_info(&pdev->dev, "registered pinctrl driver\n");
0753
0754
0755 for (n = 0; n < soc->ngpioranges; n++)
0756 pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]);
0757
0758 return 0;
0759 }
0760
0761
0762
0763
0764
0765
0766
0767
0768 int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev)
0769 {
0770 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
0771 struct mvebu_mpp_ctrl_data *mpp_data;
0772 void __iomem *base;
0773 int i;
0774
0775 base = devm_platform_ioremap_resource(pdev, 0);
0776 if (IS_ERR(base))
0777 return PTR_ERR(base);
0778
0779 mpp_data = devm_kcalloc(&pdev->dev, soc->ncontrols, sizeof(*mpp_data),
0780 GFP_KERNEL);
0781 if (!mpp_data)
0782 return -ENOMEM;
0783
0784 for (i = 0; i < soc->ncontrols; i++)
0785 mpp_data[i].base = base;
0786
0787 soc->control_data = mpp_data;
0788
0789 return mvebu_pinctrl_probe(pdev);
0790 }
0791
0792 int mvebu_regmap_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
0793 unsigned int pid, unsigned long *config)
0794 {
0795 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0796 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0797 unsigned int val;
0798 int err;
0799
0800 err = regmap_read(data->regmap.map, data->regmap.offset + off, &val);
0801 if (err)
0802 return err;
0803
0804 *config = (val >> shift) & MVEBU_MPP_MASK;
0805
0806 return 0;
0807 }
0808
0809 int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
0810 unsigned int pid, unsigned long config)
0811 {
0812 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0813 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
0814
0815 return regmap_update_bits(data->regmap.map, data->regmap.offset + off,
0816 MVEBU_MPP_MASK << shift, config << shift);
0817 }
0818
0819 int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev,
0820 struct device *syscon_dev, u32 offset)
0821 {
0822 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
0823 struct mvebu_mpp_ctrl_data *mpp_data;
0824 struct regmap *regmap;
0825 int i;
0826
0827 regmap = syscon_node_to_regmap(syscon_dev->of_node);
0828 if (IS_ERR(regmap))
0829 return PTR_ERR(regmap);
0830
0831 mpp_data = devm_kcalloc(&pdev->dev, soc->ncontrols, sizeof(*mpp_data),
0832 GFP_KERNEL);
0833 if (!mpp_data)
0834 return -ENOMEM;
0835
0836 for (i = 0; i < soc->ncontrols; i++) {
0837 mpp_data[i].regmap.map = regmap;
0838 mpp_data[i].regmap.offset = offset;
0839 }
0840
0841 soc->control_data = mpp_data;
0842
0843 return mvebu_pinctrl_probe(pdev);
0844 }