Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Marvell Berlin SoC pinctrl core driver
0004  *
0005  * Copyright (C) 2014 Marvell Technology Group Ltd.
0006  *
0007  * Antoine Ténart <antoine.tenart@free-electrons.com>
0008  */
0009 
0010 #include <linux/io.h>
0011 #include <linux/mfd/syscon.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_device.h>
0016 #include <linux/pinctrl/pinctrl.h>
0017 #include <linux/pinctrl/pinmux.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/regmap.h>
0020 #include <linux/slab.h>
0021 
0022 #include "../core.h"
0023 #include "../pinctrl-utils.h"
0024 #include "berlin.h"
0025 
0026 struct berlin_pinctrl {
0027     struct regmap *regmap;
0028     struct device *dev;
0029     const struct berlin_pinctrl_desc *desc;
0030     struct berlin_pinctrl_function *functions;
0031     unsigned nfunctions;
0032     struct pinctrl_dev *pctrl_dev;
0033 };
0034 
0035 static int berlin_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev)
0036 {
0037     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0038 
0039     return pctrl->desc->ngroups;
0040 }
0041 
0042 static const char *berlin_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
0043                          unsigned group)
0044 {
0045     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0046 
0047     return pctrl->desc->groups[group].name;
0048 }
0049 
0050 static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
0051                      struct device_node *node,
0052                      struct pinctrl_map **map,
0053                      unsigned *num_maps)
0054 {
0055     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0056     struct property *prop;
0057     const char *function_name, *group_name;
0058     unsigned reserved_maps = 0;
0059     int ret, ngroups;
0060 
0061     *map = NULL;
0062     *num_maps = 0;
0063 
0064     ret = of_property_read_string(node, "function", &function_name);
0065     if (ret) {
0066         dev_err(pctrl->dev,
0067             "missing function property in node %pOFn\n", node);
0068         return -EINVAL;
0069     }
0070 
0071     ngroups = of_property_count_strings(node, "groups");
0072     if (ngroups < 0) {
0073         dev_err(pctrl->dev,
0074             "missing groups property in node %pOFn\n", node);
0075         return -EINVAL;
0076     }
0077 
0078     ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps,
0079                     num_maps, ngroups);
0080     if (ret) {
0081         dev_err(pctrl->dev, "can't reserve map: %d\n", ret);
0082         return ret;
0083     }
0084 
0085     of_property_for_each_string(node, "groups", prop, group_name) {
0086         ret = pinctrl_utils_add_map_mux(pctrl_dev, map, &reserved_maps,
0087                         num_maps, group_name,
0088                         function_name);
0089         if (ret) {
0090             dev_err(pctrl->dev, "can't add map: %d\n", ret);
0091             return ret;
0092         }
0093     }
0094 
0095     return 0;
0096 }
0097 
0098 static const struct pinctrl_ops berlin_pinctrl_ops = {
0099     .get_groups_count   = &berlin_pinctrl_get_group_count,
0100     .get_group_name     = &berlin_pinctrl_get_group_name,
0101     .dt_node_to_map     = &berlin_pinctrl_dt_node_to_map,
0102     .dt_free_map        = &pinctrl_utils_free_map,
0103 };
0104 
0105 static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev)
0106 {
0107     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0108 
0109     return pctrl->nfunctions;
0110 }
0111 
0112 static const char *berlin_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev,
0113                            unsigned function)
0114 {
0115     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0116 
0117     return pctrl->functions[function].name;
0118 }
0119 
0120 static int berlin_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev,
0121                          unsigned function,
0122                          const char * const **groups,
0123                          unsigned * const num_groups)
0124 {
0125     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0126 
0127     *groups = pctrl->functions[function].groups;
0128     *num_groups = pctrl->functions[function].ngroups;
0129 
0130     return 0;
0131 }
0132 
0133 static struct berlin_desc_function *
0134 berlin_pinctrl_find_function_by_name(struct berlin_pinctrl *pctrl,
0135                      const struct berlin_desc_group *group,
0136                      const char *fname)
0137 {
0138     struct berlin_desc_function *function = group->functions;
0139 
0140     while (function->name) {
0141         if (!strcmp(function->name, fname))
0142             return function;
0143 
0144         function++;
0145     }
0146 
0147     return NULL;
0148 }
0149 
0150 static int berlin_pinmux_set(struct pinctrl_dev *pctrl_dev,
0151                  unsigned function,
0152                  unsigned group)
0153 {
0154     struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
0155     const struct berlin_desc_group *group_desc = pctrl->desc->groups + group;
0156     struct berlin_pinctrl_function *func = pctrl->functions + function;
0157     struct berlin_desc_function *function_desc =
0158         berlin_pinctrl_find_function_by_name(pctrl, group_desc,
0159                              func->name);
0160     u32 mask, val;
0161 
0162     if (!function_desc)
0163         return -EINVAL;
0164 
0165     mask = GENMASK(group_desc->lsb + group_desc->bit_width - 1,
0166                group_desc->lsb);
0167     val = function_desc->muxval << group_desc->lsb;
0168     regmap_update_bits(pctrl->regmap, group_desc->offset, mask, val);
0169 
0170     return 0;
0171 }
0172 
0173 static const struct pinmux_ops berlin_pinmux_ops = {
0174     .get_functions_count    = &berlin_pinmux_get_functions_count,
0175     .get_function_name  = &berlin_pinmux_get_function_name,
0176     .get_function_groups    = &berlin_pinmux_get_function_groups,
0177     .set_mux        = &berlin_pinmux_set,
0178 };
0179 
0180 static int berlin_pinctrl_add_function(struct berlin_pinctrl *pctrl,
0181                        const char *name)
0182 {
0183     struct berlin_pinctrl_function *function = pctrl->functions;
0184 
0185     while (function->name) {
0186         if (!strcmp(function->name, name)) {
0187             function->ngroups++;
0188             return -EEXIST;
0189         }
0190         function++;
0191     }
0192 
0193     function->name = name;
0194     function->ngroups = 1;
0195 
0196     pctrl->nfunctions++;
0197 
0198     return 0;
0199 }
0200 
0201 static int berlin_pinctrl_build_state(struct platform_device *pdev)
0202 {
0203     struct berlin_pinctrl *pctrl = platform_get_drvdata(pdev);
0204     const struct berlin_desc_group *desc_group;
0205     const struct berlin_desc_function *desc_function;
0206     int i, max_functions = 0;
0207 
0208     pctrl->nfunctions = 0;
0209 
0210     for (i = 0; i < pctrl->desc->ngroups; i++) {
0211         desc_group = pctrl->desc->groups + i;
0212         /* compute the maxiumum number of functions a group can have */
0213         max_functions += 1 << (desc_group->bit_width + 1);
0214     }
0215 
0216     /* we will reallocate later */
0217     pctrl->functions = kcalloc(max_functions,
0218                    sizeof(*pctrl->functions), GFP_KERNEL);
0219     if (!pctrl->functions)
0220         return -ENOMEM;
0221 
0222     /* register all functions */
0223     for (i = 0; i < pctrl->desc->ngroups; i++) {
0224         desc_group = pctrl->desc->groups + i;
0225         desc_function = desc_group->functions;
0226 
0227         while (desc_function->name) {
0228             berlin_pinctrl_add_function(pctrl, desc_function->name);
0229             desc_function++;
0230         }
0231     }
0232 
0233     pctrl->functions = krealloc(pctrl->functions,
0234                     pctrl->nfunctions * sizeof(*pctrl->functions),
0235                     GFP_KERNEL);
0236     if (!pctrl->functions)
0237         return -ENOMEM;
0238 
0239     /* map functions to theirs groups */
0240     for (i = 0; i < pctrl->desc->ngroups; i++) {
0241         desc_group = pctrl->desc->groups + i;
0242         desc_function = desc_group->functions;
0243 
0244         while (desc_function->name) {
0245             struct berlin_pinctrl_function
0246                 *function = pctrl->functions;
0247             const char **groups;
0248             bool found = false;
0249 
0250             while (function->name) {
0251                 if (!strcmp(desc_function->name, function->name)) {
0252                     found = true;
0253                     break;
0254                 }
0255                 function++;
0256             }
0257 
0258             if (!found) {
0259                 kfree(pctrl->functions);
0260                 return -EINVAL;
0261             }
0262 
0263             if (!function->groups) {
0264                 function->groups =
0265                     devm_kcalloc(&pdev->dev,
0266                              function->ngroups,
0267                              sizeof(char *),
0268                              GFP_KERNEL);
0269 
0270                 if (!function->groups) {
0271                     kfree(pctrl->functions);
0272                     return -ENOMEM;
0273                 }
0274             }
0275 
0276             groups = function->groups;
0277             while (*groups)
0278                 groups++;
0279 
0280             *groups = desc_group->name;
0281 
0282             desc_function++;
0283         }
0284     }
0285 
0286     return 0;
0287 }
0288 
0289 static struct pinctrl_desc berlin_pctrl_desc = {
0290     .name       = "berlin-pinctrl",
0291     .pctlops    = &berlin_pinctrl_ops,
0292     .pmxops     = &berlin_pinmux_ops,
0293     .owner      = THIS_MODULE,
0294 };
0295 
0296 int berlin_pinctrl_probe_regmap(struct platform_device *pdev,
0297                 const struct berlin_pinctrl_desc *desc,
0298                 struct regmap *regmap)
0299 {
0300     struct device *dev = &pdev->dev;
0301     struct berlin_pinctrl *pctrl;
0302     int ret;
0303 
0304     pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
0305     if (!pctrl)
0306         return -ENOMEM;
0307 
0308     platform_set_drvdata(pdev, pctrl);
0309 
0310     pctrl->regmap = regmap;
0311     pctrl->dev = &pdev->dev;
0312     pctrl->desc = desc;
0313 
0314     ret = berlin_pinctrl_build_state(pdev);
0315     if (ret) {
0316         dev_err(dev, "cannot build driver state: %d\n", ret);
0317         return ret;
0318     }
0319 
0320     pctrl->pctrl_dev = devm_pinctrl_register(dev, &berlin_pctrl_desc,
0321                          pctrl);
0322     if (IS_ERR(pctrl->pctrl_dev)) {
0323         dev_err(dev, "failed to register pinctrl driver\n");
0324         return PTR_ERR(pctrl->pctrl_dev);
0325     }
0326 
0327     return 0;
0328 }
0329 
0330 int berlin_pinctrl_probe(struct platform_device *pdev,
0331              const struct berlin_pinctrl_desc *desc)
0332 {
0333     struct device *dev = &pdev->dev;
0334     struct device_node *parent_np = of_get_parent(dev->of_node);
0335     struct regmap *regmap = syscon_node_to_regmap(parent_np);
0336 
0337     of_node_put(parent_np);
0338     if (IS_ERR(regmap))
0339         return PTR_ERR(regmap);
0340 
0341     return berlin_pinctrl_probe_regmap(pdev, desc, regmap);
0342 }