Path: blob/master/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
10818 views
/*1* MPC52xx gpio driver2*3* Copyright (c) 2008 Sascha Hauer <[email protected]>, Pengutronix4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 27* as published by the Free Software Foundation.8*9* This program is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*14* You should have received a copy of the GNU General Public License15* along with this program; if not, write to the Free Software16* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA17*/1819#include <linux/of.h>20#include <linux/kernel.h>21#include <linux/slab.h>22#include <linux/of_gpio.h>23#include <linux/io.h>24#include <linux/of_platform.h>2526#include <asm/gpio.h>27#include <asm/mpc52xx.h>28#include <sysdev/fsl_soc.h>2930static DEFINE_SPINLOCK(gpio_lock);3132struct mpc52xx_gpiochip {33struct of_mm_gpio_chip mmchip;34unsigned int shadow_dvo;35unsigned int shadow_gpioe;36unsigned int shadow_ddr;37};3839/*40* GPIO LIB API implementation for wakeup GPIOs.41*42* There's a maximum of 8 wakeup GPIOs. Which of these are available43* for use depends on your board setup.44*45* 0 -> GPIO_WKUP_746* 1 -> GPIO_WKUP_647* 2 -> PSC6_148* 3 -> PSC6_049* 4 -> ETH_1750* 5 -> PSC3_951* 6 -> PSC2_452* 7 -> PSC1_453*54*/55static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)56{57struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);58struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;59unsigned int ret;6061ret = (in_8(®s->wkup_ival) >> (7 - gpio)) & 1;6263pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);6465return ret;66}6768static inline void69__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)70{71struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);72struct mpc52xx_gpiochip *chip = container_of(mm_gc,73struct mpc52xx_gpiochip, mmchip);74struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;7576if (val)77chip->shadow_dvo |= 1 << (7 - gpio);78else79chip->shadow_dvo &= ~(1 << (7 - gpio));8081out_8(®s->wkup_dvo, chip->shadow_dvo);82}8384static void85mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)86{87unsigned long flags;8889spin_lock_irqsave(&gpio_lock, flags);9091__mpc52xx_wkup_gpio_set(gc, gpio, val);9293spin_unlock_irqrestore(&gpio_lock, flags);9495pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);96}9798static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)99{100struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);101struct mpc52xx_gpiochip *chip = container_of(mm_gc,102struct mpc52xx_gpiochip, mmchip);103struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;104unsigned long flags;105106spin_lock_irqsave(&gpio_lock, flags);107108/* set the direction */109chip->shadow_ddr &= ~(1 << (7 - gpio));110out_8(®s->wkup_ddr, chip->shadow_ddr);111112/* and enable the pin */113chip->shadow_gpioe |= 1 << (7 - gpio);114out_8(®s->wkup_gpioe, chip->shadow_gpioe);115116spin_unlock_irqrestore(&gpio_lock, flags);117118return 0;119}120121static int122mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)123{124struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);125struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;126struct mpc52xx_gpiochip *chip = container_of(mm_gc,127struct mpc52xx_gpiochip, mmchip);128unsigned long flags;129130spin_lock_irqsave(&gpio_lock, flags);131132__mpc52xx_wkup_gpio_set(gc, gpio, val);133134/* Then set direction */135chip->shadow_ddr |= 1 << (7 - gpio);136out_8(®s->wkup_ddr, chip->shadow_ddr);137138/* Finally enable the pin */139chip->shadow_gpioe |= 1 << (7 - gpio);140out_8(®s->wkup_gpioe, chip->shadow_gpioe);141142spin_unlock_irqrestore(&gpio_lock, flags);143144pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);145146return 0;147}148149static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)150{151struct mpc52xx_gpiochip *chip;152struct mpc52xx_gpio_wkup __iomem *regs;153struct gpio_chip *gc;154int ret;155156chip = kzalloc(sizeof(*chip), GFP_KERNEL);157if (!chip)158return -ENOMEM;159160gc = &chip->mmchip.gc;161162gc->ngpio = 8;163gc->direction_input = mpc52xx_wkup_gpio_dir_in;164gc->direction_output = mpc52xx_wkup_gpio_dir_out;165gc->get = mpc52xx_wkup_gpio_get;166gc->set = mpc52xx_wkup_gpio_set;167168ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);169if (ret)170return ret;171172regs = chip->mmchip.regs;173chip->shadow_gpioe = in_8(®s->wkup_gpioe);174chip->shadow_ddr = in_8(®s->wkup_ddr);175chip->shadow_dvo = in_8(®s->wkup_dvo);176177return 0;178}179180static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)181{182return -EBUSY;183}184185static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {186{187.compatible = "fsl,mpc5200-gpio-wkup",188},189{}190};191192static struct platform_driver mpc52xx_wkup_gpiochip_driver = {193.driver = {194.name = "gpio_wkup",195.owner = THIS_MODULE,196.of_match_table = mpc52xx_wkup_gpiochip_match,197},198.probe = mpc52xx_wkup_gpiochip_probe,199.remove = mpc52xx_gpiochip_remove,200};201202/*203* GPIO LIB API implementation for simple GPIOs204*205* There's a maximum of 32 simple GPIOs. Which of these are available206* for use depends on your board setup.207* The numbering reflects the bit numbering in the port registers:208*209* 0..1 > reserved210* 2..3 > IRDA211* 4..7 > ETHR212* 8..11 > reserved213* 12..15 > USB214* 16..17 > reserved215* 18..23 > PSC3216* 24..27 > PSC2217* 28..31 > PSC1218*/219static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)220{221struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);222struct mpc52xx_gpio __iomem *regs = mm_gc->regs;223unsigned int ret;224225ret = (in_be32(®s->simple_ival) >> (31 - gpio)) & 1;226227return ret;228}229230static inline void231__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)232{233struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);234struct mpc52xx_gpiochip *chip = container_of(mm_gc,235struct mpc52xx_gpiochip, mmchip);236struct mpc52xx_gpio __iomem *regs = mm_gc->regs;237238if (val)239chip->shadow_dvo |= 1 << (31 - gpio);240else241chip->shadow_dvo &= ~(1 << (31 - gpio));242out_be32(®s->simple_dvo, chip->shadow_dvo);243}244245static void246mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)247{248unsigned long flags;249250spin_lock_irqsave(&gpio_lock, flags);251252__mpc52xx_simple_gpio_set(gc, gpio, val);253254spin_unlock_irqrestore(&gpio_lock, flags);255256pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);257}258259static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)260{261struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);262struct mpc52xx_gpiochip *chip = container_of(mm_gc,263struct mpc52xx_gpiochip, mmchip);264struct mpc52xx_gpio __iomem *regs = mm_gc->regs;265unsigned long flags;266267spin_lock_irqsave(&gpio_lock, flags);268269/* set the direction */270chip->shadow_ddr &= ~(1 << (31 - gpio));271out_be32(®s->simple_ddr, chip->shadow_ddr);272273/* and enable the pin */274chip->shadow_gpioe |= 1 << (31 - gpio);275out_be32(®s->simple_gpioe, chip->shadow_gpioe);276277spin_unlock_irqrestore(&gpio_lock, flags);278279return 0;280}281282static int283mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)284{285struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);286struct mpc52xx_gpiochip *chip = container_of(mm_gc,287struct mpc52xx_gpiochip, mmchip);288struct mpc52xx_gpio __iomem *regs = mm_gc->regs;289unsigned long flags;290291spin_lock_irqsave(&gpio_lock, flags);292293/* First set initial value */294__mpc52xx_simple_gpio_set(gc, gpio, val);295296/* Then set direction */297chip->shadow_ddr |= 1 << (31 - gpio);298out_be32(®s->simple_ddr, chip->shadow_ddr);299300/* Finally enable the pin */301chip->shadow_gpioe |= 1 << (31 - gpio);302out_be32(®s->simple_gpioe, chip->shadow_gpioe);303304spin_unlock_irqrestore(&gpio_lock, flags);305306pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);307308return 0;309}310311static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)312{313struct mpc52xx_gpiochip *chip;314struct gpio_chip *gc;315struct mpc52xx_gpio __iomem *regs;316int ret;317318chip = kzalloc(sizeof(*chip), GFP_KERNEL);319if (!chip)320return -ENOMEM;321322gc = &chip->mmchip.gc;323324gc->ngpio = 32;325gc->direction_input = mpc52xx_simple_gpio_dir_in;326gc->direction_output = mpc52xx_simple_gpio_dir_out;327gc->get = mpc52xx_simple_gpio_get;328gc->set = mpc52xx_simple_gpio_set;329330ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);331if (ret)332return ret;333334regs = chip->mmchip.regs;335chip->shadow_gpioe = in_be32(®s->simple_gpioe);336chip->shadow_ddr = in_be32(®s->simple_ddr);337chip->shadow_dvo = in_be32(®s->simple_dvo);338339return 0;340}341342static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {343{344.compatible = "fsl,mpc5200-gpio",345},346{}347};348349static struct platform_driver mpc52xx_simple_gpiochip_driver = {350.driver = {351.name = "gpio",352.owner = THIS_MODULE,353.of_match_table = mpc52xx_simple_gpiochip_match,354},355.probe = mpc52xx_simple_gpiochip_probe,356.remove = mpc52xx_gpiochip_remove,357};358359static int __init mpc52xx_gpio_init(void)360{361if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver))362printk(KERN_ERR "Unable to register wakeup GPIO driver\n");363364if (platform_driver_register(&mpc52xx_simple_gpiochip_driver))365printk(KERN_ERR "Unable to register simple GPIO driver\n");366367return 0;368}369370371/* Make sure we get initialised before anyone else tries to use us */372subsys_initcall(mpc52xx_gpio_init);373374/* No exit call at the moment as we cannot unregister of gpio chips */375376MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");377MODULE_AUTHOR("Sascha Hauer <[email protected]");378MODULE_LICENSE("GPL v2");379380381382