linux/drivers/pinctrl/pinctrl-sunxi.c
<<
>>
Prefs
   1/*
   2 * Allwinner A1X SoCs pinctrl driver.
   3 *
   4 * Copyright (C) 2012 Maxime Ripard
   5 *
   6 * Maxime Ripard <maxime.ripard@free-electrons.com>
   7 *
   8 * This file is licensed under the terms of the GNU General Public
   9 * License version 2.  This program is licensed "as is" without any
  10 * warranty of any kind, whether express or implied.
  11 */
  12
  13#include <linux/io.h>
  14#include <linux/clk.h>
  15#include <linux/gpio.h>
  16#include <linux/irqdomain.h>
  17#include <linux/module.h>
  18#include <linux/of.h>
  19#include <linux/of_address.h>
  20#include <linux/of_device.h>
  21#include <linux/of_irq.h>
  22#include <linux/pinctrl/consumer.h>
  23#include <linux/pinctrl/machine.h>
  24#include <linux/pinctrl/pinctrl.h>
  25#include <linux/pinctrl/pinconf-generic.h>
  26#include <linux/pinctrl/pinmux.h>
  27#include <linux/platform_device.h>
  28#include <linux/slab.h>
  29
  30#include "core.h"
  31#include "pinctrl-sunxi.h"
  32#include "pinctrl-sunxi-pins.h"
  33
  34static struct sunxi_pinctrl_group *
  35sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
  36{
  37        int i;
  38
  39        for (i = 0; i < pctl->ngroups; i++) {
  40                struct sunxi_pinctrl_group *grp = pctl->groups + i;
  41
  42                if (!strcmp(grp->name, group))
  43                        return grp;
  44        }
  45
  46        return NULL;
  47}
  48
  49static struct sunxi_pinctrl_function *
  50sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
  51                                    const char *name)
  52{
  53        struct sunxi_pinctrl_function *func = pctl->functions;
  54        int i;
  55
  56        for (i = 0; i < pctl->nfunctions; i++) {
  57                if (!func[i].name)
  58                        break;
  59
  60                if (!strcmp(func[i].name, name))
  61                        return func + i;
  62        }
  63
  64        return NULL;
  65}
  66
  67static struct sunxi_desc_function *
  68sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
  69                                         const char *pin_name,
  70                                         const char *func_name)
  71{
  72        int i;
  73
  74        for (i = 0; i < pctl->desc->npins; i++) {
  75                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
  76
  77                if (!strcmp(pin->pin.name, pin_name)) {
  78                        struct sunxi_desc_function *func = pin->functions;
  79
  80                        while (func->name) {
  81                                if (!strcmp(func->name, func_name))
  82                                        return func;
  83
  84                                func++;
  85                        }
  86                }
  87        }
  88
  89        return NULL;
  90}
  91
  92static struct sunxi_desc_function *
  93sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,
  94                                        const u16 pin_num,
  95                                        const char *func_name)
  96{
  97        int i;
  98
  99        for (i = 0; i < pctl->desc->npins; i++) {
 100                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 101
 102                if (pin->pin.number == pin_num) {
 103                        struct sunxi_desc_function *func = pin->functions;
 104
 105                        while (func->name) {
 106                                if (!strcmp(func->name, func_name))
 107                                        return func;
 108
 109                                func++;
 110                        }
 111                }
 112        }
 113
 114        return NULL;
 115}
 116
 117static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
 118{
 119        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 120
 121        return pctl->ngroups;
 122}
 123
 124static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
 125                                              unsigned group)
 126{
 127        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 128
 129        return pctl->groups[group].name;
 130}
 131
 132static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
 133                                      unsigned group,
 134                                      const unsigned **pins,
 135                                      unsigned *num_pins)
 136{
 137        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 138
 139        *pins = (unsigned *)&pctl->groups[group].pin;
 140        *num_pins = 1;
 141
 142        return 0;
 143}
 144
 145static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 146                                      struct device_node *node,
 147                                      struct pinctrl_map **map,
 148                                      unsigned *num_maps)
 149{
 150        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 151        unsigned long *pinconfig;
 152        struct property *prop;
 153        const char *function;
 154        const char *group;
 155        int ret, nmaps, i = 0;
 156        u32 val;
 157
 158        *map = NULL;
 159        *num_maps = 0;
 160
 161        ret = of_property_read_string(node, "allwinner,function", &function);
 162        if (ret) {
 163                dev_err(pctl->dev,
 164                        "missing allwinner,function property in node %s\n",
 165                        node->name);
 166                return -EINVAL;
 167        }
 168
 169        nmaps = of_property_count_strings(node, "allwinner,pins") * 2;
 170        if (nmaps < 0) {
 171                dev_err(pctl->dev,
 172                        "missing allwinner,pins property in node %s\n",
 173                        node->name);
 174                return -EINVAL;
 175        }
 176
 177        *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
 178        if (!map)
 179                return -ENOMEM;
 180
 181        of_property_for_each_string(node, "allwinner,pins", prop, group) {
 182                struct sunxi_pinctrl_group *grp =
 183                        sunxi_pinctrl_find_group_by_name(pctl, group);
 184                int j = 0, configlen = 0;
 185
 186                if (!grp) {
 187                        dev_err(pctl->dev, "unknown pin %s", group);
 188                        continue;
 189                }
 190
 191                if (!sunxi_pinctrl_desc_find_function_by_name(pctl,
 192                                                              grp->name,
 193                                                              function)) {
 194                        dev_err(pctl->dev, "unsupported function %s on pin %s",
 195                                function, group);
 196                        continue;
 197                }
 198
 199                (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
 200                (*map)[i].data.mux.group = group;
 201                (*map)[i].data.mux.function = function;
 202
 203                i++;
 204
 205                (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
 206                (*map)[i].data.configs.group_or_pin = group;
 207
 208                if (of_find_property(node, "allwinner,drive", NULL))
 209                        configlen++;
 210                if (of_find_property(node, "allwinner,pull", NULL))
 211                        configlen++;
 212
 213                pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
 214
 215                if (!of_property_read_u32(node, "allwinner,drive", &val)) {
 216                        u16 strength = (val + 1) * 10;
 217                        pinconfig[j++] =
 218                                pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
 219                                                         strength);
 220                }
 221
 222                if (!of_property_read_u32(node, "allwinner,pull", &val)) {
 223                        enum pin_config_param pull = PIN_CONFIG_END;
 224                        if (val == 1)
 225                                pull = PIN_CONFIG_BIAS_PULL_UP;
 226                        else if (val == 2)
 227                                pull = PIN_CONFIG_BIAS_PULL_DOWN;
 228                        pinconfig[j++] = pinconf_to_config_packed(pull, 0);
 229                }
 230
 231                (*map)[i].data.configs.configs = pinconfig;
 232                (*map)[i].data.configs.num_configs = configlen;
 233
 234                i++;
 235        }
 236
 237        *num_maps = nmaps;
 238
 239        return 0;
 240}
 241
 242static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
 243                                    struct pinctrl_map *map,
 244                                    unsigned num_maps)
 245{
 246        int i;
 247
 248        for (i = 0; i < num_maps; i++) {
 249                if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
 250                        kfree(map[i].data.configs.configs);
 251        }
 252
 253        kfree(map);
 254}
 255
 256static const struct pinctrl_ops sunxi_pctrl_ops = {
 257        .dt_node_to_map         = sunxi_pctrl_dt_node_to_map,
 258        .dt_free_map            = sunxi_pctrl_dt_free_map,
 259        .get_groups_count       = sunxi_pctrl_get_groups_count,
 260        .get_group_name         = sunxi_pctrl_get_group_name,
 261        .get_group_pins         = sunxi_pctrl_get_group_pins,
 262};
 263
 264static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
 265                                 unsigned group,
 266                                 unsigned long *config)
 267{
 268        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 269
 270        *config = pctl->groups[group].config;
 271
 272        return 0;
 273}
 274
 275static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
 276                                 unsigned group,
 277                                 unsigned long config)
 278{
 279        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 280        struct sunxi_pinctrl_group *g = &pctl->groups[group];
 281        unsigned long flags;
 282        u32 val, mask;
 283        u16 strength;
 284        u8 dlevel;
 285
 286        switch (pinconf_to_config_param(config)) {
 287        case PIN_CONFIG_DRIVE_STRENGTH:
 288                strength = pinconf_to_config_argument(config);
 289                if (strength > 40)
 290                        return -EINVAL;
 291                /*
 292                 * We convert from mA to what the register expects:
 293                 *   0: 10mA
 294                 *   1: 20mA
 295                 *   2: 30mA
 296                 *   3: 40mA
 297                 */
 298                dlevel = strength / 10 - 1;
 299
 300                spin_lock_irqsave(&pctl->lock, flags);
 301
 302                val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
 303                mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
 304                writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin),
 305                        pctl->membase + sunxi_dlevel_reg(g->pin));
 306
 307                spin_unlock_irqrestore(&pctl->lock, flags);
 308                break;
 309        case PIN_CONFIG_BIAS_PULL_UP:
 310                spin_lock_irqsave(&pctl->lock, flags);
 311
 312                val = readl(pctl->membase + sunxi_pull_reg(g->pin));
 313                mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
 314                writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin),
 315                        pctl->membase + sunxi_pull_reg(g->pin));
 316
 317                spin_unlock_irqrestore(&pctl->lock, flags);
 318                break;
 319        case PIN_CONFIG_BIAS_PULL_DOWN:
 320                spin_lock_irqsave(&pctl->lock, flags);
 321
 322                val = readl(pctl->membase + sunxi_pull_reg(g->pin));
 323                mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
 324                writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin),
 325                        pctl->membase + sunxi_pull_reg(g->pin));
 326
 327                spin_unlock_irqrestore(&pctl->lock, flags);
 328                break;
 329        default:
 330                break;
 331        }
 332
 333        /* cache the config value */
 334        g->config = config;
 335
 336        return 0;
 337}
 338
 339static const struct pinconf_ops sunxi_pconf_ops = {
 340        .pin_config_group_get   = sunxi_pconf_group_get,
 341        .pin_config_group_set   = sunxi_pconf_group_set,
 342};
 343
 344static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
 345{
 346        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 347
 348        return pctl->nfunctions;
 349}
 350
 351static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev,
 352                                           unsigned function)
 353{
 354        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 355
 356        return pctl->functions[function].name;
 357}
 358
 359static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev,
 360                                     unsigned function,
 361                                     const char * const **groups,
 362                                     unsigned * const num_groups)
 363{
 364        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 365
 366        *groups = pctl->functions[function].groups;
 367        *num_groups = pctl->functions[function].ngroups;
 368
 369        return 0;
 370}
 371
 372static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
 373                                 unsigned pin,
 374                                 u8 config)
 375{
 376        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 377        unsigned long flags;
 378        u32 val, mask;
 379
 380        spin_lock_irqsave(&pctl->lock, flags);
 381
 382        val = readl(pctl->membase + sunxi_mux_reg(pin));
 383        mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
 384        writel((val & ~mask) | config << sunxi_mux_offset(pin),
 385                pctl->membase + sunxi_mux_reg(pin));
 386
 387        spin_unlock_irqrestore(&pctl->lock, flags);
 388}
 389
 390static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
 391                            unsigned function,
 392                            unsigned group)
 393{
 394        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 395        struct sunxi_pinctrl_group *g = pctl->groups + group;
 396        struct sunxi_pinctrl_function *func = pctl->functions + function;
 397        struct sunxi_desc_function *desc =
 398                sunxi_pinctrl_desc_find_function_by_name(pctl,
 399                                                         g->name,
 400                                                         func->name);
 401
 402        if (!desc)
 403                return -EINVAL;
 404
 405        sunxi_pmx_set(pctldev, g->pin, desc->muxval);
 406
 407        return 0;
 408}
 409
 410static int
 411sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 412                        struct pinctrl_gpio_range *range,
 413                        unsigned offset,
 414                        bool input)
 415{
 416        struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 417        struct sunxi_desc_function *desc;
 418        const char *func;
 419
 420        if (input)
 421                func = "gpio_in";
 422        else
 423                func = "gpio_out";
 424
 425        desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, func);
 426        if (!desc)
 427                return -EINVAL;
 428
 429        sunxi_pmx_set(pctldev, offset, desc->muxval);
 430
 431        return 0;
 432}
 433
 434static const struct pinmux_ops sunxi_pmx_ops = {
 435        .get_functions_count    = sunxi_pmx_get_funcs_cnt,
 436        .get_function_name      = sunxi_pmx_get_func_name,
 437        .get_function_groups    = sunxi_pmx_get_func_groups,
 438        .enable                 = sunxi_pmx_enable,
 439        .gpio_set_direction     = sunxi_pmx_gpio_set_direction,
 440};
 441
 442static struct pinctrl_desc sunxi_pctrl_desc = {
 443        .confops        = &sunxi_pconf_ops,
 444        .pctlops        = &sunxi_pctrl_ops,
 445        .pmxops         = &sunxi_pmx_ops,
 446};
 447
 448static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
 449{
 450        return pinctrl_request_gpio(chip->base + offset);
 451}
 452
 453static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
 454{
 455        pinctrl_free_gpio(chip->base + offset);
 456}
 457
 458static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
 459                                        unsigned offset)
 460{
 461        return pinctrl_gpio_direction_input(chip->base + offset);
 462}
 463
 464static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
 465{
 466        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 467
 468        u32 reg = sunxi_data_reg(offset);
 469        u8 index = sunxi_data_offset(offset);
 470        u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
 471
 472        return val;
 473}
 474
 475static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
 476                                        unsigned offset, int value)
 477{
 478        return pinctrl_gpio_direction_output(chip->base + offset);
 479}
 480
 481static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
 482                                unsigned offset, int value)
 483{
 484        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 485        u32 reg = sunxi_data_reg(offset);
 486        u8 index = sunxi_data_offset(offset);
 487        unsigned long flags;
 488        u32 regval;
 489
 490        spin_lock_irqsave(&pctl->lock, flags);
 491
 492        regval = readl(pctl->membase + reg);
 493
 494        if (value)
 495                regval |= BIT(index);
 496        else
 497                regval &= ~(BIT(index));
 498
 499        writel(regval, pctl->membase + reg);
 500
 501        spin_unlock_irqrestore(&pctl->lock, flags);
 502}
 503
 504static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
 505                                const struct of_phandle_args *gpiospec,
 506                                u32 *flags)
 507{
 508        int pin, base;
 509
 510        base = PINS_PER_BANK * gpiospec->args[0];
 511        pin = base + gpiospec->args[1];
 512
 513        if (pin > (gc->base + gc->ngpio))
 514                return -EINVAL;
 515
 516        if (flags)
 517                *flags = gpiospec->args[2];
 518
 519        return pin;
 520}
 521
 522static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 523{
 524        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 525        struct sunxi_desc_function *desc;
 526
 527        if (offset > chip->ngpio)
 528                return -ENXIO;
 529
 530        desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
 531        if (!desc)
 532                return -EINVAL;
 533
 534        pctl->irq_array[desc->irqnum] = offset;
 535
 536        dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
 537                chip->label, offset + chip->base, desc->irqnum);
 538
 539        return irq_find_mapping(pctl->domain, desc->irqnum);
 540}
 541
 542static struct gpio_chip sunxi_pinctrl_gpio_chip = {
 543        .owner                  = THIS_MODULE,
 544        .request                = sunxi_pinctrl_gpio_request,
 545        .free                   = sunxi_pinctrl_gpio_free,
 546        .direction_input        = sunxi_pinctrl_gpio_direction_input,
 547        .direction_output       = sunxi_pinctrl_gpio_direction_output,
 548        .get                    = sunxi_pinctrl_gpio_get,
 549        .set                    = sunxi_pinctrl_gpio_set,
 550        .of_xlate               = sunxi_pinctrl_gpio_of_xlate,
 551        .to_irq                 = sunxi_pinctrl_gpio_to_irq,
 552        .of_gpio_n_cells        = 3,
 553        .can_sleep              = 0,
 554};
 555
 556static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
 557                                      unsigned int type)
 558{
 559        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 560        u32 reg = sunxi_irq_cfg_reg(d->hwirq);
 561        u8 index = sunxi_irq_cfg_offset(d->hwirq);
 562        unsigned long flags;
 563        u32 regval;
 564        u8 mode;
 565
 566        switch (type) {
 567        case IRQ_TYPE_EDGE_RISING:
 568                mode = IRQ_EDGE_RISING;
 569                break;
 570        case IRQ_TYPE_EDGE_FALLING:
 571                mode = IRQ_EDGE_FALLING;
 572                break;
 573        case IRQ_TYPE_EDGE_BOTH:
 574                mode = IRQ_EDGE_BOTH;
 575                break;
 576        case IRQ_TYPE_LEVEL_HIGH:
 577                mode = IRQ_LEVEL_HIGH;
 578                break;
 579        case IRQ_TYPE_LEVEL_LOW:
 580                mode = IRQ_LEVEL_LOW;
 581                break;
 582        default:
 583                return -EINVAL;
 584        }
 585
 586        spin_lock_irqsave(&pctl->lock, flags);
 587
 588        regval = readl(pctl->membase + reg);
 589        regval &= ~IRQ_CFG_IRQ_MASK;
 590        writel(regval | (mode << index), pctl->membase + reg);
 591
 592        spin_unlock_irqrestore(&pctl->lock, flags);
 593
 594        return 0;
 595}
 596
 597static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
 598{
 599        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 600        u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
 601        u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
 602        u32 status_reg = sunxi_irq_status_reg(d->hwirq);
 603        u8 status_idx = sunxi_irq_status_offset(d->hwirq);
 604        unsigned long flags;
 605        u32 val;
 606
 607        spin_lock_irqsave(&pctl->lock, flags);
 608
 609        /* Mask the IRQ */
 610        val = readl(pctl->membase + ctrl_reg);
 611        writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
 612
 613        /* Clear the IRQ */
 614        writel(1 << status_idx, pctl->membase + status_reg);
 615
 616        spin_unlock_irqrestore(&pctl->lock, flags);
 617}
 618
 619static void sunxi_pinctrl_irq_mask(struct irq_data *d)
 620{
 621        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 622        u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
 623        u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
 624        unsigned long flags;
 625        u32 val;
 626
 627        spin_lock_irqsave(&pctl->lock, flags);
 628
 629        /* Mask the IRQ */
 630        val = readl(pctl->membase + reg);
 631        writel(val & ~(1 << idx), pctl->membase + reg);
 632
 633        spin_unlock_irqrestore(&pctl->lock, flags);
 634}
 635
 636static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
 637{
 638        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 639        struct sunxi_desc_function *func;
 640        u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
 641        u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
 642        unsigned long flags;
 643        u32 val;
 644
 645        func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
 646                                                       pctl->irq_array[d->hwirq],
 647                                                       "irq");
 648
 649        /* Change muxing to INT mode */
 650        sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
 651
 652        spin_lock_irqsave(&pctl->lock, flags);
 653
 654        /* Unmask the IRQ */
 655        val = readl(pctl->membase + reg);
 656        writel(val | (1 << idx), pctl->membase + reg);
 657
 658        spin_unlock_irqrestore(&pctl->lock, flags);
 659}
 660
 661static struct irq_chip sunxi_pinctrl_irq_chip = {
 662        .irq_mask       = sunxi_pinctrl_irq_mask,
 663        .irq_mask_ack   = sunxi_pinctrl_irq_mask_ack,
 664        .irq_unmask     = sunxi_pinctrl_irq_unmask,
 665        .irq_set_type   = sunxi_pinctrl_irq_set_type,
 666};
 667
 668static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
 669{
 670        struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
 671        const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
 672
 673        /* Clear all interrupts */
 674        writel(reg, pctl->membase + IRQ_STATUS_REG);
 675
 676        if (reg) {
 677                int irqoffset;
 678
 679                for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) {
 680                        int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
 681                        generic_handle_irq(pin_irq);
 682                }
 683        }
 684}
 685
 686static struct of_device_id sunxi_pinctrl_match[] = {
 687        { .compatible = "allwinner,sun4i-a10-pinctrl", .data = (void *)&sun4i_a10_pinctrl_data },
 688        { .compatible = "allwinner,sun5i-a10s-pinctrl", .data = (void *)&sun5i_a10s_pinctrl_data },
 689        { .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
 690        {}
 691};
 692MODULE_DEVICE_TABLE(of, sunxi_pinctrl_match);
 693
 694static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
 695                                        const char *name)
 696{
 697        struct sunxi_pinctrl_function *func = pctl->functions;
 698
 699        while (func->name) {
 700                /* function already there */
 701                if (strcmp(func->name, name) == 0) {
 702                        func->ngroups++;
 703                        return -EEXIST;
 704                }
 705                func++;
 706        }
 707
 708        func->name = name;
 709        func->ngroups = 1;
 710
 711        pctl->nfunctions++;
 712
 713        return 0;
 714}
 715
 716static int sunxi_pinctrl_build_state(struct platform_device *pdev)
 717{
 718        struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
 719        int i;
 720
 721        pctl->ngroups = pctl->desc->npins;
 722
 723        /* Allocate groups */
 724        pctl->groups = devm_kzalloc(&pdev->dev,
 725                                    pctl->ngroups * sizeof(*pctl->groups),
 726                                    GFP_KERNEL);
 727        if (!pctl->groups)
 728                return -ENOMEM;
 729
 730        for (i = 0; i < pctl->desc->npins; i++) {
 731                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 732                struct sunxi_pinctrl_group *group = pctl->groups + i;
 733
 734                group->name = pin->pin.name;
 735                group->pin = pin->pin.number;
 736        }
 737
 738        /*
 739         * We suppose that we won't have any more functions than pins,
 740         * we'll reallocate that later anyway
 741         */
 742        pctl->functions = devm_kzalloc(&pdev->dev,
 743                                pctl->desc->npins * sizeof(*pctl->functions),
 744                                GFP_KERNEL);
 745        if (!pctl->functions)
 746                return -ENOMEM;
 747
 748        /* Count functions and their associated groups */
 749        for (i = 0; i < pctl->desc->npins; i++) {
 750                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 751                struct sunxi_desc_function *func = pin->functions;
 752
 753                while (func->name) {
 754                        sunxi_pinctrl_add_function(pctl, func->name);
 755                        func++;
 756                }
 757        }
 758
 759        pctl->functions = krealloc(pctl->functions,
 760                                pctl->nfunctions * sizeof(*pctl->functions),
 761                                GFP_KERNEL);
 762
 763        for (i = 0; i < pctl->desc->npins; i++) {
 764                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 765                struct sunxi_desc_function *func = pin->functions;
 766
 767                while (func->name) {
 768                        struct sunxi_pinctrl_function *func_item;
 769                        const char **func_grp;
 770
 771                        func_item = sunxi_pinctrl_find_function_by_name(pctl,
 772                                                                        func->name);
 773                        if (!func_item)
 774                                return -EINVAL;
 775
 776                        if (!func_item->groups) {
 777                                func_item->groups =
 778                                        devm_kzalloc(&pdev->dev,
 779                                                     func_item->ngroups * sizeof(*func_item->groups),
 780                                                     GFP_KERNEL);
 781                                if (!func_item->groups)
 782                                        return -ENOMEM;
 783                        }
 784
 785                        func_grp = func_item->groups;
 786                        while (*func_grp)
 787                                func_grp++;
 788
 789                        *func_grp = pin->pin.name;
 790                        func++;
 791                }
 792        }
 793
 794        return 0;
 795}
 796
 797static int sunxi_pinctrl_probe(struct platform_device *pdev)
 798{
 799        struct device_node *node = pdev->dev.of_node;
 800        const struct of_device_id *device;
 801        struct pinctrl_pin_desc *pins;
 802        struct sunxi_pinctrl *pctl;
 803        int i, ret, last_pin;
 804        struct clk *clk;
 805
 806        pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
 807        if (!pctl)
 808                return -ENOMEM;
 809        platform_set_drvdata(pdev, pctl);
 810
 811        spin_lock_init(&pctl->lock);
 812
 813        pctl->membase = of_iomap(node, 0);
 814        if (!pctl->membase)
 815                return -ENOMEM;
 816
 817        device = of_match_device(sunxi_pinctrl_match, &pdev->dev);
 818        if (!device)
 819                return -ENODEV;
 820
 821        pctl->desc = (struct sunxi_pinctrl_desc *)device->data;
 822
 823        ret = sunxi_pinctrl_build_state(pdev);
 824        if (ret) {
 825                dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
 826                return ret;
 827        }
 828
 829        pins = devm_kzalloc(&pdev->dev,
 830                            pctl->desc->npins * sizeof(*pins),
 831                            GFP_KERNEL);
 832        if (!pins)
 833                return -ENOMEM;
 834
 835        for (i = 0; i < pctl->desc->npins; i++)
 836                pins[i] = pctl->desc->pins[i].pin;
 837
 838        sunxi_pctrl_desc.name = dev_name(&pdev->dev);
 839        sunxi_pctrl_desc.owner = THIS_MODULE;
 840        sunxi_pctrl_desc.pins = pins;
 841        sunxi_pctrl_desc.npins = pctl->desc->npins;
 842        pctl->dev = &pdev->dev;
 843        pctl->pctl_dev = pinctrl_register(&sunxi_pctrl_desc,
 844                                          &pdev->dev, pctl);
 845        if (!pctl->pctl_dev) {
 846                dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 847                return -EINVAL;
 848        }
 849
 850        pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
 851        if (!pctl->chip) {
 852                ret = -ENOMEM;
 853                goto pinctrl_error;
 854        }
 855
 856        last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
 857        pctl->chip = &sunxi_pinctrl_gpio_chip;
 858        pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
 859        pctl->chip->label = dev_name(&pdev->dev);
 860        pctl->chip->dev = &pdev->dev;
 861        pctl->chip->base = 0;
 862
 863        ret = gpiochip_add(pctl->chip);
 864        if (ret)
 865                goto pinctrl_error;
 866
 867        for (i = 0; i < pctl->desc->npins; i++) {
 868                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 869
 870                ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
 871                                             pin->pin.number,
 872                                             pin->pin.number, 1);
 873                if (ret)
 874                        goto gpiochip_error;
 875        }
 876
 877        clk = devm_clk_get(&pdev->dev, NULL);
 878        if (IS_ERR(clk)) {
 879                ret = PTR_ERR(clk);
 880                goto gpiochip_error;
 881        }
 882
 883        clk_prepare_enable(clk);
 884
 885        pctl->irq = irq_of_parse_and_map(node, 0);
 886        if (!pctl->irq) {
 887                ret = -EINVAL;
 888                goto gpiochip_error;
 889        }
 890
 891        pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
 892                                             &irq_domain_simple_ops, NULL);
 893        if (!pctl->domain) {
 894                dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
 895                ret = -ENOMEM;
 896                goto gpiochip_error;
 897        }
 898
 899        for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
 900                int irqno = irq_create_mapping(pctl->domain, i);
 901
 902                irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
 903                                         handle_simple_irq);
 904                irq_set_chip_data(irqno, pctl);
 905        };
 906
 907        irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
 908        irq_set_handler_data(pctl->irq, pctl);
 909
 910        dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
 911
 912        return 0;
 913
 914gpiochip_error:
 915        if (gpiochip_remove(pctl->chip))
 916                dev_err(&pdev->dev, "failed to remove gpio chip\n");
 917pinctrl_error:
 918        pinctrl_unregister(pctl->pctl_dev);
 919        return ret;
 920}
 921
 922static struct platform_driver sunxi_pinctrl_driver = {
 923        .probe = sunxi_pinctrl_probe,
 924        .driver = {
 925                .name = "sunxi-pinctrl",
 926                .owner = THIS_MODULE,
 927                .of_match_table = sunxi_pinctrl_match,
 928        },
 929};
 930module_platform_driver(sunxi_pinctrl_driver);
 931
 932MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
 933MODULE_DESCRIPTION("Allwinner A1X pinctrl driver");
 934MODULE_LICENSE("GPL");
 935
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.