1 /* 2 * Copyright (C) 2012 Stefan Roese <sr@denx.de> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* 8 * Driver for SPEAr600 GPIO controller 9 */ 10 11 #include <common.h> 12 #include <asm/arch/hardware.h> 13 #include <asm/gpio.h> 14 #include <asm/io.h> 15 #include <errno.h> 16 17 static int gpio_direction(unsigned gpio, 18 enum gpio_direction direction) 19 { 20 struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 21 u32 val; 22 23 val = readl(®s->gpiodir); 24 25 if (direction == GPIO_DIRECTION_OUT) 26 val |= 1 << gpio; 27 else 28 val &= ~(1 << gpio); 29 30 writel(val, ®s->gpiodir); 31 32 return 0; 33 } 34 35 int gpio_set_value(unsigned gpio, int value) 36 { 37 struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 38 39 if (value) 40 writel(1 << gpio, ®s->gpiodata[DATA_REG_ADDR(gpio)]); 41 else 42 writel(0, ®s->gpiodata[DATA_REG_ADDR(gpio)]); 43 44 return 0; 45 } 46 47 int gpio_get_value(unsigned gpio) 48 { 49 struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 50 u32 val; 51 52 val = readl(®s->gpiodata[DATA_REG_ADDR(gpio)]); 53 54 return !!val; 55 } 56 57 int gpio_request(unsigned gpio, const char *label) 58 { 59 if (gpio >= SPEAR_GPIO_COUNT) 60 return -EINVAL; 61 62 return 0; 63 } 64 65 int gpio_free(unsigned gpio) 66 { 67 return 0; 68 } 69 70 void gpio_toggle_value(unsigned gpio) 71 { 72 gpio_set_value(gpio, !gpio_get_value(gpio)); 73 } 74 75 int gpio_direction_input(unsigned gpio) 76 { 77 return gpio_direction(gpio, GPIO_DIRECTION_IN); 78 } 79 80 int gpio_direction_output(unsigned gpio, int value) 81 { 82 int ret = gpio_direction(gpio, GPIO_DIRECTION_OUT); 83 84 if (ret < 0) 85 return ret; 86 87 gpio_set_value(gpio, value); 88 return 0; 89 } 90