Merge branch 'ext4'
[kernel/u-boot.git] / drivers / gpio / bcm2835_gpio.c
1 /*
2  * Copyright (C) 2012 Vikram Narayananan
3  * <vikram186@gmail.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 #include <common.h>
20 #include <asm/gpio.h>
21 #include <asm/io.h>
22
23 inline int gpio_is_valid(unsigned gpio)
24 {
25         return (gpio < BCM2835_GPIO_COUNT);
26 }
27
28 int gpio_request(unsigned gpio, const char *label)
29 {
30         return !gpio_is_valid(gpio);
31 }
32
33 int gpio_free(unsigned gpio)
34 {
35         return 0;
36 }
37
38 int gpio_direction_input(unsigned gpio)
39 {
40         struct bcm2835_gpio_regs *reg =
41                 (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
42         unsigned val;
43
44         val = readl(&reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
45         val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio));
46         val |= (BCM2835_GPIO_INPUT << BCM2835_GPIO_FSEL_SHIFT(gpio));
47         writel(val, &reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
48
49         return 0;
50 }
51
52 int gpio_direction_output(unsigned gpio, int value)
53 {
54         struct bcm2835_gpio_regs *reg =
55                 (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
56         unsigned val;
57
58         gpio_set_value(gpio, value);
59
60         val = readl(&reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
61         val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio));
62         val |= (BCM2835_GPIO_OUTPUT << BCM2835_GPIO_FSEL_SHIFT(gpio));
63         writel(val, &reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
64
65         return 0;
66 }
67
68 int gpio_get_value(unsigned gpio)
69 {
70         struct bcm2835_gpio_regs *reg =
71                 (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
72         unsigned val;
73
74         val = readl(&reg->gplev[BCM2835_GPIO_COMMON_BANK(gpio)]);
75
76         return (val >> BCM2835_GPIO_COMMON_SHIFT(gpio)) & 0x1;
77 }
78
79 int gpio_set_value(unsigned gpio, int value)
80 {
81         struct bcm2835_gpio_regs *reg =
82                 (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
83         u32 *output_reg = value ? reg->gpset : reg->gpclr;
84
85         writel(1 << BCM2835_GPIO_COMMON_SHIFT(gpio),
86                                 &output_reg[BCM2835_GPIO_COMMON_BANK(gpio)]);
87
88         return 0;
89 }