Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Pinctrl for Cirrus Logic Madera codecs
0004  *
0005  * Copyright (C) 2016-2018 Cirrus Logic
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  * Use pin GPIO names for consistency
0030  * NOTE: IDs are zero-indexed for coding convenience
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  * All single-pin functions can be mapped to any GPIO, however pinmux applies
0077  * functions to pin groups and only those groups declared as supporting that
0078  * function. To make this work we must put each pin in its own dummy group so
0079  * that the functions can be described as applying to all pins.
0080  * Since these do not correspond to anything in the actual hardware - they are
0081  * merely an adaptation to pinctrl's view of the world - we use the same name
0082  * as the pin to avoid confusion when comparing with datasheet instructions
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 /* set of pin numbers for single-pin groups, zero-indexed */
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  * alt-functions always apply to a single pin group, other functions always
0119  * apply to all pins
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     /* Number of alt function groups plus number of single-pin groups */
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         /* return the dummy group for a single pin */
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; /* ignore unknown function values */
0500     }
0501 
0502     /* alt function */
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     /* State of direction bit is only relevant if function==1 */
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         /* alt func always maps to a single group */
0600         *num_groups = 1;
0601     } else {
0602         /* other funcs map to all available gpio pins */
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         /* alt func pin assignments are codec-specific */
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          * for other funcs the group will be the gpio number and will
0652          * be offset by the number of chip-specific functions at the
0653          * start of the group list
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     /* put the pin into GPIO mode */
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     /* disable GPIO by setting to GPIO IN */
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, /* GPIO and other functions are exclusive */
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              * we can't configure debounce time per-pin so value
0871              * is just a flag
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         /* group is a single pin, convert to pin number and set */
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     /* if the configuration is provided through pdata, apply it */
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");