]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/am33xx_gpio.c
Unified codebase for TX28, TX48, TX51, TX53
[karo-tx-uboot.git] / drivers / gpio / am33xx_gpio.c
1 /*
2  * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <common.h>
19 #include <errno.h>
20 #include <asm-generic/gpio.h>
21 #include <asm/io.h>
22 #include <asm/bitops.h>
23 #include <asm/sizes.h>
24 #include <asm/arch/hardware.h>
25
26 struct gpio_regs {
27         unsigned int res1[0x134 / 4];
28         unsigned int oe;                /* 0x134 */
29         unsigned int datain;            /* 0x138 */
30         unsigned int res2[0x54 / 4];
31         unsigned int cleardataout;      /* 0x190 */
32         unsigned int setdataout;        /* 0x194 */
33 };
34
35 struct gpio_regs *gpio_base[] = {
36         (struct gpio_regs *)GPIO0_BASE,
37         (struct gpio_regs *)GPIO1_BASE,
38         (struct gpio_regs *)GPIO2_BASE,
39         (struct gpio_regs *)GPIO3_BASE,
40 };
41
42 static unsigned long gpio_map[ARRAY_SIZE(gpio_base)];
43
44 #define MAX_GPIO        (ARRAY_SIZE(gpio_base) * 32)
45
46 int gpio_request(unsigned gpio, const char *name)
47 {
48         if (gpio >= MAX_GPIO)
49                 return -EINVAL;
50         if (test_and_set_bit(gpio, gpio_map))
51                 return -EBUSY;
52         return 0;
53 }
54
55 int gpio_free(unsigned gpio)
56 {
57         if (gpio >= MAX_GPIO)
58                 return -EINVAL;
59
60         if (test_bit(gpio, gpio_map))
61                 __clear_bit(gpio, gpio_map);
62         else
63                 printf("ERROR: trying to free unclaimed GPIO %u\n", gpio);
64
65         return 0;
66 }
67
68 int gpio_set_value(unsigned gpio, int val)
69 {
70         int bank = gpio / 32;
71         int mask = 1 << (gpio % 32);
72
73         if (bank >= ARRAY_SIZE(gpio_base))
74                 return -EINVAL;
75
76         if (val)
77                 writel(mask, &gpio_base[bank]->setdataout);
78         else
79                 writel(mask, &gpio_base[bank]->cleardataout);
80         return 0;
81 }
82
83 int gpio_direction_input(unsigned gpio)
84 {
85         int bank = gpio / 32;
86         int mask = 1 << (gpio % 32);
87
88         if (bank >= ARRAY_SIZE(gpio_base))
89                 return -EINVAL;
90
91         writel(readl(&gpio_base[bank]->oe) | mask, &gpio_base[bank]->oe);
92         return 0;
93 }
94
95 int gpio_direction_output(unsigned gpio, int val)
96 {
97         int bank = gpio / 32;
98         int mask = 1 << (gpio % 32);
99
100         if (bank >= ARRAY_SIZE(gpio_base))
101                 return -EINVAL;
102
103         gpio_set_value(gpio, val);
104         writel(readl(&gpio_base[bank]->oe) & ~mask, &gpio_base[bank]->oe);
105         return 0;
106 }