xref: /openbmc/u-boot/drivers/gpio/bcm2835_gpio.c (revision e874d5b0)
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 }
90