Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * MPC52xx gpio driver
0004  *
0005  * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
0006  */
0007 
0008 #include <linux/of.h>
0009 #include <linux/kernel.h>
0010 #include <linux/slab.h>
0011 #include <linux/of_gpio.h>
0012 #include <linux/io.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/module.h>
0015 
0016 #include <asm/mpc52xx.h>
0017 #include <sysdev/fsl_soc.h>
0018 
0019 static DEFINE_SPINLOCK(gpio_lock);
0020 
0021 struct mpc52xx_gpiochip {
0022     struct of_mm_gpio_chip mmchip;
0023     unsigned int shadow_dvo;
0024     unsigned int shadow_gpioe;
0025     unsigned int shadow_ddr;
0026 };
0027 
0028 /*
0029  * GPIO LIB API implementation for wakeup GPIOs.
0030  *
0031  * There's a maximum of 8 wakeup GPIOs. Which of these are available
0032  * for use depends on your board setup.
0033  *
0034  * 0 -> GPIO_WKUP_7
0035  * 1 -> GPIO_WKUP_6
0036  * 2 -> PSC6_1
0037  * 3 -> PSC6_0
0038  * 4 -> ETH_17
0039  * 5 -> PSC3_9
0040  * 6 -> PSC2_4
0041  * 7 -> PSC1_4
0042  *
0043  */
0044 static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
0045 {
0046     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0047     struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
0048     unsigned int ret;
0049 
0050     ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
0051 
0052     pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
0053 
0054     return ret;
0055 }
0056 
0057 static inline void
0058 __mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
0059 {
0060     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0061     struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
0062     struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
0063 
0064     if (val)
0065         chip->shadow_dvo |= 1 << (7 - gpio);
0066     else
0067         chip->shadow_dvo &= ~(1 << (7 - gpio));
0068 
0069     out_8(&regs->wkup_dvo, chip->shadow_dvo);
0070 }
0071 
0072 static void
0073 mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
0074 {
0075     unsigned long flags;
0076 
0077     spin_lock_irqsave(&gpio_lock, flags);
0078 
0079     __mpc52xx_wkup_gpio_set(gc, gpio, val);
0080 
0081     spin_unlock_irqrestore(&gpio_lock, flags);
0082 
0083     pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
0084 }
0085 
0086 static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
0087 {
0088     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0089     struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
0090     struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
0091     unsigned long flags;
0092 
0093     spin_lock_irqsave(&gpio_lock, flags);
0094 
0095     /* set the direction */
0096     chip->shadow_ddr &= ~(1 << (7 - gpio));
0097     out_8(&regs->wkup_ddr, chip->shadow_ddr);
0098 
0099     /* and enable the pin */
0100     chip->shadow_gpioe |= 1 << (7 - gpio);
0101     out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
0102 
0103     spin_unlock_irqrestore(&gpio_lock, flags);
0104 
0105     return 0;
0106 }
0107 
0108 static int
0109 mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
0110 {
0111     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0112     struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
0113     struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
0114     unsigned long flags;
0115 
0116     spin_lock_irqsave(&gpio_lock, flags);
0117 
0118     __mpc52xx_wkup_gpio_set(gc, gpio, val);
0119 
0120     /* Then set direction */
0121     chip->shadow_ddr |= 1 << (7 - gpio);
0122     out_8(&regs->wkup_ddr, chip->shadow_ddr);
0123 
0124     /* Finally enable the pin */
0125     chip->shadow_gpioe |= 1 << (7 - gpio);
0126     out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
0127 
0128     spin_unlock_irqrestore(&gpio_lock, flags);
0129 
0130     pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
0131 
0132     return 0;
0133 }
0134 
0135 static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
0136 {
0137     struct mpc52xx_gpiochip *chip;
0138     struct mpc52xx_gpio_wkup __iomem *regs;
0139     struct gpio_chip *gc;
0140     int ret;
0141 
0142     chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
0143     if (!chip)
0144         return -ENOMEM;
0145 
0146     platform_set_drvdata(ofdev, chip);
0147 
0148     gc = &chip->mmchip.gc;
0149 
0150     gc->ngpio            = 8;
0151     gc->direction_input  = mpc52xx_wkup_gpio_dir_in;
0152     gc->direction_output = mpc52xx_wkup_gpio_dir_out;
0153     gc->get              = mpc52xx_wkup_gpio_get;
0154     gc->set              = mpc52xx_wkup_gpio_set;
0155 
0156     ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
0157     if (ret)
0158         return ret;
0159 
0160     regs = chip->mmchip.regs;
0161     chip->shadow_gpioe = in_8(&regs->wkup_gpioe);
0162     chip->shadow_ddr = in_8(&regs->wkup_ddr);
0163     chip->shadow_dvo = in_8(&regs->wkup_dvo);
0164 
0165     return 0;
0166 }
0167 
0168 static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
0169 {
0170     struct mpc52xx_gpiochip *chip = platform_get_drvdata(ofdev);
0171 
0172     of_mm_gpiochip_remove(&chip->mmchip);
0173 
0174     return 0;
0175 }
0176 
0177 static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
0178     { .compatible = "fsl,mpc5200-gpio-wkup", },
0179     {}
0180 };
0181 
0182 static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
0183     .driver = {
0184         .name = "mpc5200-gpio-wkup",
0185         .of_match_table = mpc52xx_wkup_gpiochip_match,
0186     },
0187     .probe = mpc52xx_wkup_gpiochip_probe,
0188     .remove = mpc52xx_gpiochip_remove,
0189 };
0190 
0191 /*
0192  * GPIO LIB API implementation for simple GPIOs
0193  *
0194  * There's a maximum of 32 simple GPIOs. Which of these are available
0195  * for use depends on your board setup.
0196  * The numbering reflects the bit numbering in the port registers:
0197  *
0198  *  0..1  > reserved
0199  *  2..3  > IRDA
0200  *  4..7  > ETHR
0201  *  8..11 > reserved
0202  * 12..15 > USB
0203  * 16..17 > reserved
0204  * 18..23 > PSC3
0205  * 24..27 > PSC2
0206  * 28..31 > PSC1
0207  */
0208 static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
0209 {
0210     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0211     struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
0212     unsigned int ret;
0213 
0214     ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
0215 
0216     return ret;
0217 }
0218 
0219 static inline void
0220 __mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
0221 {
0222     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0223     struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
0224     struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
0225 
0226     if (val)
0227         chip->shadow_dvo |= 1 << (31 - gpio);
0228     else
0229         chip->shadow_dvo &= ~(1 << (31 - gpio));
0230     out_be32(&regs->simple_dvo, chip->shadow_dvo);
0231 }
0232 
0233 static void
0234 mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
0235 {
0236     unsigned long flags;
0237 
0238     spin_lock_irqsave(&gpio_lock, flags);
0239 
0240     __mpc52xx_simple_gpio_set(gc, gpio, val);
0241 
0242     spin_unlock_irqrestore(&gpio_lock, flags);
0243 
0244     pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
0245 }
0246 
0247 static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
0248 {
0249     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0250     struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
0251     struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
0252     unsigned long flags;
0253 
0254     spin_lock_irqsave(&gpio_lock, flags);
0255 
0256     /* set the direction */
0257     chip->shadow_ddr &= ~(1 << (31 - gpio));
0258     out_be32(&regs->simple_ddr, chip->shadow_ddr);
0259 
0260     /* and enable the pin */
0261     chip->shadow_gpioe |= 1 << (31 - gpio);
0262     out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
0263 
0264     spin_unlock_irqrestore(&gpio_lock, flags);
0265 
0266     return 0;
0267 }
0268 
0269 static int
0270 mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
0271 {
0272     struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
0273     struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
0274     struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
0275     unsigned long flags;
0276 
0277     spin_lock_irqsave(&gpio_lock, flags);
0278 
0279     /* First set initial value */
0280     __mpc52xx_simple_gpio_set(gc, gpio, val);
0281 
0282     /* Then set direction */
0283     chip->shadow_ddr |= 1 << (31 - gpio);
0284     out_be32(&regs->simple_ddr, chip->shadow_ddr);
0285 
0286     /* Finally enable the pin */
0287     chip->shadow_gpioe |= 1 << (31 - gpio);
0288     out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
0289 
0290     spin_unlock_irqrestore(&gpio_lock, flags);
0291 
0292     pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
0293 
0294     return 0;
0295 }
0296 
0297 static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
0298 {
0299     struct mpc52xx_gpiochip *chip;
0300     struct gpio_chip *gc;
0301     struct mpc52xx_gpio __iomem *regs;
0302     int ret;
0303 
0304     chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
0305     if (!chip)
0306         return -ENOMEM;
0307 
0308     platform_set_drvdata(ofdev, chip);
0309 
0310     gc = &chip->mmchip.gc;
0311 
0312     gc->ngpio            = 32;
0313     gc->direction_input  = mpc52xx_simple_gpio_dir_in;
0314     gc->direction_output = mpc52xx_simple_gpio_dir_out;
0315     gc->get              = mpc52xx_simple_gpio_get;
0316     gc->set              = mpc52xx_simple_gpio_set;
0317 
0318     ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
0319     if (ret)
0320         return ret;
0321 
0322     regs = chip->mmchip.regs;
0323     chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
0324     chip->shadow_ddr = in_be32(&regs->simple_ddr);
0325     chip->shadow_dvo = in_be32(&regs->simple_dvo);
0326 
0327     return 0;
0328 }
0329 
0330 static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
0331     { .compatible = "fsl,mpc5200-gpio", },
0332     {}
0333 };
0334 
0335 static struct platform_driver mpc52xx_simple_gpiochip_driver = {
0336     .driver = {
0337         .name = "mpc5200-gpio",
0338         .of_match_table = mpc52xx_simple_gpiochip_match,
0339     },
0340     .probe = mpc52xx_simple_gpiochip_probe,
0341     .remove = mpc52xx_gpiochip_remove,
0342 };
0343 
0344 static struct platform_driver * const drivers[] = {
0345     &mpc52xx_wkup_gpiochip_driver,
0346     &mpc52xx_simple_gpiochip_driver,
0347 };
0348 
0349 static int __init mpc52xx_gpio_init(void)
0350 {
0351     return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
0352 }
0353 
0354 /* Make sure we get initialised before anyone else tries to use us */
0355 subsys_initcall(mpc52xx_gpio_init);
0356 
0357 static void __exit mpc52xx_gpio_exit(void)
0358 {
0359     platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
0360 }
0361 module_exit(mpc52xx_gpio_exit);
0362 
0363 MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
0364 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
0365 MODULE_LICENSE("GPL v2");
0366