diff options
| author | Kevin Hilman <khilman@ti.com> | 2011-04-20 19:31:23 -0400 |
|---|---|---|
| committer | Kevin Hilman <khilman@ti.com> | 2011-06-16 14:13:42 -0400 |
| commit | fa87931acb8203a1f40a3c637863ad238f70cd40 (patch) | |
| tree | fd79e56fb9819bbb1096c9d3904f0ba04bec832a /drivers/gpio/gpio-omap.c | |
| parent | a8be8dafd00e3ccf4f85e2f30babf42be5076324 (diff) | |
gpio/omap: consolidate direction, input, output, remove #ifdefs
Add register offset fields to GPIO platform_data for registers.
This patch adds registers that control direction, input and output
data. Using these register offsets in the common driver allows
removal of #ifdefs and greatly improves readability.
Also create dedicated data out functions: one for banks with dedicated
set/clear registers, and another for banks with a single mask
register.
Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/gpio/gpio-omap.c')
| -rw-r--r-- | drivers/gpio/gpio-omap.c | 243 |
1 files changed, 43 insertions, 200 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 25a7ee6bddb0..945642143e1b 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -55,6 +55,10 @@ struct gpio_bank { | |||
| 55 | bool dbck_flag; | 55 | bool dbck_flag; |
| 56 | int stride; | 56 | int stride; |
| 57 | u32 width; | 57 | u32 width; |
| 58 | |||
| 59 | void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable); | ||
| 60 | |||
| 61 | struct omap_gpio_reg_offs *regs; | ||
| 58 | }; | 62 | }; |
| 59 | 63 | ||
| 60 | #ifdef CONFIG_ARCH_OMAP3 | 64 | #ifdef CONFIG_ARCH_OMAP3 |
| @@ -125,41 +129,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | |||
| 125 | void __iomem *reg = bank->base; | 129 | void __iomem *reg = bank->base; |
| 126 | u32 l; | 130 | u32 l; |
| 127 | 131 | ||
| 128 | switch (bank->method) { | 132 | reg += bank->regs->direction; |
| 129 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 130 | case METHOD_MPUIO: | ||
| 131 | reg += OMAP_MPUIO_IO_CNTL / bank->stride; | ||
| 132 | break; | ||
| 133 | #endif | ||
| 134 | #ifdef CONFIG_ARCH_OMAP15XX | ||
| 135 | case METHOD_GPIO_1510: | ||
| 136 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
| 137 | break; | ||
| 138 | #endif | ||
| 139 | #ifdef CONFIG_ARCH_OMAP16XX | ||
| 140 | case METHOD_GPIO_1610: | ||
| 141 | reg += OMAP1610_GPIO_DIRECTION; | ||
| 142 | break; | ||
| 143 | #endif | ||
| 144 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
| 145 | case METHOD_GPIO_7XX: | ||
| 146 | reg += OMAP7XX_GPIO_DIR_CONTROL; | ||
| 147 | break; | ||
| 148 | #endif | ||
| 149 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
| 150 | case METHOD_GPIO_24XX: | ||
| 151 | reg += OMAP24XX_GPIO_OE; | ||
| 152 | break; | ||
| 153 | #endif | ||
| 154 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 155 | case METHOD_GPIO_44XX: | ||
| 156 | reg += OMAP4_GPIO_OE; | ||
| 157 | break; | ||
| 158 | #endif | ||
| 159 | default: | ||
| 160 | WARN_ON(1); | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | l = __raw_readl(reg); | 133 | l = __raw_readl(reg); |
| 164 | if (is_input) | 134 | if (is_input) |
| 165 | l |= 1 << gpio; | 135 | l |= 1 << gpio; |
| @@ -168,163 +138,52 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | |||
| 168 | __raw_writel(l, reg); | 138 | __raw_writel(l, reg); |
| 169 | } | 139 | } |
| 170 | 140 | ||
| 171 | static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | 141 | |
| 142 | /* set data out value using dedicate set/clear register */ | ||
| 143 | static void _set_gpio_dataout_reg(struct gpio_bank *bank, int gpio, int enable) | ||
| 172 | { | 144 | { |
| 173 | void __iomem *reg = bank->base; | 145 | void __iomem *reg = bank->base; |
| 174 | u32 l = 0; | 146 | u32 l = GPIO_BIT(bank, gpio); |
| 175 | 147 | ||
| 176 | switch (bank->method) { | 148 | if (enable) |
| 177 | #ifdef CONFIG_ARCH_OMAP1 | 149 | reg += bank->regs->set_dataout; |
| 178 | case METHOD_MPUIO: | 150 | else |
| 179 | reg += OMAP_MPUIO_OUTPUT / bank->stride; | 151 | reg += bank->regs->clr_dataout; |
| 180 | l = __raw_readl(reg); | 152 | |
| 181 | if (enable) | 153 | __raw_writel(l, reg); |
| 182 | l |= 1 << gpio; | 154 | } |
| 183 | else | 155 | |
| 184 | l &= ~(1 << gpio); | 156 | /* set data out value using mask register */ |
| 185 | break; | 157 | static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable) |
| 186 | #endif | 158 | { |
| 187 | #ifdef CONFIG_ARCH_OMAP15XX | 159 | void __iomem *reg = bank->base + bank->regs->dataout; |
| 188 | case METHOD_GPIO_1510: | 160 | u32 gpio_bit = GPIO_BIT(bank, gpio); |
| 189 | reg += OMAP1510_GPIO_DATA_OUTPUT; | 161 | u32 l; |
| 190 | l = __raw_readl(reg); | 162 | |
| 191 | if (enable) | 163 | l = __raw_readl(reg); |
| 192 | l |= 1 << gpio; | 164 | if (enable) |
| 193 | else | 165 | l |= gpio_bit; |
| 194 | l &= ~(1 << gpio); | 166 | else |
| 195 | break; | 167 | l &= ~gpio_bit; |
| 196 | #endif | ||
| 197 | #ifdef CONFIG_ARCH_OMAP16XX | ||
| 198 | case METHOD_GPIO_1610: | ||
| 199 | if (enable) | ||
| 200 | reg += OMAP1610_GPIO_SET_DATAOUT; | ||
| 201 | else | ||
| 202 | reg += OMAP1610_GPIO_CLEAR_DATAOUT; | ||
| 203 | l = 1 << gpio; | ||
| 204 | break; | ||
| 205 | #endif | ||
| 206 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
| 207 | case METHOD_GPIO_7XX: | ||
| 208 | reg += OMAP7XX_GPIO_DATA_OUTPUT; | ||
| 209 | l = __raw_readl(reg); | ||
| 210 | if (enable) | ||
| 211 | l |= 1 << gpio; | ||
| 212 | else | ||
| 213 | l &= ~(1 << gpio); | ||
| 214 | break; | ||
| 215 | #endif | ||
| 216 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
| 217 | case METHOD_GPIO_24XX: | ||
| 218 | if (enable) | ||
| 219 | reg += OMAP24XX_GPIO_SETDATAOUT; | ||
| 220 | else | ||
| 221 | reg += OMAP24XX_GPIO_CLEARDATAOUT; | ||
| 222 | l = 1 << gpio; | ||
| 223 | break; | ||
| 224 | #endif | ||
| 225 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 226 | case METHOD_GPIO_44XX: | ||
| 227 | if (enable) | ||
| 228 | reg += OMAP4_GPIO_SETDATAOUT; | ||
| 229 | else | ||
| 230 | reg += OMAP4_GPIO_CLEARDATAOUT; | ||
| 231 | l = 1 << gpio; | ||
| 232 | break; | ||
| 233 | #endif | ||
| 234 | default: | ||
| 235 | WARN_ON(1); | ||
| 236 | return; | ||
| 237 | } | ||
| 238 | __raw_writel(l, reg); | 168 | __raw_writel(l, reg); |
| 239 | } | 169 | } |
| 240 | 170 | ||
| 241 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) | 171 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) |
| 242 | { | 172 | { |
| 243 | void __iomem *reg; | 173 | void __iomem *reg = bank->base + bank->regs->datain; |
| 244 | 174 | ||
| 245 | if (check_gpio(gpio) < 0) | 175 | if (check_gpio(gpio) < 0) |
| 246 | return -EINVAL; | 176 | return -EINVAL; |
| 247 | reg = bank->base; | 177 | |
| 248 | switch (bank->method) { | 178 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
| 249 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 250 | case METHOD_MPUIO: | ||
| 251 | reg += OMAP_MPUIO_INPUT_LATCH / bank->stride; | ||
| 252 | break; | ||
| 253 | #endif | ||
| 254 | #ifdef CONFIG_ARCH_OMAP15XX | ||
| 255 | case METHOD_GPIO_1510: | ||
| 256 | reg += OMAP1510_GPIO_DATA_INPUT; | ||
| 257 | break; | ||
| 258 | #endif | ||
| 259 | #ifdef CONFIG_ARCH_OMAP16XX | ||
| 260 | case METHOD_GPIO_1610: | ||
| 261 | reg += OMAP1610_GPIO_DATAIN; | ||
| 262 | break; | ||
| 263 | #endif | ||
| 264 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
| 265 | case METHOD_GPIO_7XX: | ||
| 266 | reg += OMAP7XX_GPIO_DATA_INPUT; | ||
| 267 | break; | ||
| 268 | #endif | ||
| 269 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
| 270 | case METHOD_GPIO_24XX: | ||
| 271 | reg += OMAP24XX_GPIO_DATAIN; | ||
| 272 | break; | ||
| 273 | #endif | ||
| 274 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 275 | case METHOD_GPIO_44XX: | ||
| 276 | reg += OMAP4_GPIO_DATAIN; | ||
| 277 | break; | ||
| 278 | #endif | ||
| 279 | default: | ||
| 280 | return -EINVAL; | ||
| 281 | } | ||
| 282 | return (__raw_readl(reg) | ||
| 283 | & (GPIO_BIT(bank, gpio))) != 0; | ||
| 284 | } | 179 | } |
| 285 | 180 | ||
| 286 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | 181 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) |
| 287 | { | 182 | { |
| 288 | void __iomem *reg; | 183 | void __iomem *reg = bank->base + bank->regs->dataout; |
| 289 | 184 | ||
| 290 | if (check_gpio(gpio) < 0) | 185 | if (check_gpio(gpio) < 0) |
| 291 | return -EINVAL; | 186 | return -EINVAL; |
| 292 | reg = bank->base; | ||
| 293 | |||
| 294 | switch (bank->method) { | ||
| 295 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 296 | case METHOD_MPUIO: | ||
| 297 | reg += OMAP_MPUIO_OUTPUT / bank->stride; | ||
| 298 | break; | ||
| 299 | #endif | ||
| 300 | #ifdef CONFIG_ARCH_OMAP15XX | ||
| 301 | case METHOD_GPIO_1510: | ||
| 302 | reg += OMAP1510_GPIO_DATA_OUTPUT; | ||
| 303 | break; | ||
| 304 | #endif | ||
| 305 | #ifdef CONFIG_ARCH_OMAP16XX | ||
| 306 | case METHOD_GPIO_1610: | ||
| 307 | reg += OMAP1610_GPIO_DATAOUT; | ||
| 308 | break; | ||
| 309 | #endif | ||
| 310 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | ||
| 311 | case METHOD_GPIO_7XX: | ||
| 312 | reg += OMAP7XX_GPIO_DATA_OUTPUT; | ||
| 313 | break; | ||
| 314 | #endif | ||
| 315 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
| 316 | case METHOD_GPIO_24XX: | ||
| 317 | reg += OMAP24XX_GPIO_DATAOUT; | ||
| 318 | break; | ||
| 319 | #endif | ||
| 320 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 321 | case METHOD_GPIO_44XX: | ||
| 322 | reg += OMAP4_GPIO_DATAOUT; | ||
| 323 | break; | ||
| 324 | #endif | ||
| 325 | default: | ||
| 326 | return -EINVAL; | ||
| 327 | } | ||
| 328 | 187 | ||
| 329 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; | 188 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
| 330 | } | 189 | } |
| @@ -1281,31 +1140,8 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
| 1281 | 1140 | ||
| 1282 | static int gpio_is_input(struct gpio_bank *bank, int mask) | 1141 | static int gpio_is_input(struct gpio_bank *bank, int mask) |
| 1283 | { | 1142 | { |
| 1284 | void __iomem *reg = bank->base; | 1143 | void __iomem *reg = bank->base + bank->regs->direction; |
| 1285 | 1144 | ||
| 1286 | switch (bank->method) { | ||
| 1287 | case METHOD_MPUIO: | ||
| 1288 | reg += OMAP_MPUIO_IO_CNTL / bank->stride; | ||
| 1289 | break; | ||
| 1290 | case METHOD_GPIO_1510: | ||
| 1291 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
| 1292 | break; | ||
| 1293 | case METHOD_GPIO_1610: | ||
| 1294 | reg += OMAP1610_GPIO_DIRECTION; | ||
| 1295 | break; | ||
| 1296 | case METHOD_GPIO_7XX: | ||
| 1297 | reg += OMAP7XX_GPIO_DIR_CONTROL; | ||
| 1298 | break; | ||
| 1299 | case METHOD_GPIO_24XX: | ||
| 1300 | reg += OMAP24XX_GPIO_OE; | ||
| 1301 | break; | ||
| 1302 | case METHOD_GPIO_44XX: | ||
| 1303 | reg += OMAP4_GPIO_OE; | ||
| 1304 | break; | ||
| 1305 | default: | ||
| 1306 | WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method"); | ||
| 1307 | return -EINVAL; | ||
| 1308 | } | ||
| 1309 | return __raw_readl(reg) & mask; | 1145 | return __raw_readl(reg) & mask; |
| 1310 | } | 1146 | } |
| 1311 | 1147 | ||
| @@ -1334,7 +1170,7 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | |||
| 1334 | 1170 | ||
| 1335 | bank = container_of(chip, struct gpio_bank, chip); | 1171 | bank = container_of(chip, struct gpio_bank, chip); |
| 1336 | spin_lock_irqsave(&bank->lock, flags); | 1172 | spin_lock_irqsave(&bank->lock, flags); |
| 1337 | _set_gpio_dataout(bank, offset, value); | 1173 | bank->set_dataout(bank, offset, value); |
| 1338 | _set_gpio_direction(bank, offset, 0); | 1174 | _set_gpio_direction(bank, offset, 0); |
| 1339 | spin_unlock_irqrestore(&bank->lock, flags); | 1175 | spin_unlock_irqrestore(&bank->lock, flags); |
| 1340 | return 0; | 1176 | return 0; |
| @@ -1368,7 +1204,7 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
| 1368 | 1204 | ||
| 1369 | bank = container_of(chip, struct gpio_bank, chip); | 1205 | bank = container_of(chip, struct gpio_bank, chip); |
| 1370 | spin_lock_irqsave(&bank->lock, flags); | 1206 | spin_lock_irqsave(&bank->lock, flags); |
| 1371 | _set_gpio_dataout(bank, offset, value); | 1207 | bank->set_dataout(bank, offset, value); |
| 1372 | spin_unlock_irqrestore(&bank->lock, flags); | 1208 | spin_unlock_irqrestore(&bank->lock, flags); |
| 1373 | } | 1209 | } |
| 1374 | 1210 | ||
| @@ -1564,6 +1400,13 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
| 1564 | bank->stride = pdata->bank_stride; | 1400 | bank->stride = pdata->bank_stride; |
| 1565 | bank->width = pdata->bank_width; | 1401 | bank->width = pdata->bank_width; |
| 1566 | 1402 | ||
| 1403 | bank->regs = pdata->regs; | ||
| 1404 | |||
| 1405 | if (bank->regs->set_dataout && bank->regs->clr_dataout) | ||
| 1406 | bank->set_dataout = _set_gpio_dataout_reg; | ||
| 1407 | else | ||
| 1408 | bank->set_dataout = _set_gpio_dataout_mask; | ||
| 1409 | |||
| 1567 | spin_lock_init(&bank->lock); | 1410 | spin_lock_init(&bank->lock); |
| 1568 | 1411 | ||
| 1569 | /* Static mapping, never released */ | 1412 | /* Static mapping, never released */ |
