Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gpio.c
Go to the documentation of this file.
1 /*
2  * OMAP2+ specific gpio initialization
3  *
4  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * Author:
7  * Charulatha V <[email protected]>
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 #include <linux/of.h>
25 
26 #include <plat/omap_hwmod.h>
27 #include <plat/omap_device.h>
28 #include <plat/omap-pm.h>
29 
30 #include "powerdomain.h"
31 
32 static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
33 {
34  struct platform_device *pdev;
37  char *name = "omap_gpio";
38  int id;
39  struct powerdomain *pwrdm;
40 
41  /*
42  * extract the device id from name field available in the
43  * hwmod database and use the same for constructing ids for
44  * gpio devices.
45  * CAUTION: Make sure the name in the hwmod database does
46  * not change. If changed, make corresponding change here
47  * or make use of static variable mechanism to handle this.
48  */
49  sscanf(oh->name, "gpio%d", &id);
50 
51  pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
52  if (!pdata) {
53  pr_err("gpio%d: Memory allocation failed\n", id);
54  return -ENOMEM;
55  }
56 
57  dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr;
58  pdata->bank_width = dev_attr->bank_width;
59  pdata->dbck_flag = dev_attr->dbck_flag;
61  pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
62  if (!pdata->regs) {
63  pr_err("gpio%d: Memory allocation failed\n", id);
64  kfree(pdata);
65  return -ENOMEM;
66  }
67 
68  switch (oh->class->rev) {
69  case 0:
70  if (id == 1)
71  /* non-wakeup GPIO pins for OMAP2 Bank1 */
72  pdata->non_wakeup_gpios = 0xe203ffc0;
73  else if (id == 2)
74  /* non-wakeup GPIO pins for OMAP2 Bank2 */
75  pdata->non_wakeup_gpios = 0x08700040;
76  /* fall through */
77 
78  case 1:
79  pdata->regs->revision = OMAP24XX_GPIO_REVISION;
80  pdata->regs->direction = OMAP24XX_GPIO_OE;
81  pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
82  pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
83  pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
84  pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
85  pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
86  pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
87  pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
88  pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2;
89  pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
90  pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
91  pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
92  pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
93  pdata->regs->ctrl = OMAP24XX_GPIO_CTRL;
94  pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN;
95  pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0;
96  pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1;
97  pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT;
98  pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT;
99  break;
100  case 2:
101  pdata->regs->revision = OMAP4_GPIO_REVISION;
102  pdata->regs->direction = OMAP4_GPIO_OE;
103  pdata->regs->datain = OMAP4_GPIO_DATAIN;
104  pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
105  pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
106  pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
107  pdata->regs->irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0;
108  pdata->regs->irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1;
109  pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
110  pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
111  pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
112  pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1;
113  pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
114  pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
115  pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
116  pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
117  pdata->regs->ctrl = OMAP4_GPIO_CTRL;
118  pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0;
119  pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0;
120  pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1;
121  pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT;
122  pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT;
123  break;
124  default:
125  WARN(1, "Invalid gpio bank_type\n");
126  kfree(pdata->regs);
127  kfree(pdata);
128  return -EINVAL;
129  }
130 
131  pwrdm = omap_hwmod_get_pwrdm(oh);
133 
134  pdev = omap_device_build(name, id - 1, oh, pdata,
135  sizeof(*pdata), NULL, 0, false);
136  kfree(pdata);
137 
138  if (IS_ERR(pdev)) {
139  WARN(1, "Can't build omap_device for %s:%s.\n",
140  name, oh->name);
141  return PTR_ERR(pdev);
142  }
143 
144  return 0;
145 }
146 
147 /*
148  * gpio_init needs to be done before
149  * machine_init functions access gpio APIs.
150  * Hence gpio_init is a postcore_initcall.
151  */
152 static int __init omap2_gpio_init(void)
153 {
154  /* If dtb is there, the devices will be created dynamically */
155  if (of_have_populated_dt())
156  return -ENODEV;
157 
158  return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL);
159 }
160 postcore_initcall(omap2_gpio_init);