linux/drivers/gpio/gpio-mpc5200.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * MPC52xx gpio driver
   4 *
   5 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
   6 */
   7
   8#include <linux/of.h>
   9#include <linux/kernel.h>
  10#include <linux/slab.h>
  11#include <linux/of_gpio.h>
  12#include <linux/io.h>
  13#include <linux/of_platform.h>
  14#include <linux/module.h>
  15
  16#include <asm/mpc52xx.h>
  17#include <sysdev/fsl_soc.h>
  18
  19static DEFINE_SPINLOCK(gpio_lock);
  20
  21struct mpc52xx_gpiochip {
  22        struct of_mm_gpio_chip mmchip;
  23        unsigned int shadow_dvo;
  24        unsigned int shadow_gpioe;
  25        unsigned int shadow_ddr;
  26};
  27
  28/*
  29 * GPIO LIB API implementation for wakeup GPIOs.
  30 *
  31 * There's a maximum of 8 wakeup GPIOs. Which of these are available
  32 * for use depends on your board setup.
  33 *
  34 * 0 -> GPIO_WKUP_7
  35 * 1 -> GPIO_WKUP_6
  36 * 2 -> PSC6_1
  37 * 3 -> PSC6_0
  38 * 4 -> ETH_17
  39 * 5 -> PSC3_9
  40 * 6 -> PSC2_4
  41 * 7 -> PSC1_4
  42 *
  43 */
  44static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
  45{
  46        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  47        struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
  48        unsigned int ret;
  49
  50        ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
  51
  52        pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
  53
  54        return ret;
  55}
  56
  57static inline void
  58__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  59{
  60        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  61        struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
  62        struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
  63
  64        if (val)
  65                chip->shadow_dvo |= 1 << (7 - gpio);
  66        else
  67                chip->shadow_dvo &= ~(1 << (7 - gpio));
  68
  69        out_8(&regs->wkup_dvo, chip->shadow_dvo);
  70}
  71
  72static void
  73mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
  74{
  75        unsigned long flags;
  76
  77        spin_lock_irqsave(&gpio_lock, flags);
  78
  79        __mpc52xx_wkup_gpio_set(gc, gpio, val);
  80
  81        spin_unlock_irqrestore(&gpio_lock, flags);
  82
  83        pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
  84}
  85
  86static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
  87{
  88        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
  89        struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
  90        struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
  91        unsigned long flags;
  92
  93        spin_lock_irqsave(&gpio_lock, flags);
  94
  95        /* set the direction */
  96        chip->shadow_ddr &= ~(1 << (7 - gpio));
  97        out_8(&regs->wkup_ddr, chip->shadow_ddr);
  98
  99        /* and enable the pin */
 100        chip->shadow_gpioe |= 1 << (7 - gpio);
 101        out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
 102
 103        spin_unlock_irqrestore(&gpio_lock, flags);
 104
 105        return 0;
 106}
 107
 108static int
 109mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 110{
 111        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 112        struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
 113        struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
 114        unsigned long flags;
 115
 116        spin_lock_irqsave(&gpio_lock, flags);
 117
 118        __mpc52xx_wkup_gpio_set(gc, gpio, val);
 119
 120        /* Then set direction */
 121        chip->shadow_ddr |= 1 << (7 - gpio);
 122        out_8(&regs->wkup_ddr, chip->shadow_ddr);
 123
 124        /* Finally enable the pin */
 125        chip->shadow_gpioe |= 1 << (7 - gpio);
 126        out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
 127
 128        spin_unlock_irqrestore(&gpio_lock, flags);
 129
 130        pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
 131
 132        return 0;
 133}
 134
 135static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
 136{
 137        struct mpc52xx_gpiochip *chip;
 138        struct mpc52xx_gpio_wkup __iomem *regs;
 139        struct gpio_chip *gc;
 140        int ret;
 141
 142        chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
 143        if (!chip)
 144                return -ENOMEM;
 145
 146        platform_set_drvdata(ofdev, chip);
 147
 148        gc = &chip->mmchip.gc;
 149
 150        gc->ngpio            = 8;
 151        gc->direction_input  = mpc52xx_wkup_gpio_dir_in;
 152        gc->direction_output = mpc52xx_wkup_gpio_dir_out;
 153        gc->get              = mpc52xx_wkup_gpio_get;
 154        gc->set              = mpc52xx_wkup_gpio_set;
 155
 156        ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
 157        if (ret)
 158                return ret;
 159
 160        regs = chip->mmchip.regs;
 161        chip->shadow_gpioe = in_8(&regs->wkup_gpioe);
 162        chip->shadow_ddr = in_8(&regs->wkup_ddr);
 163        chip->shadow_dvo = in_8(&regs->wkup_dvo);
 164
 165        return 0;
 166}
 167
 168static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
 169{
 170        struct mpc52xx_gpiochip *chip = platform_get_drvdata(ofdev);
 171
 172        of_mm_gpiochip_remove(&chip->mmchip);
 173
 174        return 0;
 175}
 176
 177static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
 178        { .compatible = "fsl,mpc5200-gpio-wkup", },
 179        {}
 180};
 181
 182static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
 183        .driver = {
 184                .name = "mpc5200-gpio-wkup",
 185                .of_match_table = mpc52xx_wkup_gpiochip_match,
 186        },
 187        .probe = mpc52xx_wkup_gpiochip_probe,
 188        .remove = mpc52xx_gpiochip_remove,
 189};
 190
 191/*
 192 * GPIO LIB API implementation for simple GPIOs
 193 *
 194 * There's a maximum of 32 simple GPIOs. Which of these are available
 195 * for use depends on your board setup.
 196 * The numbering reflects the bit numbering in the port registers:
 197 *
 198 *  0..1  > reserved
 199 *  2..3  > IRDA
 200 *  4..7  > ETHR
 201 *  8..11 > reserved
 202 * 12..15 > USB
 203 * 16..17 > reserved
 204 * 18..23 > PSC3
 205 * 24..27 > PSC2
 206 * 28..31 > PSC1
 207 */
 208static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 209{
 210        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 211        struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
 212        unsigned int ret;
 213
 214        ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
 215
 216        return ret;
 217}
 218
 219static inline void
 220__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 221{
 222        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 223        struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
 224        struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
 225
 226        if (val)
 227                chip->shadow_dvo |= 1 << (31 - gpio);
 228        else
 229                chip->shadow_dvo &= ~(1 << (31 - gpio));
 230        out_be32(&regs->simple_dvo, chip->shadow_dvo);
 231}
 232
 233static void
 234mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 235{
 236        unsigned long flags;
 237
 238        spin_lock_irqsave(&gpio_lock, flags);
 239
 240        __mpc52xx_simple_gpio_set(gc, gpio, val);
 241
 242        spin_unlock_irqrestore(&gpio_lock, flags);
 243
 244        pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
 245}
 246
 247static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 248{
 249        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 250        struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
 251        struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
 252        unsigned long flags;
 253
 254        spin_lock_irqsave(&gpio_lock, flags);
 255
 256        /* set the direction */
 257        chip->shadow_ddr &= ~(1 << (31 - gpio));
 258        out_be32(&regs->simple_ddr, chip->shadow_ddr);
 259
 260        /* and enable the pin */
 261        chip->shadow_gpioe |= 1 << (31 - gpio);
 262        out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
 263
 264        spin_unlock_irqrestore(&gpio_lock, flags);
 265
 266        return 0;
 267}
 268
 269static int
 270mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 271{
 272        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 273        struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
 274        struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
 275        unsigned long flags;
 276
 277        spin_lock_irqsave(&gpio_lock, flags);
 278
 279        /* First set initial value */
 280        __mpc52xx_simple_gpio_set(gc, gpio, val);
 281
 282        /* Then set direction */
 283        chip->shadow_ddr |= 1 << (31 - gpio);
 284        out_be32(&regs->simple_ddr, chip->shadow_ddr);
 285
 286        /* Finally enable the pin */
 287        chip->shadow_gpioe |= 1 << (31 - gpio);
 288        out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
 289
 290        spin_unlock_irqrestore(&gpio_lock, flags);
 291
 292        pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
 293
 294        return 0;
 295}
 296
 297static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
 298{
 299        struct mpc52xx_gpiochip *chip;
 300        struct gpio_chip *gc;
 301        struct mpc52xx_gpio __iomem *regs;
 302        int ret;
 303
 304        chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
 305        if (!chip)
 306                return -ENOMEM;
 307
 308        platform_set_drvdata(ofdev, chip);
 309
 310        gc = &chip->mmchip.gc;
 311
 312        gc->ngpio            = 32;
 313        gc->direction_input  = mpc52xx_simple_gpio_dir_in;
 314        gc->direction_output = mpc52xx_simple_gpio_dir_out;
 315        gc->get              = mpc52xx_simple_gpio_get;
 316        gc->set              = mpc52xx_simple_gpio_set;
 317
 318        ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
 319        if (ret)
 320                return ret;
 321
 322        regs = chip->mmchip.regs;
 323        chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
 324        chip->shadow_ddr = in_be32(&regs->simple_ddr);
 325        chip->shadow_dvo = in_be32(&regs->simple_dvo);
 326
 327        return 0;
 328}
 329
 330static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
 331        { .compatible = "fsl,mpc5200-gpio", },
 332        {}
 333};
 334
 335static struct platform_driver mpc52xx_simple_gpiochip_driver = {
 336        .driver = {
 337                .name = "mpc5200-gpio",
 338                .of_match_table = mpc52xx_simple_gpiochip_match,
 339        },
 340        .probe = mpc52xx_simple_gpiochip_probe,
 341        .remove = mpc52xx_gpiochip_remove,
 342};
 343
 344static struct platform_driver * const drivers[] = {
 345        &mpc52xx_wkup_gpiochip_driver,
 346        &mpc52xx_simple_gpiochip_driver,
 347};
 348
 349static int __init mpc52xx_gpio_init(void)
 350{
 351        return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 352}
 353
 354/* Make sure we get initialised before anyone else tries to use us */
 355subsys_initcall(mpc52xx_gpio_init);
 356
 357static void __exit mpc52xx_gpio_exit(void)
 358{
 359        platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 360}
 361module_exit(mpc52xx_gpio_exit);
 362
 363MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
 364MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
 365MODULE_LICENSE("GPL v2");
 366
 367