linux/drivers/pinctrl/pinctrl-digicolor.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Driver for Conexant Digicolor General Purpose Pin Mapping
   4 *
   5 * Author: Baruch Siach <baruch@tkos.co.il>
   6 *
   7 * Copyright (C) 2015 Paradox Innovation Ltd.
   8 *
   9 * TODO:
  10 * - GPIO interrupt support
  11 * - Pin pad configuration (pull up/down, strength)
  12 */
  13
  14#include <linux/init.h>
  15#include <linux/platform_device.h>
  16#include <linux/of.h>
  17#include <linux/of_device.h>
  18#include <linux/io.h>
  19#include <linux/gpio/driver.h>
  20#include <linux/spinlock.h>
  21#include <linux/pinctrl/machine.h>
  22#include <linux/pinctrl/pinconf.h>
  23#include <linux/pinctrl/pinconf-generic.h>
  24#include <linux/pinctrl/pinctrl.h>
  25#include <linux/pinctrl/pinmux.h>
  26#include "pinctrl-utils.h"
  27
  28#define DRIVER_NAME     "pinctrl-digicolor"
  29
  30#define GP_CLIENTSEL(clct)      ((clct)*8 + 0x20)
  31#define GP_DRIVE0(clct)         (GP_CLIENTSEL(clct) + 2)
  32#define GP_OUTPUT0(clct)        (GP_CLIENTSEL(clct) + 3)
  33#define GP_INPUT(clct)          (GP_CLIENTSEL(clct) + 6)
  34
  35#define PIN_COLLECTIONS         ('R' - 'A' + 1)
  36#define PINS_PER_COLLECTION     8
  37#define PINS_COUNT              (PIN_COLLECTIONS * PINS_PER_COLLECTION)
  38
  39struct dc_pinmap {
  40        void __iomem            *regs;
  41        struct device           *dev;
  42        struct pinctrl_dev      *pctl;
  43
  44        struct pinctrl_desc     *desc;
  45        const char              *pin_names[PINS_COUNT];
  46
  47        struct gpio_chip        chip;
  48        spinlock_t              lock;
  49};
  50
  51static int dc_get_groups_count(struct pinctrl_dev *pctldev)
  52{
  53        return PINS_COUNT;
  54}
  55
  56static const char *dc_get_group_name(struct pinctrl_dev *pctldev,
  57                                     unsigned selector)
  58{
  59        struct dc_pinmap *pmap = pinctrl_dev_get_drvdata(pctldev);
  60
  61        /* Exactly one group per pin */
  62        return pmap->desc->pins[selector].name;
  63}
  64
  65static int dc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
  66                             const unsigned **pins,
  67                             unsigned *num_pins)
  68{
  69        struct dc_pinmap *pmap = pinctrl_dev_get_drvdata(pctldev);
  70
  71        *pins = &pmap->desc->pins[selector].number;
  72        *num_pins = 1;
  73
  74        return 0;
  75}
  76
  77static const struct pinctrl_ops dc_pinctrl_ops = {
  78        .get_groups_count       = dc_get_groups_count,
  79        .get_group_name         = dc_get_group_name,
  80        .get_group_pins         = dc_get_group_pins,
  81        .dt_node_to_map         = pinconf_generic_dt_node_to_map_pin,
  82        .dt_free_map            = pinctrl_utils_free_map,
  83};
  84
  85static const char *const dc_functions[] = {
  86        "gpio",
  87        "client_a",
  88        "client_b",
  89        "client_c",
  90};
  91
  92static int dc_get_functions_count(struct pinctrl_dev *pctldev)
  93{
  94        return ARRAY_SIZE(dc_functions);
  95}
  96
  97static const char *dc_get_fname(struct pinctrl_dev *pctldev, unsigned selector)
  98{
  99        return dc_functions[selector];
 100}
 101
 102static int dc_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
 103                         const char * const **groups,
 104                         unsigned * const num_groups)
 105{
 106        struct dc_pinmap *pmap = pinctrl_dev_get_drvdata(pctldev);
 107
 108        *groups = pmap->pin_names;
 109        *num_groups = PINS_COUNT;
 110
 111        return 0;
 112}
 113
 114static void dc_client_sel(int pin_num, int *reg, int *bit)
 115{
 116        *bit = (pin_num % PINS_PER_COLLECTION) * 2;
 117        *reg = GP_CLIENTSEL(pin_num/PINS_PER_COLLECTION);
 118
 119        if (*bit >= PINS_PER_COLLECTION) {
 120                *bit -= PINS_PER_COLLECTION;
 121                *reg += 1;
 122        }
 123}
 124
 125static int dc_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
 126                      unsigned group)
 127{
 128        struct dc_pinmap *pmap = pinctrl_dev_get_drvdata(pctldev);
 129        int bit_off, reg_off;
 130        u8 reg;
 131
 132        dc_client_sel(group, &reg_off, &bit_off);
 133
 134        reg = readb_relaxed(pmap->regs + reg_off);
 135        reg &= ~(3 << bit_off);
 136        reg |= (selector << bit_off);
 137        writeb_relaxed(reg, pmap->regs + reg_off);
 138
 139        return 0;
 140}
 141
 142static int dc_pmx_request_gpio(struct pinctrl_dev *pcdev,
 143                               struct pinctrl_gpio_range *range,
 144                               unsigned offset)
 145{
 146        struct dc_pinmap *pmap = pinctrl_dev_get_drvdata(pcdev);
 147        int bit_off, reg_off;
 148        u8 reg;
 149
 150        dc_client_sel(offset, &reg_off, &bit_off);
 151
 152        reg = readb_relaxed(pmap->regs + reg_off);
 153        if ((reg & (3 << bit_off)) != 0)
 154                return -EBUSY;
 155
 156        return 0;
 157}
 158
 159static const struct pinmux_ops dc_pmxops = {
 160        .get_functions_count    = dc_get_functions_count,
 161        .get_function_name      = dc_get_fname,
 162        .get_function_groups    = dc_get_groups,
 163        .set_mux                = dc_set_mux,
 164        .gpio_request_enable    = dc_pmx_request_gpio,
 165};
 166
 167static int dc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 168{
 169        struct dc_pinmap *pmap = gpiochip_get_data(chip);
 170        int reg_off = GP_DRIVE0(gpio/PINS_PER_COLLECTION);
 171        int bit_off = gpio % PINS_PER_COLLECTION;
 172        u8 drive;
 173        unsigned long flags;
 174
 175        spin_lock_irqsave(&pmap->lock, flags);
 176        drive = readb_relaxed(pmap->regs + reg_off);
 177        drive &= ~BIT(bit_off);
 178        writeb_relaxed(drive, pmap->regs + reg_off);
 179        spin_unlock_irqrestore(&pmap->lock, flags);
 180
 181        return 0;
 182}
 183
 184static void dc_gpio_set(struct gpio_chip *chip, unsigned gpio, int value);
 185
 186static int dc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
 187                                    int value)
 188{
 189        struct dc_pinmap *pmap = gpiochip_get_data(chip);
 190        int reg_off = GP_DRIVE0(gpio/PINS_PER_COLLECTION);
 191        int bit_off = gpio % PINS_PER_COLLECTION;
 192        u8 drive;
 193        unsigned long flags;
 194
 195        dc_gpio_set(chip, gpio, value);
 196
 197        spin_lock_irqsave(&pmap->lock, flags);
 198        drive = readb_relaxed(pmap->regs + reg_off);
 199        drive |= BIT(bit_off);
 200        writeb_relaxed(drive, pmap->regs + reg_off);
 201        spin_unlock_irqrestore(&pmap->lock, flags);
 202
 203        return 0;
 204}
 205
 206static int dc_gpio_get(struct gpio_chip *chip, unsigned gpio)
 207{
 208        struct dc_pinmap *pmap = gpiochip_get_data(chip);
 209        int reg_off = GP_INPUT(gpio/PINS_PER_COLLECTION);
 210        int bit_off = gpio % PINS_PER_COLLECTION;
 211        u8 input;
 212
 213        input = readb_relaxed(pmap->regs + reg_off);
 214
 215        return !!(input & BIT(bit_off));
 216}
 217
 218static void dc_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
 219{
 220        struct dc_pinmap *pmap = gpiochip_get_data(chip);
 221        int reg_off = GP_OUTPUT0(gpio/PINS_PER_COLLECTION);
 222        int bit_off = gpio % PINS_PER_COLLECTION;
 223        u8 output;
 224        unsigned long flags;
 225
 226        spin_lock_irqsave(&pmap->lock, flags);
 227        output = readb_relaxed(pmap->regs + reg_off);
 228        if (value)
 229                output |= BIT(bit_off);
 230        else
 231                output &= ~BIT(bit_off);
 232        writeb_relaxed(output, pmap->regs + reg_off);
 233        spin_unlock_irqrestore(&pmap->lock, flags);
 234}
 235
 236static int dc_gpiochip_add(struct dc_pinmap *pmap, struct device_node *np)
 237{
 238        struct gpio_chip *chip = &pmap->chip;
 239        int ret;
 240
 241        chip->label             = DRIVER_NAME;
 242        chip->parent            = pmap->dev;
 243        chip->request           = gpiochip_generic_request;
 244        chip->free              = gpiochip_generic_free;
 245        chip->direction_input   = dc_gpio_direction_input;
 246        chip->direction_output  = dc_gpio_direction_output;
 247        chip->get               = dc_gpio_get;
 248        chip->set               = dc_gpio_set;
 249        chip->base              = -1;
 250        chip->ngpio             = PINS_COUNT;
 251        chip->of_node           = np;
 252        chip->of_gpio_n_cells   = 2;
 253
 254        spin_lock_init(&pmap->lock);
 255
 256        ret = gpiochip_add_data(chip, pmap);
 257        if (ret < 0)
 258                return ret;
 259
 260        ret = gpiochip_add_pin_range(chip, dev_name(pmap->dev), 0, 0,
 261                                     PINS_COUNT);
 262        if (ret < 0) {
 263                gpiochip_remove(chip);
 264                return ret;
 265        }
 266
 267        return 0;
 268}
 269
 270static int dc_pinctrl_probe(struct platform_device *pdev)
 271{
 272        struct dc_pinmap *pmap;
 273        struct pinctrl_pin_desc *pins;
 274        struct pinctrl_desc *pctl_desc;
 275        char *pin_names;
 276        int name_len = strlen("GP_xx") + 1;
 277        int i, j;
 278
 279        pmap = devm_kzalloc(&pdev->dev, sizeof(*pmap), GFP_KERNEL);
 280        if (!pmap)
 281                return -ENOMEM;
 282
 283        pmap->regs = devm_platform_ioremap_resource(pdev, 0);
 284        if (IS_ERR(pmap->regs))
 285                return PTR_ERR(pmap->regs);
 286
 287        pins = devm_kcalloc(&pdev->dev, PINS_COUNT, sizeof(*pins),
 288                            GFP_KERNEL);
 289        if (!pins)
 290                return -ENOMEM;
 291        pin_names = devm_kcalloc(&pdev->dev, PINS_COUNT, name_len,
 292                                 GFP_KERNEL);
 293        if (!pin_names)
 294                return -ENOMEM;
 295
 296        for (i = 0; i < PIN_COLLECTIONS; i++) {
 297                for (j = 0; j < PINS_PER_COLLECTION; j++) {
 298                        int pin_id = i*PINS_PER_COLLECTION + j;
 299                        char *name = &pin_names[pin_id * name_len];
 300
 301                        snprintf(name, name_len, "GP_%c%c", 'A'+i, '0'+j);
 302
 303                        pins[pin_id].number = pin_id;
 304                        pins[pin_id].name = name;
 305                        pmap->pin_names[pin_id] = name;
 306                }
 307        }
 308
 309        pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
 310        if (!pctl_desc)
 311                return -ENOMEM;
 312
 313        pctl_desc->name = DRIVER_NAME,
 314        pctl_desc->owner = THIS_MODULE,
 315        pctl_desc->pctlops = &dc_pinctrl_ops,
 316        pctl_desc->pmxops = &dc_pmxops,
 317        pctl_desc->npins = PINS_COUNT;
 318        pctl_desc->pins = pins;
 319        pmap->desc = pctl_desc;
 320
 321        pmap->dev = &pdev->dev;
 322
 323        pmap->pctl = devm_pinctrl_register(&pdev->dev, pctl_desc, pmap);
 324        if (IS_ERR(pmap->pctl)) {
 325                dev_err(&pdev->dev, "pinctrl driver registration failed\n");
 326                return PTR_ERR(pmap->pctl);
 327        }
 328
 329        return dc_gpiochip_add(pmap, pdev->dev.of_node);
 330}
 331
 332static const struct of_device_id dc_pinctrl_ids[] = {
 333        { .compatible = "cnxt,cx92755-pinctrl" },
 334        { /* sentinel */ }
 335};
 336
 337static struct platform_driver dc_pinctrl_driver = {
 338        .driver = {
 339                .name = DRIVER_NAME,
 340                .of_match_table = dc_pinctrl_ids,
 341                .suppress_bind_attrs = true,
 342        },
 343        .probe = dc_pinctrl_probe,
 344};
 345builtin_platform_driver(dc_pinctrl_driver);
 346