linux/drivers/pinctrl/meson/pinctrl-meson.c
<<
>>
Prefs
   1/*
   2 * Pin controller and GPIO driver for Amlogic Meson SoCs
   3 *
   4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * version 2 as published by the Free Software Foundation.
   9 *
  10 * You should have received a copy of the GNU General Public License
  11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
  12 */
  13
  14/*
  15 * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO,
  16 * BOOT,CARD for meson6, X,Y,DV,H,Z,AO,BOOT,CARD for meson8 and
  17 * X,Y,DV,H,AO,BOOT,CARD,DIF for meson8b) and each bank has a
  18 * variable number of pins.
  19 *
  20 * The AO bank is special because it belongs to the Always-On power
  21 * domain which can't be powered off; the bank also uses a set of
  22 * registers different from the other banks.
  23 *
  24 * For each pin controller there are 4 different register ranges that
  25 * control the following properties of the pins:
  26 *  1) pin muxing
  27 *  2) pull enable/disable
  28 *  3) pull up/down
  29 *  4) GPIO direction, output value, input value
  30 *
  31 * In some cases the register ranges for pull enable and pull
  32 * direction are the same and thus there are only 3 register ranges.
  33 *
  34 * For the pull and GPIO configuration every bank uses a contiguous
  35 * set of bits in the register sets described above; the same register
  36 * can be shared by more banks with different offsets.
  37 *
  38 * In addition to this there are some registers shared between all
  39 * banks that control the IRQ functionality. This feature is not
  40 * supported at the moment by the driver.
  41 */
  42
  43#include <linux/device.h>
  44#include <linux/gpio.h>
  45#include <linux/init.h>
  46#include <linux/io.h>
  47#include <linux/of.h>
  48#include <linux/of_address.h>
  49#include <linux/of_device.h>
  50#include <linux/pinctrl/pinconf-generic.h>
  51#include <linux/pinctrl/pinconf.h>
  52#include <linux/pinctrl/pinctrl.h>
  53#include <linux/pinctrl/pinmux.h>
  54#include <linux/platform_device.h>
  55#include <linux/regmap.h>
  56#include <linux/seq_file.h>
  57
  58#include "../core.h"
  59#include "../pinctrl-utils.h"
  60#include "pinctrl-meson.h"
  61
  62/**
  63 * meson_get_bank() - find the bank containing a given pin
  64 *
  65 * @pc:         the pinctrl instance
  66 * @pin:        the pin number
  67 * @bank:       the found bank
  68 *
  69 * Return:      0 on success, a negative value on error
  70 */
  71static int meson_get_bank(struct meson_pinctrl *pc, unsigned int pin,
  72                          struct meson_bank **bank)
  73{
  74        int i;
  75
  76        for (i = 0; i < pc->data->num_banks; i++) {
  77                if (pin >= pc->data->banks[i].first &&
  78                    pin <= pc->data->banks[i].last) {
  79                        *bank = &pc->data->banks[i];
  80                        return 0;
  81                }
  82        }
  83
  84        return -EINVAL;
  85}
  86
  87/**
  88 * meson_calc_reg_and_bit() - calculate register and bit for a pin
  89 *
  90 * @bank:       the bank containing the pin
  91 * @pin:        the pin number
  92 * @reg_type:   the type of register needed (pull-enable, pull, etc...)
  93 * @reg:        the computed register offset
  94 * @bit:        the computed bit
  95 */
  96static void meson_calc_reg_and_bit(struct meson_bank *bank, unsigned int pin,
  97                                   enum meson_reg_type reg_type,
  98                                   unsigned int *reg, unsigned int *bit)
  99{
 100        struct meson_reg_desc *desc = &bank->regs[reg_type];
 101
 102        *reg = desc->reg * 4;
 103        *bit = desc->bit + pin - bank->first;
 104}
 105
 106static int meson_get_groups_count(struct pinctrl_dev *pcdev)
 107{
 108        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 109
 110        return pc->data->num_groups;
 111}
 112
 113static const char *meson_get_group_name(struct pinctrl_dev *pcdev,
 114                                        unsigned selector)
 115{
 116        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 117
 118        return pc->data->groups[selector].name;
 119}
 120
 121static int meson_get_group_pins(struct pinctrl_dev *pcdev, unsigned selector,
 122                                const unsigned **pins, unsigned *num_pins)
 123{
 124        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 125
 126        *pins = pc->data->groups[selector].pins;
 127        *num_pins = pc->data->groups[selector].num_pins;
 128
 129        return 0;
 130}
 131
 132static void meson_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s,
 133                               unsigned offset)
 134{
 135        seq_printf(s, " %s", dev_name(pcdev->dev));
 136}
 137
 138static const struct pinctrl_ops meson_pctrl_ops = {
 139        .get_groups_count       = meson_get_groups_count,
 140        .get_group_name         = meson_get_group_name,
 141        .get_group_pins         = meson_get_group_pins,
 142        .dt_node_to_map         = pinconf_generic_dt_node_to_map_all,
 143        .dt_free_map            = pinctrl_utils_free_map,
 144        .pin_dbg_show           = meson_pin_dbg_show,
 145};
 146
 147int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
 148{
 149        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 150
 151        return pc->data->num_funcs;
 152}
 153
 154const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
 155                                    unsigned selector)
 156{
 157        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 158
 159        return pc->data->funcs[selector].name;
 160}
 161
 162int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
 163                         const char * const **groups,
 164                         unsigned * const num_groups)
 165{
 166        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 167
 168        *groups = pc->data->funcs[selector].groups;
 169        *num_groups = pc->data->funcs[selector].num_groups;
 170
 171        return 0;
 172}
 173
 174static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
 175                             unsigned long *configs, unsigned num_configs)
 176{
 177        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 178        struct meson_bank *bank;
 179        enum pin_config_param param;
 180        unsigned int reg, bit;
 181        int i, ret;
 182
 183        ret = meson_get_bank(pc, pin, &bank);
 184        if (ret)
 185                return ret;
 186
 187        for (i = 0; i < num_configs; i++) {
 188                param = pinconf_to_config_param(configs[i]);
 189
 190                switch (param) {
 191                case PIN_CONFIG_BIAS_DISABLE:
 192                        dev_dbg(pc->dev, "pin %u: disable bias\n", pin);
 193
 194                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 195                        ret = regmap_update_bits(pc->reg_pull, reg,
 196                                                 BIT(bit), 0);
 197                        if (ret)
 198                                return ret;
 199                        break;
 200                case PIN_CONFIG_BIAS_PULL_UP:
 201                        dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin);
 202
 203                        meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
 204                                               &reg, &bit);
 205                        ret = regmap_update_bits(pc->reg_pullen, reg,
 206                                                 BIT(bit), BIT(bit));
 207                        if (ret)
 208                                return ret;
 209
 210                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 211                        ret = regmap_update_bits(pc->reg_pull, reg,
 212                                                 BIT(bit), BIT(bit));
 213                        if (ret)
 214                                return ret;
 215                        break;
 216                case PIN_CONFIG_BIAS_PULL_DOWN:
 217                        dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin);
 218
 219                        meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
 220                                               &reg, &bit);
 221                        ret = regmap_update_bits(pc->reg_pullen, reg,
 222                                                 BIT(bit), BIT(bit));
 223                        if (ret)
 224                                return ret;
 225
 226                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 227                        ret = regmap_update_bits(pc->reg_pull, reg,
 228                                                 BIT(bit), 0);
 229                        if (ret)
 230                                return ret;
 231                        break;
 232                default:
 233                        return -ENOTSUPP;
 234                }
 235        }
 236
 237        return 0;
 238}
 239
 240static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
 241{
 242        struct meson_bank *bank;
 243        unsigned int reg, bit, val;
 244        int ret, conf;
 245
 246        ret = meson_get_bank(pc, pin, &bank);
 247        if (ret)
 248                return ret;
 249
 250        meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
 251
 252        ret = regmap_read(pc->reg_pullen, reg, &val);
 253        if (ret)
 254                return ret;
 255
 256        if (!(val & BIT(bit))) {
 257                conf = PIN_CONFIG_BIAS_DISABLE;
 258        } else {
 259                meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
 260
 261                ret = regmap_read(pc->reg_pull, reg, &val);
 262                if (ret)
 263                        return ret;
 264
 265                if (val & BIT(bit))
 266                        conf = PIN_CONFIG_BIAS_PULL_UP;
 267                else
 268                        conf = PIN_CONFIG_BIAS_PULL_DOWN;
 269        }
 270
 271        return conf;
 272}
 273
 274static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
 275                             unsigned long *config)
 276{
 277        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 278        enum pin_config_param param = pinconf_to_config_param(*config);
 279        u16 arg;
 280
 281        switch (param) {
 282        case PIN_CONFIG_BIAS_DISABLE:
 283        case PIN_CONFIG_BIAS_PULL_DOWN:
 284        case PIN_CONFIG_BIAS_PULL_UP:
 285                if (meson_pinconf_get_pull(pc, pin) == param)
 286                        arg = 1;
 287                else
 288                        return -EINVAL;
 289                break;
 290        default:
 291                return -ENOTSUPP;
 292        }
 293
 294        *config = pinconf_to_config_packed(param, arg);
 295        dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);
 296
 297        return 0;
 298}
 299
 300static int meson_pinconf_group_set(struct pinctrl_dev *pcdev,
 301                                   unsigned int num_group,
 302                                   unsigned long *configs, unsigned num_configs)
 303{
 304        struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
 305        struct meson_pmx_group *group = &pc->data->groups[num_group];
 306        int i;
 307
 308        dev_dbg(pc->dev, "set pinconf for group %s\n", group->name);
 309
 310        for (i = 0; i < group->num_pins; i++) {
 311                meson_pinconf_set(pcdev, group->pins[i], configs,
 312                                  num_configs);
 313        }
 314
 315        return 0;
 316}
 317
 318static int meson_pinconf_group_get(struct pinctrl_dev *pcdev,
 319                                   unsigned int group, unsigned long *config)
 320{
 321        return -ENOTSUPP;
 322}
 323
 324static const struct pinconf_ops meson_pinconf_ops = {
 325        .pin_config_get         = meson_pinconf_get,
 326        .pin_config_set         = meson_pinconf_set,
 327        .pin_config_group_get   = meson_pinconf_group_get,
 328        .pin_config_group_set   = meson_pinconf_group_set,
 329        .is_generic             = true,
 330};
 331
 332static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 333{
 334        struct meson_pinctrl *pc = gpiochip_get_data(chip);
 335        unsigned int reg, bit;
 336        struct meson_bank *bank;
 337        int ret;
 338
 339        ret = meson_get_bank(pc, gpio, &bank);
 340        if (ret)
 341                return ret;
 342
 343        meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
 344
 345        return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), BIT(bit));
 346}
 347
 348static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
 349                                       int value)
 350{
 351        struct meson_pinctrl *pc = gpiochip_get_data(chip);
 352        unsigned int reg, bit;
 353        struct meson_bank *bank;
 354        int ret;
 355
 356        ret = meson_get_bank(pc, gpio, &bank);
 357        if (ret)
 358                return ret;
 359
 360        meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
 361        ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0);
 362        if (ret)
 363                return ret;
 364
 365        meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
 366        return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
 367                                  value ? BIT(bit) : 0);
 368}
 369
 370static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
 371{
 372        struct meson_pinctrl *pc = gpiochip_get_data(chip);
 373        unsigned int reg, bit;
 374        struct meson_bank *bank;
 375        int ret;
 376
 377        ret = meson_get_bank(pc, gpio, &bank);
 378        if (ret)
 379                return;
 380
 381        meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
 382        regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
 383                           value ? BIT(bit) : 0);
 384}
 385
 386static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
 387{
 388        struct meson_pinctrl *pc = gpiochip_get_data(chip);
 389        unsigned int reg, bit, val;
 390        struct meson_bank *bank;
 391        int ret;
 392
 393        ret = meson_get_bank(pc, gpio, &bank);
 394        if (ret)
 395                return ret;
 396
 397        meson_calc_reg_and_bit(bank, gpio, REG_IN, &reg, &bit);
 398        regmap_read(pc->reg_gpio, reg, &val);
 399
 400        return !!(val & BIT(bit));
 401}
 402
 403static int meson_gpiolib_register(struct meson_pinctrl *pc)
 404{
 405        int ret;
 406
 407        pc->chip.label = pc->data->name;
 408        pc->chip.parent = pc->dev;
 409        pc->chip.request = gpiochip_generic_request;
 410        pc->chip.free = gpiochip_generic_free;
 411        pc->chip.direction_input = meson_gpio_direction_input;
 412        pc->chip.direction_output = meson_gpio_direction_output;
 413        pc->chip.get = meson_gpio_get;
 414        pc->chip.set = meson_gpio_set;
 415        pc->chip.base = -1;
 416        pc->chip.ngpio = pc->data->num_pins;
 417        pc->chip.can_sleep = false;
 418        pc->chip.of_node = pc->of_node;
 419        pc->chip.of_gpio_n_cells = 2;
 420
 421        ret = gpiochip_add_data(&pc->chip, pc);
 422        if (ret) {
 423                dev_err(pc->dev, "can't add gpio chip %s\n",
 424                        pc->data->name);
 425                return ret;
 426        }
 427
 428        return 0;
 429}
 430
 431static struct regmap_config meson_regmap_config = {
 432        .reg_bits = 32,
 433        .val_bits = 32,
 434        .reg_stride = 4,
 435};
 436
 437static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
 438                                         struct device_node *node, char *name)
 439{
 440        struct resource res;
 441        void __iomem *base;
 442        int i;
 443
 444        i = of_property_match_string(node, "reg-names", name);
 445        if (of_address_to_resource(node, i, &res))
 446                return ERR_PTR(-ENOENT);
 447
 448        base = devm_ioremap_resource(pc->dev, &res);
 449        if (IS_ERR(base))
 450                return ERR_CAST(base);
 451
 452        meson_regmap_config.max_register = resource_size(&res) - 4;
 453        meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
 454                                                  "%s-%s", node->name,
 455                                                  name);
 456        if (!meson_regmap_config.name)
 457                return ERR_PTR(-ENOMEM);
 458
 459        return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
 460}
 461
 462static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
 463                                  struct device_node *node)
 464{
 465        struct device_node *np, *gpio_np = NULL;
 466
 467        for_each_child_of_node(node, np) {
 468                if (!of_find_property(np, "gpio-controller", NULL))
 469                        continue;
 470                if (gpio_np) {
 471                        dev_err(pc->dev, "multiple gpio nodes\n");
 472                        return -EINVAL;
 473                }
 474                gpio_np = np;
 475        }
 476
 477        if (!gpio_np) {
 478                dev_err(pc->dev, "no gpio node found\n");
 479                return -EINVAL;
 480        }
 481
 482        pc->of_node = gpio_np;
 483
 484        pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
 485        if (IS_ERR(pc->reg_mux)) {
 486                dev_err(pc->dev, "mux registers not found\n");
 487                return PTR_ERR(pc->reg_mux);
 488        }
 489
 490        pc->reg_pull = meson_map_resource(pc, gpio_np, "pull");
 491        if (IS_ERR(pc->reg_pull)) {
 492                dev_err(pc->dev, "pull registers not found\n");
 493                return PTR_ERR(pc->reg_pull);
 494        }
 495
 496        pc->reg_pullen = meson_map_resource(pc, gpio_np, "pull-enable");
 497        /* Use pull region if pull-enable one is not present */
 498        if (IS_ERR(pc->reg_pullen))
 499                pc->reg_pullen = pc->reg_pull;
 500
 501        pc->reg_gpio = meson_map_resource(pc, gpio_np, "gpio");
 502        if (IS_ERR(pc->reg_gpio)) {
 503                dev_err(pc->dev, "gpio registers not found\n");
 504                return PTR_ERR(pc->reg_gpio);
 505        }
 506
 507        return 0;
 508}
 509
 510int meson_pinctrl_probe(struct platform_device *pdev)
 511{
 512        struct device *dev = &pdev->dev;
 513        struct meson_pinctrl *pc;
 514        int ret;
 515
 516        pc = devm_kzalloc(dev, sizeof(struct meson_pinctrl), GFP_KERNEL);
 517        if (!pc)
 518                return -ENOMEM;
 519
 520        pc->dev = dev;
 521        pc->data = (struct meson_pinctrl_data *) of_device_get_match_data(dev);
 522
 523        ret = meson_pinctrl_parse_dt(pc, dev->of_node);
 524        if (ret)
 525                return ret;
 526
 527        pc->desc.name           = "pinctrl-meson";
 528        pc->desc.owner          = THIS_MODULE;
 529        pc->desc.pctlops        = &meson_pctrl_ops;
 530        pc->desc.pmxops         = pc->data->pmx_ops;
 531        pc->desc.confops        = &meson_pinconf_ops;
 532        pc->desc.pins           = pc->data->pins;
 533        pc->desc.npins          = pc->data->num_pins;
 534
 535        pc->pcdev = devm_pinctrl_register(pc->dev, &pc->desc, pc);
 536        if (IS_ERR(pc->pcdev)) {
 537                dev_err(pc->dev, "can't register pinctrl device");
 538                return PTR_ERR(pc->pcdev);
 539        }
 540
 541        return meson_gpiolib_register(pc);
 542}
 543