linux/arch/arm/mach-omap2/gpio.c
<<
>>
Prefs
   1/*
   2 * OMAP2+ specific gpio initialization
   3 *
   4 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
   5 *
   6 * Author:
   7 *      Charulatha V <charu@ti.com>
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation version 2.
  12 *
  13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  14 * kind, whether express or implied; without even the implied warranty
  15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 */
  18
  19#include <linux/gpio.h>
  20#include <linux/err.h>
  21#include <linux/slab.h>
  22#include <linux/interrupt.h>
  23
  24#include <plat/omap_hwmod.h>
  25#include <plat/omap_device.h>
  26
  27static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
  28{
  29        struct platform_device *pdev;
  30        struct omap_gpio_platform_data *pdata;
  31        struct omap_gpio_dev_attr *dev_attr;
  32        char *name = "omap_gpio";
  33        int id;
  34
  35        /*
  36         * extract the device id from name field available in the
  37         * hwmod database and use the same for constructing ids for
  38         * gpio devices.
  39         * CAUTION: Make sure the name in the hwmod database does
  40         * not change. If changed, make corresponding change here
  41         * or make use of static variable mechanism to handle this.
  42         */
  43        sscanf(oh->name, "gpio%d", &id);
  44
  45        pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
  46        if (!pdata) {
  47                pr_err("gpio%d: Memory allocation failed\n", id);
  48                return -ENOMEM;
  49        }
  50
  51        dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr;
  52        pdata->bank_width = dev_attr->bank_width;
  53        pdata->dbck_flag = dev_attr->dbck_flag;
  54        pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
  55
  56        pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
  57        if (!pdata) {
  58                pr_err("gpio%d: Memory allocation failed\n", id);
  59                return -ENOMEM;
  60        }
  61
  62        switch (oh->class->rev) {
  63        case 0:
  64        case 1:
  65                pdata->bank_type = METHOD_GPIO_24XX;
  66                pdata->regs->revision = OMAP24XX_GPIO_REVISION;
  67                pdata->regs->direction = OMAP24XX_GPIO_OE;
  68                pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
  69                pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
  70                pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
  71                pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
  72                pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
  73                pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
  74                pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
  75                pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
  76                pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
  77                pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
  78                pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
  79                break;
  80        case 2:
  81                pdata->bank_type = METHOD_GPIO_44XX;
  82                pdata->regs->revision = OMAP4_GPIO_REVISION;
  83                pdata->regs->direction = OMAP4_GPIO_OE;
  84                pdata->regs->datain = OMAP4_GPIO_DATAIN;
  85                pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
  86                pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
  87                pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
  88                pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
  89                pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
  90                pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
  91                pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
  92                pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
  93                pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
  94                pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
  95                break;
  96        default:
  97                WARN(1, "Invalid gpio bank_type\n");
  98                kfree(pdata);
  99                return -EINVAL;
 100        }
 101
 102        pdev = omap_device_build(name, id - 1, oh, pdata,
 103                                sizeof(*pdata), NULL, 0, false);
 104        kfree(pdata);
 105
 106        if (IS_ERR(pdev)) {
 107                WARN(1, "Can't build omap_device for %s:%s.\n",
 108                                        name, oh->name);
 109                return PTR_ERR(pdev);
 110        }
 111
 112        omap_device_disable_idle_on_suspend(pdev);
 113
 114        gpio_bank_count++;
 115        return 0;
 116}
 117
 118/*
 119 * gpio_init needs to be done before
 120 * machine_init functions access gpio APIs.
 121 * Hence gpio_init is a postcore_initcall.
 122 */
 123static int __init omap2_gpio_init(void)
 124{
 125        return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init,
 126                                                NULL);
 127}
 128postcore_initcall(omap2_gpio_init);
 129
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.