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 writel(1 << gpio, ®s->gpiodata[DATA_REG_ADDR(gpio)]); 40 41 return 0; 42 } 43 44 int gpio_get_value(unsigned gpio) 45 { 46 struct gpio_regs *regs = (struct gpio_regs *)CONFIG_GPIO_BASE; 47 u32 val; 48 49 val = readl(®s->gpiodata[DATA_REG_ADDR(gpio)]); 50 51 return !!val; 52 } 53 54 int gpio_request(unsigned gpio, const char *label) 55 { 56 if (gpio >= SPEAR_GPIO_COUNT) 57 return -EINVAL; 58 59 return 0; 60 } 61 62 int gpio_free(unsigned gpio) 63 { 64 return 0; 65 } 66 67 void gpio_toggle_value(unsigned gpio) 68 { 69 gpio_set_value(gpio, !gpio_get_value(gpio)); 70 } 71 72 int gpio_direction_input(unsigned gpio) 73 { 74 return gpio_direction(gpio, GPIO_DIRECTION_IN); 75 } 76 77 int gpio_direction_output(unsigned gpio, int value) 78 { 79 int ret = gpio_direction(gpio, GPIO_DIRECTION_OUT); 80 81 if (ret < 0) 82 return ret; 83 84 gpio_set_value(gpio, value); 85 return 0; 86 } 87