0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/err.h>
0009 #include <linux/module.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/property.h>
0012 #include <linux/regmap.h>
0013 #include <linux/slab.h>
0014
0015 #include <linux/pinctrl/machine.h>
0016 #include <linux/pinctrl/pinctrl.h>
0017 #include <linux/pinctrl/pinmux.h>
0018 #include <linux/pinctrl/pinconf.h>
0019 #include <linux/pinctrl/pinconf-generic.h>
0020
0021 #include <linux/mfd/madera/core.h>
0022 #include <linux/mfd/madera/registers.h>
0023
0024 #include "../pinctrl-utils.h"
0025
0026 #include "pinctrl-madera.h"
0027
0028
0029
0030
0031
0032 static const struct pinctrl_pin_desc madera_pins[] = {
0033 PINCTRL_PIN(0, "gpio1"),
0034 PINCTRL_PIN(1, "gpio2"),
0035 PINCTRL_PIN(2, "gpio3"),
0036 PINCTRL_PIN(3, "gpio4"),
0037 PINCTRL_PIN(4, "gpio5"),
0038 PINCTRL_PIN(5, "gpio6"),
0039 PINCTRL_PIN(6, "gpio7"),
0040 PINCTRL_PIN(7, "gpio8"),
0041 PINCTRL_PIN(8, "gpio9"),
0042 PINCTRL_PIN(9, "gpio10"),
0043 PINCTRL_PIN(10, "gpio11"),
0044 PINCTRL_PIN(11, "gpio12"),
0045 PINCTRL_PIN(12, "gpio13"),
0046 PINCTRL_PIN(13, "gpio14"),
0047 PINCTRL_PIN(14, "gpio15"),
0048 PINCTRL_PIN(15, "gpio16"),
0049 PINCTRL_PIN(16, "gpio17"),
0050 PINCTRL_PIN(17, "gpio18"),
0051 PINCTRL_PIN(18, "gpio19"),
0052 PINCTRL_PIN(19, "gpio20"),
0053 PINCTRL_PIN(20, "gpio21"),
0054 PINCTRL_PIN(21, "gpio22"),
0055 PINCTRL_PIN(22, "gpio23"),
0056 PINCTRL_PIN(23, "gpio24"),
0057 PINCTRL_PIN(24, "gpio25"),
0058 PINCTRL_PIN(25, "gpio26"),
0059 PINCTRL_PIN(26, "gpio27"),
0060 PINCTRL_PIN(27, "gpio28"),
0061 PINCTRL_PIN(28, "gpio29"),
0062 PINCTRL_PIN(29, "gpio30"),
0063 PINCTRL_PIN(30, "gpio31"),
0064 PINCTRL_PIN(31, "gpio32"),
0065 PINCTRL_PIN(32, "gpio33"),
0066 PINCTRL_PIN(33, "gpio34"),
0067 PINCTRL_PIN(34, "gpio35"),
0068 PINCTRL_PIN(35, "gpio36"),
0069 PINCTRL_PIN(36, "gpio37"),
0070 PINCTRL_PIN(37, "gpio38"),
0071 PINCTRL_PIN(38, "gpio39"),
0072 PINCTRL_PIN(39, "gpio40"),
0073 };
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 static const char * const madera_pin_single_group_names[] = {
0085 "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
0086 "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
0087 "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
0088 "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
0089 "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
0090 "gpio36", "gpio37", "gpio38", "gpio39", "gpio40",
0091 };
0092
0093
0094 static const unsigned int madera_pin_single_group_pins[] = {
0095 0, 1, 2, 3, 4, 5, 6,
0096 7, 8, 9, 10, 11, 12, 13,
0097 14, 15, 16, 17, 18, 19, 20,
0098 21, 22, 23, 24, 25, 26, 27,
0099 28, 29, 30, 31, 32, 33, 34,
0100 35, 36, 37, 38, 39,
0101 };
0102
0103 static const char * const madera_aif1_group_names[] = { "aif1" };
0104 static const char * const madera_aif2_group_names[] = { "aif2" };
0105 static const char * const madera_aif3_group_names[] = { "aif3" };
0106 static const char * const madera_aif4_group_names[] = { "aif4" };
0107 static const char * const madera_mif1_group_names[] = { "mif1" };
0108 static const char * const madera_mif2_group_names[] = { "mif2" };
0109 static const char * const madera_mif3_group_names[] = { "mif3" };
0110 static const char * const madera_dmic3_group_names[] = { "dmic3" };
0111 static const char * const madera_dmic4_group_names[] = { "dmic4" };
0112 static const char * const madera_dmic5_group_names[] = { "dmic5" };
0113 static const char * const madera_dmic6_group_names[] = { "dmic6" };
0114 static const char * const madera_spk1_group_names[] = { "pdmspk1" };
0115 static const char * const madera_spk2_group_names[] = { "pdmspk2" };
0116
0117
0118
0119
0120
0121 static const struct {
0122 const char *name;
0123 const char * const *group_names;
0124 u32 func;
0125 } madera_mux_funcs[] = {
0126 {
0127 .name = "aif1",
0128 .group_names = madera_aif1_group_names,
0129 .func = 0x000
0130 },
0131 {
0132 .name = "aif2",
0133 .group_names = madera_aif2_group_names,
0134 .func = 0x000
0135 },
0136 {
0137 .name = "aif3",
0138 .group_names = madera_aif3_group_names,
0139 .func = 0x000
0140 },
0141 {
0142 .name = "aif4",
0143 .group_names = madera_aif4_group_names,
0144 .func = 0x000
0145 },
0146 {
0147 .name = "mif1",
0148 .group_names = madera_mif1_group_names,
0149 .func = 0x000
0150 },
0151 {
0152 .name = "mif2",
0153 .group_names = madera_mif2_group_names,
0154 .func = 0x000
0155 },
0156 {
0157 .name = "mif3",
0158 .group_names = madera_mif3_group_names,
0159 .func = 0x000
0160 },
0161 {
0162 .name = "dmic3",
0163 .group_names = madera_dmic3_group_names,
0164 .func = 0x000
0165 },
0166 {
0167 .name = "dmic4",
0168 .group_names = madera_dmic4_group_names,
0169 .func = 0x000
0170 },
0171 {
0172 .name = "dmic5",
0173 .group_names = madera_dmic5_group_names,
0174 .func = 0x000
0175 },
0176 {
0177 .name = "dmic6",
0178 .group_names = madera_dmic6_group_names,
0179 .func = 0x000
0180 },
0181 {
0182 .name = "pdmspk1",
0183 .group_names = madera_spk1_group_names,
0184 .func = 0x000
0185 },
0186 {
0187 .name = "pdmspk2",
0188 .group_names = madera_spk2_group_names,
0189 .func = 0x000
0190 },
0191 {
0192 .name = "io",
0193 .group_names = madera_pin_single_group_names,
0194 .func = 0x001
0195 },
0196 {
0197 .name = "dsp-gpio",
0198 .group_names = madera_pin_single_group_names,
0199 .func = 0x002
0200 },
0201 {
0202 .name = "irq1",
0203 .group_names = madera_pin_single_group_names,
0204 .func = 0x003
0205 },
0206 {
0207 .name = "irq2",
0208 .group_names = madera_pin_single_group_names,
0209 .func = 0x004
0210 },
0211 {
0212 .name = "fll1-clk",
0213 .group_names = madera_pin_single_group_names,
0214 .func = 0x010
0215 },
0216 {
0217 .name = "fll2-clk",
0218 .group_names = madera_pin_single_group_names,
0219 .func = 0x011
0220 },
0221 {
0222 .name = "fll3-clk",
0223 .group_names = madera_pin_single_group_names,
0224 .func = 0x012
0225 },
0226 {
0227 .name = "fllao-clk",
0228 .group_names = madera_pin_single_group_names,
0229 .func = 0x013
0230 },
0231 {
0232 .name = "fll1-lock",
0233 .group_names = madera_pin_single_group_names,
0234 .func = 0x018
0235 },
0236 {
0237 .name = "fll2-lock",
0238 .group_names = madera_pin_single_group_names,
0239 .func = 0x019
0240 },
0241 {
0242 .name = "fll3-lock",
0243 .group_names = madera_pin_single_group_names,
0244 .func = 0x01a
0245 },
0246 {
0247 .name = "fllao-lock",
0248 .group_names = madera_pin_single_group_names,
0249 .func = 0x01b
0250 },
0251 {
0252 .name = "opclk",
0253 .group_names = madera_pin_single_group_names,
0254 .func = 0x040
0255 },
0256 {
0257 .name = "opclk-async",
0258 .group_names = madera_pin_single_group_names,
0259 .func = 0x041
0260 },
0261 {
0262 .name = "pwm1",
0263 .group_names = madera_pin_single_group_names,
0264 .func = 0x048
0265 },
0266 {
0267 .name = "pwm2",
0268 .group_names = madera_pin_single_group_names,
0269 .func = 0x049
0270 },
0271 {
0272 .name = "spdif",
0273 .group_names = madera_pin_single_group_names,
0274 .func = 0x04c
0275 },
0276 {
0277 .name = "asrc1-in1-lock",
0278 .group_names = madera_pin_single_group_names,
0279 .func = 0x088
0280 },
0281 {
0282 .name = "asrc1-in2-lock",
0283 .group_names = madera_pin_single_group_names,
0284 .func = 0x089
0285 },
0286 {
0287 .name = "asrc2-in1-lock",
0288 .group_names = madera_pin_single_group_names,
0289 .func = 0x08a
0290 },
0291 {
0292 .name = "asrc2-in2-lock",
0293 .group_names = madera_pin_single_group_names,
0294 .func = 0x08b
0295 },
0296 {
0297 .name = "spkl-short-circuit",
0298 .group_names = madera_pin_single_group_names,
0299 .func = 0x0b6
0300 },
0301 {
0302 .name = "spkr-short-circuit",
0303 .group_names = madera_pin_single_group_names,
0304 .func = 0x0b7
0305 },
0306 {
0307 .name = "spk-shutdown",
0308 .group_names = madera_pin_single_group_names,
0309 .func = 0x0e0
0310 },
0311 {
0312 .name = "spk-overheat-shutdown",
0313 .group_names = madera_pin_single_group_names,
0314 .func = 0x0e1
0315 },
0316 {
0317 .name = "spk-overheat-warn",
0318 .group_names = madera_pin_single_group_names,
0319 .func = 0x0e2
0320 },
0321 {
0322 .name = "timer1-sts",
0323 .group_names = madera_pin_single_group_names,
0324 .func = 0x140
0325 },
0326 {
0327 .name = "timer2-sts",
0328 .group_names = madera_pin_single_group_names,
0329 .func = 0x141
0330 },
0331 {
0332 .name = "timer3-sts",
0333 .group_names = madera_pin_single_group_names,
0334 .func = 0x142
0335 },
0336 {
0337 .name = "timer4-sts",
0338 .group_names = madera_pin_single_group_names,
0339 .func = 0x143
0340 },
0341 {
0342 .name = "timer5-sts",
0343 .group_names = madera_pin_single_group_names,
0344 .func = 0x144
0345 },
0346 {
0347 .name = "timer6-sts",
0348 .group_names = madera_pin_single_group_names,
0349 .func = 0x145
0350 },
0351 {
0352 .name = "timer7-sts",
0353 .group_names = madera_pin_single_group_names,
0354 .func = 0x146
0355 },
0356 {
0357 .name = "timer8-sts",
0358 .group_names = madera_pin_single_group_names,
0359 .func = 0x147
0360 },
0361 {
0362 .name = "log1-fifo-ne",
0363 .group_names = madera_pin_single_group_names,
0364 .func = 0x150
0365 },
0366 {
0367 .name = "log2-fifo-ne",
0368 .group_names = madera_pin_single_group_names,
0369 .func = 0x151
0370 },
0371 {
0372 .name = "log3-fifo-ne",
0373 .group_names = madera_pin_single_group_names,
0374 .func = 0x152
0375 },
0376 {
0377 .name = "log4-fifo-ne",
0378 .group_names = madera_pin_single_group_names,
0379 .func = 0x153
0380 },
0381 {
0382 .name = "log5-fifo-ne",
0383 .group_names = madera_pin_single_group_names,
0384 .func = 0x154
0385 },
0386 {
0387 .name = "log6-fifo-ne",
0388 .group_names = madera_pin_single_group_names,
0389 .func = 0x155
0390 },
0391 {
0392 .name = "log7-fifo-ne",
0393 .group_names = madera_pin_single_group_names,
0394 .func = 0x156
0395 },
0396 {
0397 .name = "log8-fifo-ne",
0398 .group_names = madera_pin_single_group_names,
0399 .func = 0x157
0400 },
0401 {
0402 .name = "aux-pdm-clk",
0403 .group_names = madera_pin_single_group_names,
0404 .func = 0x280
0405 },
0406 {
0407 .name = "aux-pdm-dat",
0408 .group_names = madera_pin_single_group_names,
0409 .func = 0x281
0410 },
0411 };
0412
0413 static u16 madera_pin_make_drv_str(struct madera_pin_private *priv,
0414 unsigned int milliamps)
0415 {
0416 switch (milliamps) {
0417 case 4:
0418 return 0;
0419 case 8:
0420 return 2 << MADERA_GP1_DRV_STR_SHIFT;
0421 default:
0422 break;
0423 }
0424
0425 dev_warn(priv->dev, "%u mA not a valid drive strength", milliamps);
0426
0427 return 0;
0428 }
0429
0430 static unsigned int madera_pin_unmake_drv_str(struct madera_pin_private *priv,
0431 u16 regval)
0432 {
0433 regval = (regval & MADERA_GP1_DRV_STR_MASK) >> MADERA_GP1_DRV_STR_SHIFT;
0434
0435 switch (regval) {
0436 case 0:
0437 return 4;
0438 case 2:
0439 return 8;
0440 default:
0441 return 0;
0442 }
0443 }
0444
0445 static int madera_get_groups_count(struct pinctrl_dev *pctldev)
0446 {
0447 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0448
0449
0450 return priv->chip->n_pin_groups + priv->chip->n_pins;
0451 }
0452
0453 static const char *madera_get_group_name(struct pinctrl_dev *pctldev,
0454 unsigned int selector)
0455 {
0456 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0457
0458 if (selector < priv->chip->n_pin_groups)
0459 return priv->chip->pin_groups[selector].name;
0460
0461 selector -= priv->chip->n_pin_groups;
0462 return madera_pin_single_group_names[selector];
0463 }
0464
0465 static int madera_get_group_pins(struct pinctrl_dev *pctldev,
0466 unsigned int selector,
0467 const unsigned int **pins,
0468 unsigned int *num_pins)
0469 {
0470 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0471
0472 if (selector < priv->chip->n_pin_groups) {
0473 *pins = priv->chip->pin_groups[selector].pins;
0474 *num_pins = priv->chip->pin_groups[selector].n_pins;
0475 } else {
0476
0477 selector -= priv->chip->n_pin_groups;
0478 *pins = &madera_pin_single_group_pins[selector];
0479 *num_pins = 1;
0480 }
0481 return 0;
0482 }
0483
0484 static void madera_pin_dbg_show_fn(struct madera_pin_private *priv,
0485 struct seq_file *s,
0486 unsigned int pin, unsigned int fn)
0487 {
0488 const struct madera_pin_chip *chip = priv->chip;
0489 int i, g_pin;
0490
0491 if (fn != 0) {
0492 for (i = 0; i < ARRAY_SIZE(madera_mux_funcs); ++i) {
0493 if (madera_mux_funcs[i].func == fn) {
0494 seq_printf(s, " FN=%s",
0495 madera_mux_funcs[i].name);
0496 return;
0497 }
0498 }
0499 return;
0500 }
0501
0502
0503 for (i = 0; i < chip->n_pin_groups; ++i) {
0504 for (g_pin = 0; g_pin < chip->pin_groups[i].n_pins; ++g_pin) {
0505 if (chip->pin_groups[i].pins[g_pin] == pin) {
0506 seq_printf(s, " FN=%s",
0507 chip->pin_groups[i].name);
0508 return;
0509 }
0510 }
0511 }
0512 }
0513
0514 static void __maybe_unused madera_pin_dbg_show(struct pinctrl_dev *pctldev,
0515 struct seq_file *s,
0516 unsigned int pin)
0517 {
0518 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0519 unsigned int conf[2];
0520 unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
0521 unsigned int fn;
0522 int ret;
0523
0524 ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
0525 if (ret)
0526 return;
0527
0528 ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
0529 if (ret)
0530 return;
0531
0532 seq_printf(s, "%04x:%04x", conf[0], conf[1]);
0533
0534 fn = (conf[0] & MADERA_GP1_FN_MASK) >> MADERA_GP1_FN_SHIFT;
0535 madera_pin_dbg_show_fn(priv, s, pin, fn);
0536
0537
0538 if (fn == 1) {
0539 if (conf[1] & MADERA_GP1_DIR_MASK)
0540 seq_puts(s, " IN");
0541 else
0542 seq_puts(s, " OUT");
0543 }
0544
0545 if (conf[1] & MADERA_GP1_PU_MASK)
0546 seq_puts(s, " PU");
0547
0548 if (conf[1] & MADERA_GP1_PD_MASK)
0549 seq_puts(s, " PD");
0550
0551 if (conf[0] & MADERA_GP1_DB_MASK)
0552 seq_puts(s, " DB");
0553
0554 if (conf[0] & MADERA_GP1_OP_CFG_MASK)
0555 seq_puts(s, " OD");
0556 else
0557 seq_puts(s, " CMOS");
0558
0559 seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
0560
0561 if (conf[0] & MADERA_GP1_IP_CFG_MASK)
0562 seq_puts(s, " SCHMITT");
0563 }
0564
0565 static const struct pinctrl_ops madera_pin_group_ops = {
0566 .get_groups_count = madera_get_groups_count,
0567 .get_group_name = madera_get_group_name,
0568 .get_group_pins = madera_get_group_pins,
0569 #if IS_ENABLED(CONFIG_OF)
0570 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
0571 .dt_free_map = pinctrl_utils_free_map,
0572 #endif
0573 #if IS_ENABLED(CONFIG_DEBUG_FS)
0574 .pin_dbg_show = madera_pin_dbg_show,
0575 #endif
0576 };
0577
0578 static int madera_mux_get_funcs_count(struct pinctrl_dev *pctldev)
0579 {
0580 return ARRAY_SIZE(madera_mux_funcs);
0581 }
0582
0583 static const char *madera_mux_get_func_name(struct pinctrl_dev *pctldev,
0584 unsigned int selector)
0585 {
0586 return madera_mux_funcs[selector].name;
0587 }
0588
0589 static int madera_mux_get_groups(struct pinctrl_dev *pctldev,
0590 unsigned int selector,
0591 const char * const **groups,
0592 unsigned int * const num_groups)
0593 {
0594 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0595
0596 *groups = madera_mux_funcs[selector].group_names;
0597
0598 if (madera_mux_funcs[selector].func == 0) {
0599
0600 *num_groups = 1;
0601 } else {
0602
0603 *num_groups = priv->chip->n_pins;
0604 }
0605
0606 return 0;
0607 }
0608
0609 static int madera_mux_set_mux(struct pinctrl_dev *pctldev,
0610 unsigned int selector,
0611 unsigned int group)
0612 {
0613 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0614 struct madera *madera = priv->madera;
0615 const struct madera_pin_groups *pin_group = priv->chip->pin_groups;
0616 unsigned int n_chip_groups = priv->chip->n_pin_groups;
0617 const char *func_name = madera_mux_funcs[selector].name;
0618 unsigned int reg;
0619 int i, ret = 0;
0620
0621 dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
0622 __func__, selector, func_name, group,
0623 madera_get_group_name(pctldev, group));
0624
0625 if (madera_mux_funcs[selector].func == 0) {
0626
0627 for (i = 0; i < n_chip_groups; ++i) {
0628 if (strcmp(func_name, pin_group->name) == 0)
0629 break;
0630
0631 ++pin_group;
0632 }
0633
0634 if (i == n_chip_groups)
0635 return -EINVAL;
0636
0637 for (i = 0; i < pin_group->n_pins; ++i) {
0638 reg = MADERA_GPIO1_CTRL_1 + (2 * pin_group->pins[i]);
0639
0640 dev_dbg(priv->dev, "%s setting 0x%x func bits to 0\n",
0641 __func__, reg);
0642
0643 ret = regmap_update_bits(madera->regmap, reg,
0644 MADERA_GP1_FN_MASK, 0);
0645 if (ret)
0646 break;
0647
0648 }
0649 } else {
0650
0651
0652
0653
0654
0655 group -= n_chip_groups;
0656 reg = MADERA_GPIO1_CTRL_1 + (2 * group);
0657
0658 dev_dbg(priv->dev, "%s setting 0x%x func bits to 0x%x\n",
0659 __func__, reg, madera_mux_funcs[selector].func);
0660
0661 ret = regmap_update_bits(madera->regmap,
0662 reg,
0663 MADERA_GP1_FN_MASK,
0664 madera_mux_funcs[selector].func);
0665 }
0666
0667 if (ret)
0668 dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
0669
0670 return ret;
0671 }
0672
0673 static int madera_gpio_set_direction(struct pinctrl_dev *pctldev,
0674 struct pinctrl_gpio_range *range,
0675 unsigned int offset,
0676 bool input)
0677 {
0678 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0679 struct madera *madera = priv->madera;
0680 unsigned int reg = MADERA_GPIO1_CTRL_2 + (2 * offset);
0681 unsigned int val;
0682 int ret;
0683
0684 if (input)
0685 val = MADERA_GP1_DIR;
0686 else
0687 val = 0;
0688
0689 ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_DIR_MASK, val);
0690 if (ret)
0691 dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
0692
0693 return ret;
0694 }
0695
0696 static int madera_gpio_request_enable(struct pinctrl_dev *pctldev,
0697 struct pinctrl_gpio_range *range,
0698 unsigned int offset)
0699 {
0700 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0701 struct madera *madera = priv->madera;
0702 unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
0703 int ret;
0704
0705
0706 ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
0707 if (ret)
0708 dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
0709
0710 return ret;
0711 }
0712
0713 static void madera_gpio_disable_free(struct pinctrl_dev *pctldev,
0714 struct pinctrl_gpio_range *range,
0715 unsigned int offset)
0716 {
0717 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0718 struct madera *madera = priv->madera;
0719 unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
0720 int ret;
0721
0722
0723 madera_gpio_set_direction(pctldev, range, offset, true);
0724
0725 ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
0726 if (ret)
0727 dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
0728 }
0729
0730 static const struct pinmux_ops madera_pin_mux_ops = {
0731 .get_functions_count = madera_mux_get_funcs_count,
0732 .get_function_name = madera_mux_get_func_name,
0733 .get_function_groups = madera_mux_get_groups,
0734 .set_mux = madera_mux_set_mux,
0735 .gpio_request_enable = madera_gpio_request_enable,
0736 .gpio_disable_free = madera_gpio_disable_free,
0737 .gpio_set_direction = madera_gpio_set_direction,
0738 .strict = true,
0739 };
0740
0741 static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
0742 unsigned long *config)
0743 {
0744 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0745 unsigned int param = pinconf_to_config_param(*config);
0746 unsigned int result = 0;
0747 unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
0748 unsigned int conf[2];
0749 int ret;
0750
0751 ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
0752 if (!ret)
0753 ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
0754
0755 if (ret) {
0756 dev_err(priv->dev, "Failed to read GP%d conf (%d)\n",
0757 pin + 1, ret);
0758 return ret;
0759 }
0760
0761 switch (param) {
0762 case PIN_CONFIG_BIAS_BUS_HOLD:
0763 conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0764 if (conf[1] == (MADERA_GP1_PU | MADERA_GP1_PD))
0765 result = 1;
0766 break;
0767 case PIN_CONFIG_BIAS_DISABLE:
0768 conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0769 if (!conf[1])
0770 result = 1;
0771 break;
0772 case PIN_CONFIG_BIAS_PULL_DOWN:
0773 conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0774 if (conf[1] == MADERA_GP1_PD_MASK)
0775 result = 1;
0776 break;
0777 case PIN_CONFIG_BIAS_PULL_UP:
0778 conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0779 if (conf[1] == MADERA_GP1_PU_MASK)
0780 result = 1;
0781 break;
0782 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
0783 if (conf[0] & MADERA_GP1_OP_CFG_MASK)
0784 result = 1;
0785 break;
0786 case PIN_CONFIG_DRIVE_PUSH_PULL:
0787 if (!(conf[0] & MADERA_GP1_OP_CFG_MASK))
0788 result = 1;
0789 break;
0790 case PIN_CONFIG_DRIVE_STRENGTH:
0791 result = madera_pin_unmake_drv_str(priv, conf[1]);
0792 break;
0793 case PIN_CONFIG_INPUT_DEBOUNCE:
0794 if (conf[0] & MADERA_GP1_DB_MASK)
0795 result = 1;
0796 break;
0797 case PIN_CONFIG_INPUT_ENABLE:
0798 if (conf[0] & MADERA_GP1_DIR_MASK)
0799 result = 1;
0800 break;
0801 case PIN_CONFIG_INPUT_SCHMITT:
0802 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
0803 if (conf[0] & MADERA_GP1_IP_CFG_MASK)
0804 result = 1;
0805 break;
0806 case PIN_CONFIG_OUTPUT:
0807 if ((conf[1] & MADERA_GP1_DIR_MASK) &&
0808 (conf[0] & MADERA_GP1_LVL_MASK))
0809 result = 1;
0810 break;
0811 default:
0812 return -ENOTSUPP;
0813 }
0814
0815 *config = pinconf_to_config_packed(param, result);
0816
0817 return 0;
0818 }
0819
0820 static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
0821 unsigned long *configs, unsigned int num_configs)
0822 {
0823 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0824 u16 conf[2] = {0, 0};
0825 u16 mask[2] = {0, 0};
0826 unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
0827 unsigned int val;
0828 int ret;
0829
0830 while (num_configs) {
0831 dev_dbg(priv->dev, "%s config 0x%lx\n", __func__, *configs);
0832
0833 switch (pinconf_to_config_param(*configs)) {
0834 case PIN_CONFIG_BIAS_BUS_HOLD:
0835 mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0836 conf[1] |= MADERA_GP1_PU | MADERA_GP1_PD;
0837 break;
0838 case PIN_CONFIG_BIAS_DISABLE:
0839 mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0840 conf[1] &= ~(MADERA_GP1_PU | MADERA_GP1_PD);
0841 break;
0842 case PIN_CONFIG_BIAS_PULL_DOWN:
0843 mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0844 conf[1] |= MADERA_GP1_PD;
0845 conf[1] &= ~MADERA_GP1_PU;
0846 break;
0847 case PIN_CONFIG_BIAS_PULL_UP:
0848 mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
0849 conf[1] |= MADERA_GP1_PU;
0850 conf[1] &= ~MADERA_GP1_PD;
0851 break;
0852 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
0853 mask[0] |= MADERA_GP1_OP_CFG_MASK;
0854 conf[0] |= MADERA_GP1_OP_CFG;
0855 break;
0856 case PIN_CONFIG_DRIVE_PUSH_PULL:
0857 mask[0] |= MADERA_GP1_OP_CFG_MASK;
0858 conf[0] &= ~MADERA_GP1_OP_CFG;
0859 break;
0860 case PIN_CONFIG_DRIVE_STRENGTH:
0861 val = pinconf_to_config_argument(*configs);
0862 mask[1] |= MADERA_GP1_DRV_STR_MASK;
0863 conf[1] &= ~MADERA_GP1_DRV_STR_MASK;
0864 conf[1] |= madera_pin_make_drv_str(priv, val);
0865 break;
0866 case PIN_CONFIG_INPUT_DEBOUNCE:
0867 mask[0] |= MADERA_GP1_DB_MASK;
0868
0869
0870
0871
0872
0873 val = pinconf_to_config_argument(*configs);
0874 if (val)
0875 conf[0] |= MADERA_GP1_DB;
0876 else
0877 conf[0] &= ~MADERA_GP1_DB;
0878 break;
0879 case PIN_CONFIG_INPUT_ENABLE:
0880 val = pinconf_to_config_argument(*configs);
0881 mask[1] |= MADERA_GP1_DIR_MASK;
0882 if (val)
0883 conf[1] |= MADERA_GP1_DIR;
0884 else
0885 conf[1] &= ~MADERA_GP1_DIR;
0886 break;
0887 case PIN_CONFIG_INPUT_SCHMITT:
0888 val = pinconf_to_config_argument(*configs);
0889 mask[0] |= MADERA_GP1_IP_CFG;
0890 if (val)
0891 conf[0] |= MADERA_GP1_IP_CFG;
0892 else
0893 conf[0] &= ~MADERA_GP1_IP_CFG;
0894
0895 mask[1] |= MADERA_GP1_DIR_MASK;
0896 conf[1] |= MADERA_GP1_DIR;
0897 break;
0898 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
0899 mask[0] |= MADERA_GP1_IP_CFG;
0900 conf[0] |= MADERA_GP1_IP_CFG;
0901 mask[1] |= MADERA_GP1_DIR_MASK;
0902 conf[1] |= MADERA_GP1_DIR;
0903 break;
0904 case PIN_CONFIG_OUTPUT:
0905 val = pinconf_to_config_argument(*configs);
0906 mask[0] |= MADERA_GP1_LVL_MASK;
0907 if (val)
0908 conf[0] |= MADERA_GP1_LVL;
0909 else
0910 conf[0] &= ~MADERA_GP1_LVL;
0911
0912 mask[1] |= MADERA_GP1_DIR_MASK;
0913 conf[1] &= ~MADERA_GP1_DIR;
0914 break;
0915 default:
0916 return -ENOTSUPP;
0917 }
0918
0919 ++configs;
0920 --num_configs;
0921 }
0922
0923 dev_dbg(priv->dev,
0924 "%s gpio%d 0x%x:0x%x 0x%x:0x%x\n",
0925 __func__, pin + 1, reg, conf[0], reg + 1, conf[1]);
0926
0927 ret = regmap_update_bits(priv->madera->regmap, reg, mask[0], conf[0]);
0928 if (ret)
0929 goto err;
0930
0931 ++reg;
0932 ret = regmap_update_bits(priv->madera->regmap, reg, mask[1], conf[1]);
0933 if (ret)
0934 goto err;
0935
0936 return 0;
0937
0938 err:
0939 dev_err(priv->dev,
0940 "Failed to write GPIO%d conf (%d) reg 0x%x\n",
0941 pin + 1, ret, reg);
0942
0943 return ret;
0944 }
0945
0946 static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
0947 unsigned int selector,
0948 unsigned long *configs,
0949 unsigned int num_configs)
0950 {
0951 struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
0952 const struct madera_pin_groups *pin_group;
0953 unsigned int n_groups = priv->chip->n_pin_groups;
0954 int i, ret;
0955
0956 dev_dbg(priv->dev, "%s setting group %s\n", __func__,
0957 madera_get_group_name(pctldev, selector));
0958
0959 if (selector >= n_groups) {
0960
0961 return madera_pin_conf_set(pctldev,
0962 selector - n_groups,
0963 configs,
0964 num_configs);
0965 } else {
0966 pin_group = &priv->chip->pin_groups[selector];
0967
0968 for (i = 0; i < pin_group->n_pins; ++i) {
0969 ret = madera_pin_conf_set(pctldev,
0970 pin_group->pins[i],
0971 configs,
0972 num_configs);
0973 if (ret)
0974 return ret;
0975 }
0976 }
0977
0978 return 0;
0979 }
0980
0981 static const struct pinconf_ops madera_pin_conf_ops = {
0982 .is_generic = true,
0983 .pin_config_get = madera_pin_conf_get,
0984 .pin_config_set = madera_pin_conf_set,
0985 .pin_config_group_set = madera_pin_conf_group_set,
0986 };
0987
0988 static struct pinctrl_desc madera_pin_desc = {
0989 .name = "madera-pinctrl",
0990 .pins = madera_pins,
0991 .pctlops = &madera_pin_group_ops,
0992 .pmxops = &madera_pin_mux_ops,
0993 .confops = &madera_pin_conf_ops,
0994 .owner = THIS_MODULE,
0995 };
0996
0997 static int madera_pin_probe(struct platform_device *pdev)
0998 {
0999 struct madera *madera = dev_get_drvdata(pdev->dev.parent);
1000 const struct madera_pdata *pdata = &madera->pdata;
1001 struct madera_pin_private *priv;
1002 int ret;
1003
1004 BUILD_BUG_ON(ARRAY_SIZE(madera_pin_single_group_names) !=
1005 ARRAY_SIZE(madera_pin_single_group_pins));
1006
1007 dev_dbg(&pdev->dev, "%s\n", __func__);
1008
1009 device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent));
1010
1011 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1012 if (!priv)
1013 return -ENOMEM;
1014
1015 priv->dev = &pdev->dev;
1016 priv->madera = madera;
1017
1018 switch (madera->type) {
1019 case CS47L15:
1020 if (IS_ENABLED(CONFIG_PINCTRL_CS47L15))
1021 priv->chip = &cs47l15_pin_chip;
1022 break;
1023 case CS47L35:
1024 if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
1025 priv->chip = &cs47l35_pin_chip;
1026 break;
1027 case CS47L85:
1028 case WM1840:
1029 if (IS_ENABLED(CONFIG_PINCTRL_CS47L85))
1030 priv->chip = &cs47l85_pin_chip;
1031 break;
1032 case CS47L90:
1033 case CS47L91:
1034 if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
1035 priv->chip = &cs47l90_pin_chip;
1036 break;
1037 case CS42L92:
1038 case CS47L92:
1039 case CS47L93:
1040 if (IS_ENABLED(CONFIG_PINCTRL_CS47L92))
1041 priv->chip = &cs47l92_pin_chip;
1042 break;
1043 default:
1044 break;
1045 }
1046
1047 if (!priv->chip)
1048 return -ENODEV;
1049
1050 madera_pin_desc.npins = priv->chip->n_pins;
1051
1052 ret = devm_pinctrl_register_and_init(&pdev->dev,
1053 &madera_pin_desc,
1054 priv,
1055 &priv->pctl);
1056 if (ret) {
1057 dev_err(priv->dev, "Failed pinctrl register (%d)\n", ret);
1058 return ret;
1059 }
1060
1061
1062 if (pdata->gpio_configs) {
1063 ret = pinctrl_register_mappings(pdata->gpio_configs,
1064 pdata->n_gpio_configs);
1065 if (ret) {
1066 dev_err(priv->dev,
1067 "Failed to register pdata mappings (%d)\n",
1068 ret);
1069 return ret;
1070 }
1071 }
1072
1073 ret = pinctrl_enable(priv->pctl);
1074 if (ret) {
1075 dev_err(priv->dev, "Failed to enable pinctrl (%d)\n", ret);
1076 return ret;
1077 }
1078
1079 platform_set_drvdata(pdev, priv);
1080
1081 dev_dbg(priv->dev, "pinctrl probed ok\n");
1082
1083 return 0;
1084 }
1085
1086 static int madera_pin_remove(struct platform_device *pdev)
1087 {
1088 struct madera_pin_private *priv = platform_get_drvdata(pdev);
1089
1090 if (priv->madera->pdata.gpio_configs)
1091 pinctrl_unregister_mappings(priv->madera->pdata.gpio_configs);
1092
1093 return 0;
1094 }
1095
1096 static struct platform_driver madera_pin_driver = {
1097 .probe = madera_pin_probe,
1098 .remove = madera_pin_remove,
1099 .driver = {
1100 .name = "madera-pinctrl",
1101 },
1102 };
1103
1104 module_platform_driver(madera_pin_driver);
1105
1106 MODULE_DESCRIPTION("Madera pinctrl driver");
1107 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1108 MODULE_LICENSE("GPL v2");