root/drivers/gpio/gpio-mpc5200.c

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

DEFINITIONS

This source file includes following definitions.
  1. mpc52xx_wkup_gpio_get
  2. __mpc52xx_wkup_gpio_set
  3. mpc52xx_wkup_gpio_set
  4. mpc52xx_wkup_gpio_dir_in
  5. mpc52xx_wkup_gpio_dir_out
  6. mpc52xx_wkup_gpiochip_probe
  7. mpc52xx_gpiochip_remove
  8. mpc52xx_simple_gpio_get
  9. __mpc52xx_simple_gpio_set
  10. mpc52xx_simple_gpio_set
  11. mpc52xx_simple_gpio_dir_in
  12. mpc52xx_simple_gpio_dir_out
  13. mpc52xx_simple_gpiochip_probe
  14. mpc52xx_gpio_init
  15. mpc52xx_gpio_exit

   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 
  19 static DEFINE_SPINLOCK(gpio_lock);
  20 
  21 struct 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  */
  44 static 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 
  57 static 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 
  72 static void
  73 mpc52xx_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 
  86 static 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 
 108 static int
 109 mpc52xx_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 
 135 static 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 
 168 static 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 
 177 static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
 178         { .compatible = "fsl,mpc5200-gpio-wkup", },
 179         {}
 180 };
 181 
 182 static 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  */
 208 static 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 
 219 static 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 
 233 static void
 234 mpc52xx_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 
 247 static 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 
 269 static int
 270 mpc52xx_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 
 297 static 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 
 330 static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
 331         { .compatible = "fsl,mpc5200-gpio", },
 332         {}
 333 };
 334 
 335 static 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 
 344 static struct platform_driver * const drivers[] = {
 345         &mpc52xx_wkup_gpiochip_driver,
 346         &mpc52xx_simple_gpiochip_driver,
 347 };
 348 
 349 static 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 */
 355 subsys_initcall(mpc52xx_gpio_init);
 356 
 357 static void __exit mpc52xx_gpio_exit(void)
 358 {
 359         platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 360 }
 361 module_exit(mpc52xx_gpio_exit);
 362 
 363 MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
 364 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
 365 MODULE_LICENSE("GPL v2");
 366 

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