1/* 2 * Texas Instruments TNETV107X GPIO Controller 3 * 4 * Copyright (C) 2010 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/gpio.h> 18 19#include <mach/common.h> 20#include <mach/tnetv107x.h> 21 22struct tnetv107x_gpio_regs { 23 u32 idver; 24 u32 data_in[3]; 25 u32 data_out[3]; 26 u32 direction[3]; 27 u32 enable[3]; 28}; 29 30#define gpio_reg_index(gpio) ((gpio) >> 5) 31#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f) 32 33#define gpio_reg_rmw(reg, mask, val) \ 34 __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg)) 35 36#define gpio_reg_set_bit(reg, gpio) \ 37 gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio)) 38 39#define gpio_reg_clear_bit(reg, gpio) \ 40 gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0) 41 42#define gpio_reg_get_bit(reg, gpio) \ 43 (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio)) 44 45#define chip2controller(chip) \ 46 container_of(chip, struct davinci_gpio_controller, chip) 47 48#define TNETV107X_GPIO_CTLRS DIV_ROUND_UP(TNETV107X_N_GPIO, 32) 49 50static struct davinci_gpio_controller chips[TNETV107X_GPIO_CTLRS]; 51 52static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset) 53{ 54 struct davinci_gpio_controller *ctlr = chip2controller(chip); 55 struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; 56 unsigned gpio = chip->base + offset; 57 unsigned long flags; 58 59 spin_lock_irqsave(&ctlr->lock, flags); 60 61 gpio_reg_set_bit(®s->enable, gpio); 62 63 spin_unlock_irqrestore(&ctlr->lock, flags); 64 65 return 0; 66} 67 68static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset) 69{ 70 struct davinci_gpio_controller *ctlr = chip2controller(chip); 71 struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; 72 unsigned gpio = chip->base + offset; 73 unsigned long flags; 74 75 spin_lock_irqsave(&ctlr->lock, flags); 76 77 gpio_reg_clear_bit(®s->enable, gpio); 78 79 spin_unlock_irqrestore(&ctlr->lock, flags); 80} 81 82static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset) 83{ 84 struct davinci_gpio_controller *ctlr = chip2controller(chip); 85 struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; 86 unsigned gpio = chip->base + offset; 87 unsigned long flags; 88 89 spin_lock_irqsave(&ctlr->lock, flags); 90 91 gpio_reg_set_bit(®s->direction, gpio); 92 93 spin_unlock_irqrestore(&ctlr->lock, flags); 94 95 return 0; 96} 97 98static int tnetv107x_gpio_dir_out(struct gpio_chip *chip, 99 unsigned offset, int value) 100{ 101 struct davinci_gpio_controller *ctlr = chip2controller(chip); 102 struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; 103 unsigned gpio = chip->base + offset; 104 unsigned long flags; 105 106 spin_lock_irqsave(&ctlr->lock, flags); 107 108 if (value) 109 gpio_reg_set_bit(®s->data_out, gpio); 110 else 111 gpio_reg_clear_bit(®s->data_out, gpio); 112 113 gpio_reg_clear_bit(®s->direction, gpio); 114 115 spin_unlock_irqrestore(&ctlr->lock, flags); 116 117 return 0; 118} 119 120static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset) 121{ 122 struct davinci_gpio_controller *ctlr = chip2controller(chip); 123 struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; 124 unsigned gpio = chip->base + offset; 125 int ret; 126 127 ret = gpio_reg_get_bit(®s->data_in, gpio); 128 129 return ret ? 1 : 0; 130} 131 132static void tnetv107x_gpio_set(struct gpio_chip *chip, 133 unsigned offset, int value) 134{ 135 struct davinci_gpio_controller *ctlr = chip2controller(chip); 136 struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; 137 unsigned gpio = chip->base + offset; 138 unsigned long flags; 139 140 spin_lock_irqsave(&ctlr->lock, flags); 141 142 if (value) 143 gpio_reg_set_bit(®s->data_out, gpio); 144 else 145 gpio_reg_clear_bit(®s->data_out, gpio); 146 147 spin_unlock_irqrestore(&ctlr->lock, flags); 148} 149 150static int __init tnetv107x_gpio_setup(void) 151{ 152 int i, base; 153 unsigned ngpio; 154 struct davinci_soc_info *soc_info = &davinci_soc_info; 155 struct tnetv107x_gpio_regs *regs; 156 struct davinci_gpio_controller *ctlr; 157 158 if (soc_info->gpio_type != GPIO_TYPE_TNETV107X) 159 return 0; 160 161 ngpio = soc_info->gpio_num; 162 if (ngpio == 0) { 163 pr_err("GPIO setup: how many GPIOs?\n"); 164 return -EINVAL; 165 } 166 167 if (WARN_ON(TNETV107X_N_GPIO < ngpio)) 168 ngpio = TNETV107X_N_GPIO; 169 170 regs = ioremap(soc_info->gpio_base, SZ_4K); 171 if (WARN_ON(!regs)) 172 return -EINVAL; 173 174 for (i = 0, base = 0; base < ngpio; i++, base += 32) { 175 ctlr = &chips[i]; 176 177 ctlr->chip.label = "tnetv107x"; 178 ctlr->chip.can_sleep = 0; 179 ctlr->chip.base = base; 180 ctlr->chip.ngpio = ngpio - base; 181 if (ctlr->chip.ngpio > 32) 182 ctlr->chip.ngpio = 32; 183 184 ctlr->chip.request = tnetv107x_gpio_request; 185 ctlr->chip.free = tnetv107x_gpio_free; 186 ctlr->chip.direction_input = tnetv107x_gpio_dir_in; 187 ctlr->chip.get = tnetv107x_gpio_get; 188 ctlr->chip.direction_output = tnetv107x_gpio_dir_out; 189 ctlr->chip.set = tnetv107x_gpio_set; 190 191 spin_lock_init(&ctlr->lock); 192 193 ctlr->regs = regs; 194 ctlr->set_data = ®s->data_out[i]; 195 ctlr->clr_data = ®s->data_out[i]; 196 ctlr->in_data = ®s->data_in[i]; 197 198 gpiochip_add(&ctlr->chip); 199 } 200 201 soc_info->gpio_ctlrs = chips; 202 soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); 203 return 0; 204} 205pure_initcall(tnetv107x_gpio_setup); 206