root/drivers/pinctrl/spear/pinctrl-spear.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. muxregs_endisable
  2. set_mode
  3. pmx_init_gpio_pingroup_addr
  4. pmx_init_addr
  5. spear_pinctrl_get_groups_cnt
  6. spear_pinctrl_get_group_name
  7. spear_pinctrl_get_group_pins
  8. spear_pinctrl_pin_dbg_show
  9. spear_pinctrl_dt_node_to_map
  10. spear_pinctrl_dt_free_map
  11. spear_pinctrl_get_funcs_count
  12. spear_pinctrl_get_func_name
  13. spear_pinctrl_get_func_groups
  14. spear_pinctrl_endisable
  15. spear_pinctrl_set_mux
  16. get_gpio_pingroup
  17. gpio_request_endisable
  18. gpio_request_enable
  19. gpio_disable_free
  20. spear_pinctrl_probe

   1 /*
   2  * Driver for the ST Microelectronics SPEAr pinmux
   3  *
   4  * Copyright (C) 2012 ST Microelectronics
   5  * Viresh Kumar <vireshk@kernel.org>
   6  *
   7  * Inspired from:
   8  * - U300 Pinctl drivers
   9  * - Tegra Pinctl drivers
  10  *
  11  * This file is licensed under the terms of the GNU General Public
  12  * License version 2. This program is licensed "as is" without any
  13  * warranty of any kind, whether express or implied.
  14  */
  15 
  16 #include <linux/err.h>
  17 #include <linux/module.h>
  18 #include <linux/of.h>
  19 #include <linux/of_address.h>
  20 #include <linux/of_gpio.h>
  21 #include <linux/pinctrl/machine.h>
  22 #include <linux/pinctrl/pinctrl.h>
  23 #include <linux/pinctrl/pinmux.h>
  24 #include <linux/platform_device.h>
  25 #include <linux/slab.h>
  26 
  27 #include "pinctrl-spear.h"
  28 
  29 #define DRIVER_NAME "spear-pinmux"
  30 
  31 static void muxregs_endisable(struct spear_pmx *pmx,
  32                 struct spear_muxreg *muxregs, u8 count, bool enable)
  33 {
  34         struct spear_muxreg *muxreg;
  35         u32 val, temp, j;
  36 
  37         for (j = 0; j < count; j++) {
  38                 muxreg = &muxregs[j];
  39 
  40                 val = pmx_readl(pmx, muxreg->reg);
  41                 val &= ~muxreg->mask;
  42 
  43                 if (enable)
  44                         temp = muxreg->val;
  45                 else
  46                         temp = ~muxreg->val;
  47 
  48                 val |= muxreg->mask & temp;
  49                 pmx_writel(pmx, val, muxreg->reg);
  50         }
  51 }
  52 
  53 static int set_mode(struct spear_pmx *pmx, int mode)
  54 {
  55         struct spear_pmx_mode *pmx_mode = NULL;
  56         int i;
  57         u32 val;
  58 
  59         if (!pmx->machdata->pmx_modes || !pmx->machdata->npmx_modes)
  60                 return -EINVAL;
  61 
  62         for (i = 0; i < pmx->machdata->npmx_modes; i++) {
  63                 if (pmx->machdata->pmx_modes[i]->mode == (1 << mode)) {
  64                         pmx_mode = pmx->machdata->pmx_modes[i];
  65                         break;
  66                 }
  67         }
  68 
  69         if (!pmx_mode)
  70                 return -EINVAL;
  71 
  72         val = pmx_readl(pmx, pmx_mode->reg);
  73         val &= ~pmx_mode->mask;
  74         val |= pmx_mode->val;
  75         pmx_writel(pmx, val, pmx_mode->reg);
  76 
  77         pmx->machdata->mode = pmx_mode->mode;
  78         dev_info(pmx->dev, "Configured Mode: %s with id: %x\n\n",
  79                         pmx_mode->name ? pmx_mode->name : "no_name",
  80                         pmx_mode->reg);
  81 
  82         return 0;
  83 }
  84 
  85 void pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
  86                                  unsigned count, u16 reg)
  87 {
  88         int i, j;
  89 
  90         for (i = 0; i < count; i++)
  91                 for (j = 0; j < gpio_pingroup[i].nmuxregs; j++)
  92                         gpio_pingroup[i].muxregs[j].reg = reg;
  93 }
  94 
  95 void pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
  96 {
  97         struct spear_pingroup *pgroup;
  98         struct spear_modemux *modemux;
  99         int i, j, group;
 100 
 101         for (group = 0; group < machdata->ngroups; group++) {
 102                 pgroup = machdata->groups[group];
 103 
 104                 for (i = 0; i < pgroup->nmodemuxs; i++) {
 105                         modemux = &pgroup->modemuxs[i];
 106 
 107                         for (j = 0; j < modemux->nmuxregs; j++)
 108                                 if (modemux->muxregs[j].reg == 0xFFFF)
 109                                         modemux->muxregs[j].reg = reg;
 110                 }
 111         }
 112 }
 113 
 114 static int spear_pinctrl_get_groups_cnt(struct pinctrl_dev *pctldev)
 115 {
 116         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 117 
 118         return pmx->machdata->ngroups;
 119 }
 120 
 121 static const char *spear_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
 122                 unsigned group)
 123 {
 124         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 125 
 126         return pmx->machdata->groups[group]->name;
 127 }
 128 
 129 static int spear_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
 130                 unsigned group, const unsigned **pins, unsigned *num_pins)
 131 {
 132         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 133 
 134         *pins = pmx->machdata->groups[group]->pins;
 135         *num_pins = pmx->machdata->groups[group]->npins;
 136 
 137         return 0;
 138 }
 139 
 140 static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
 141                 struct seq_file *s, unsigned offset)
 142 {
 143         seq_printf(s, " " DRIVER_NAME);
 144 }
 145 
 146 static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 147                                         struct device_node *np_config,
 148                                         struct pinctrl_map **map,
 149                                         unsigned *num_maps)
 150 {
 151         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 152         struct device_node *np;
 153         struct property *prop;
 154         const char *function, *group;
 155         int ret, index = 0, count = 0;
 156 
 157         /* calculate number of maps required */
 158         for_each_child_of_node(np_config, np) {
 159                 ret = of_property_read_string(np, "st,function", &function);
 160                 if (ret < 0) {
 161                         of_node_put(np);
 162                         return ret;
 163                 }
 164 
 165                 ret = of_property_count_strings(np, "st,pins");
 166                 if (ret < 0) {
 167                         of_node_put(np);
 168                         return ret;
 169                 }
 170 
 171                 count += ret;
 172         }
 173 
 174         if (!count) {
 175                 dev_err(pmx->dev, "No child nodes passed via DT\n");
 176                 return -ENODEV;
 177         }
 178 
 179         *map = kcalloc(count, sizeof(**map), GFP_KERNEL);
 180         if (!*map)
 181                 return -ENOMEM;
 182 
 183         for_each_child_of_node(np_config, np) {
 184                 of_property_read_string(np, "st,function", &function);
 185                 of_property_for_each_string(np, "st,pins", prop, group) {
 186                         (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
 187                         (*map)[index].data.mux.group = group;
 188                         (*map)[index].data.mux.function = function;
 189                         index++;
 190                 }
 191         }
 192 
 193         *num_maps = count;
 194 
 195         return 0;
 196 }
 197 
 198 static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
 199                                       struct pinctrl_map *map,
 200                                       unsigned num_maps)
 201 {
 202         kfree(map);
 203 }
 204 
 205 static const struct pinctrl_ops spear_pinctrl_ops = {
 206         .get_groups_count = spear_pinctrl_get_groups_cnt,
 207         .get_group_name = spear_pinctrl_get_group_name,
 208         .get_group_pins = spear_pinctrl_get_group_pins,
 209         .pin_dbg_show = spear_pinctrl_pin_dbg_show,
 210         .dt_node_to_map = spear_pinctrl_dt_node_to_map,
 211         .dt_free_map = spear_pinctrl_dt_free_map,
 212 };
 213 
 214 static int spear_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
 215 {
 216         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 217 
 218         return pmx->machdata->nfunctions;
 219 }
 220 
 221 static const char *spear_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
 222                 unsigned function)
 223 {
 224         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 225 
 226         return pmx->machdata->functions[function]->name;
 227 }
 228 
 229 static int spear_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
 230                 unsigned function, const char *const **groups,
 231                 unsigned * const ngroups)
 232 {
 233         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 234 
 235         *groups = pmx->machdata->functions[function]->groups;
 236         *ngroups = pmx->machdata->functions[function]->ngroups;
 237 
 238         return 0;
 239 }
 240 
 241 static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
 242                 unsigned function, unsigned group, bool enable)
 243 {
 244         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 245         const struct spear_pingroup *pgroup;
 246         const struct spear_modemux *modemux;
 247         int i;
 248         bool found = false;
 249 
 250         pgroup = pmx->machdata->groups[group];
 251 
 252         for (i = 0; i < pgroup->nmodemuxs; i++) {
 253                 modemux = &pgroup->modemuxs[i];
 254 
 255                 /* SoC have any modes */
 256                 if (pmx->machdata->modes_supported) {
 257                         if (!(pmx->machdata->mode & modemux->modes))
 258                                 continue;
 259                 }
 260 
 261                 found = true;
 262                 muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs,
 263                                 enable);
 264         }
 265 
 266         if (!found) {
 267                 dev_err(pmx->dev, "pinmux group: %s not supported\n",
 268                                 pgroup->name);
 269                 return -ENODEV;
 270         }
 271 
 272         return 0;
 273 }
 274 
 275 static int spear_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned function,
 276                 unsigned group)
 277 {
 278         return spear_pinctrl_endisable(pctldev, function, group, true);
 279 }
 280 
 281 /* gpio with pinmux */
 282 static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
 283                 unsigned pin)
 284 {
 285         struct spear_gpio_pingroup *gpio_pingroup;
 286         int i, j;
 287 
 288         if (!pmx->machdata->gpio_pingroups)
 289                 return NULL;
 290 
 291         for (i = 0; i < pmx->machdata->ngpio_pingroups; i++) {
 292                 gpio_pingroup = &pmx->machdata->gpio_pingroups[i];
 293 
 294                 for (j = 0; j < gpio_pingroup->npins; j++) {
 295                         if (gpio_pingroup->pins[j] == pin)
 296                                 return gpio_pingroup;
 297                 }
 298         }
 299 
 300         return NULL;
 301 }
 302 
 303 static int gpio_request_endisable(struct pinctrl_dev *pctldev,
 304                 struct pinctrl_gpio_range *range, unsigned offset, bool enable)
 305 {
 306         struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 307         struct spear_pinctrl_machdata *machdata = pmx->machdata;
 308         struct spear_gpio_pingroup *gpio_pingroup;
 309 
 310         /*
 311          * Some SoC have configuration options applicable to group of pins,
 312          * rather than a single pin.
 313          */
 314         gpio_pingroup = get_gpio_pingroup(pmx, offset);
 315         if (gpio_pingroup)
 316                 muxregs_endisable(pmx, gpio_pingroup->muxregs,
 317                                 gpio_pingroup->nmuxregs, enable);
 318 
 319         /*
 320          * SoC may need some extra configurations, or configurations for single
 321          * pin
 322          */
 323         if (machdata->gpio_request_endisable)
 324                 machdata->gpio_request_endisable(pmx, offset, enable);
 325 
 326         return 0;
 327 }
 328 
 329 static int gpio_request_enable(struct pinctrl_dev *pctldev,
 330                 struct pinctrl_gpio_range *range, unsigned offset)
 331 {
 332         return gpio_request_endisable(pctldev, range, offset, true);
 333 }
 334 
 335 static void gpio_disable_free(struct pinctrl_dev *pctldev,
 336                 struct pinctrl_gpio_range *range, unsigned offset)
 337 {
 338         gpio_request_endisable(pctldev, range, offset, false);
 339 }
 340 
 341 static const struct pinmux_ops spear_pinmux_ops = {
 342         .get_functions_count = spear_pinctrl_get_funcs_count,
 343         .get_function_name = spear_pinctrl_get_func_name,
 344         .get_function_groups = spear_pinctrl_get_func_groups,
 345         .set_mux = spear_pinctrl_set_mux,
 346         .gpio_request_enable = gpio_request_enable,
 347         .gpio_disable_free = gpio_disable_free,
 348 };
 349 
 350 static struct pinctrl_desc spear_pinctrl_desc = {
 351         .name = DRIVER_NAME,
 352         .pctlops = &spear_pinctrl_ops,
 353         .pmxops = &spear_pinmux_ops,
 354         .owner = THIS_MODULE,
 355 };
 356 
 357 int spear_pinctrl_probe(struct platform_device *pdev,
 358                         struct spear_pinctrl_machdata *machdata)
 359 {
 360         struct device_node *np = pdev->dev.of_node;
 361         struct resource *res;
 362         struct spear_pmx *pmx;
 363 
 364         if (!machdata)
 365                 return -ENODEV;
 366 
 367         pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
 368         if (!pmx)
 369                 return -ENOMEM;
 370 
 371         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 372         pmx->vbase = devm_ioremap_resource(&pdev->dev, res);
 373         if (IS_ERR(pmx->vbase))
 374                 return PTR_ERR(pmx->vbase);
 375 
 376         pmx->dev = &pdev->dev;
 377         pmx->machdata = machdata;
 378 
 379         /* configure mode, if supported by SoC */
 380         if (machdata->modes_supported) {
 381                 int mode = 0;
 382 
 383                 if (of_property_read_u32(np, "st,pinmux-mode", &mode)) {
 384                         dev_err(&pdev->dev, "OF: pinmux mode not passed\n");
 385                         return -EINVAL;
 386                 }
 387 
 388                 if (set_mode(pmx, mode)) {
 389                         dev_err(&pdev->dev, "OF: Couldn't configure mode: %x\n",
 390                                         mode);
 391                         return -EINVAL;
 392                 }
 393         }
 394 
 395         platform_set_drvdata(pdev, pmx);
 396 
 397         spear_pinctrl_desc.pins = machdata->pins;
 398         spear_pinctrl_desc.npins = machdata->npins;
 399 
 400         pmx->pctl = devm_pinctrl_register(&pdev->dev, &spear_pinctrl_desc, pmx);
 401         if (IS_ERR(pmx->pctl)) {
 402                 dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
 403                 return PTR_ERR(pmx->pctl);
 404         }
 405 
 406         return 0;
 407 }

/* [<][>][^][v][top][bottom][index][help] */