1/* 2 * Coldfire generic GPIO support 3 * 4 * (C) Copyright 2009, Steven King <sfking@fdwdc.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14*/ 15 16#include <linux/kernel.h> 17#include <linux/init.h> 18 19#include <asm/coldfire.h> 20#include <asm/mcfsim.h> 21#include <asm/mcfgpio.h> 22 23static struct mcf_gpio_chip mcf_gpio_chips[] = { 24 { 25 .gpio_chip = { 26 .label = "PIRQ", 27 .request = mcf_gpio_request, 28 .free = mcf_gpio_free, 29 .direction_input = mcf_gpio_direction_input, 30 .direction_output = mcf_gpio_direction_output, 31 .get = mcf_gpio_get_value, 32 .set = mcf_gpio_set_value, 33 .ngpio = 8, 34 }, 35 .pddr = (void __iomem *) MCFEPORT_EPDDR, 36 .podr = (void __iomem *) MCFEPORT_EPDR, 37 .ppdr = (void __iomem *) MCFEPORT_EPPDR, 38 }, 39 { 40 .gpio_chip = { 41 .label = "FECH", 42 .request = mcf_gpio_request, 43 .free = mcf_gpio_free, 44 .direction_input = mcf_gpio_direction_input, 45 .direction_output = mcf_gpio_direction_output, 46 .get = mcf_gpio_get_value, 47 .set = mcf_gpio_set_value_fast, 48 .base = 8, 49 .ngpio = 8, 50 }, 51 .pddr = (void __iomem *) MCFGPIO_PDDR_FECH, 52 .podr = (void __iomem *) MCFGPIO_PODR_FECH, 53 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECH, 54 .setr = (void __iomem *) MCFGPIO_PPDSDR_FECH, 55 .clrr = (void __iomem *) MCFGPIO_PCLRR_FECH, 56 }, 57 { 58 .gpio_chip = { 59 .label = "FECL", 60 .request = mcf_gpio_request, 61 .free = mcf_gpio_free, 62 .direction_input = mcf_gpio_direction_input, 63 .direction_output = mcf_gpio_direction_output, 64 .get = mcf_gpio_get_value, 65 .set = mcf_gpio_set_value_fast, 66 .base = 16, 67 .ngpio = 8, 68 }, 69 .pddr = (void __iomem *) MCFGPIO_PDDR_FECL, 70 .podr = (void __iomem *) MCFGPIO_PODR_FECL, 71 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECL, 72 .setr = (void __iomem *) MCFGPIO_PPDSDR_FECL, 73 .clrr = (void __iomem *) MCFGPIO_PCLRR_FECL, 74 }, 75 { 76 .gpio_chip = { 77 .label = "SSI", 78 .request = mcf_gpio_request, 79 .free = mcf_gpio_free, 80 .direction_input = mcf_gpio_direction_input, 81 .direction_output = mcf_gpio_direction_output, 82 .get = mcf_gpio_get_value, 83 .set = mcf_gpio_set_value_fast, 84 .base = 24, 85 .ngpio = 5, 86 }, 87 .pddr = (void __iomem *) MCFGPIO_PDDR_SSI, 88 .podr = (void __iomem *) MCFGPIO_PODR_SSI, 89 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_SSI, 90 .setr = (void __iomem *) MCFGPIO_PPDSDR_SSI, 91 .clrr = (void __iomem *) MCFGPIO_PCLRR_SSI, 92 }, 93 { 94 .gpio_chip = { 95 .label = "BUSCTL", 96 .request = mcf_gpio_request, 97 .free = mcf_gpio_free, 98 .direction_input = mcf_gpio_direction_input, 99 .direction_output = mcf_gpio_direction_output, 100 .get = mcf_gpio_get_value, 101 .set = mcf_gpio_set_value_fast, 102 .base = 32, 103 .ngpio = 4, 104 }, 105 .pddr = (void __iomem *) MCFGPIO_PDDR_BUSCTL, 106 .podr = (void __iomem *) MCFGPIO_PODR_BUSCTL, 107 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, 108 .setr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL, 109 .clrr = (void __iomem *) MCFGPIO_PCLRR_BUSCTL, 110 }, 111 { 112 .gpio_chip = { 113 .label = "BE", 114 .request = mcf_gpio_request, 115 .free = mcf_gpio_free, 116 .direction_input = mcf_gpio_direction_input, 117 .direction_output = mcf_gpio_direction_output, 118 .get = mcf_gpio_get_value, 119 .set = mcf_gpio_set_value_fast, 120 .base = 40, 121 .ngpio = 4, 122 }, 123 .pddr = (void __iomem *) MCFGPIO_PDDR_BE, 124 .podr = (void __iomem *) MCFGPIO_PODR_BE, 125 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_BE, 126 .setr = (void __iomem *) MCFGPIO_PPDSDR_BE, 127 .clrr = (void __iomem *) MCFGPIO_PCLRR_BE, 128 }, 129 { 130 .gpio_chip = { 131 .label = "CS", 132 .request = mcf_gpio_request, 133 .free = mcf_gpio_free, 134 .direction_input = mcf_gpio_direction_input, 135 .direction_output = mcf_gpio_direction_output, 136 .get = mcf_gpio_get_value, 137 .set = mcf_gpio_set_value_fast, 138 .base = 49, 139 .ngpio = 5, 140 }, 141 .pddr = (void __iomem *) MCFGPIO_PDDR_CS, 142 .podr = (void __iomem *) MCFGPIO_PODR_CS, 143 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_CS, 144 .setr = (void __iomem *) MCFGPIO_PPDSDR_CS, 145 .clrr = (void __iomem *) MCFGPIO_PCLRR_CS, 146 }, 147 { 148 .gpio_chip = { 149 .label = "PWM", 150 .request = mcf_gpio_request, 151 .free = mcf_gpio_free, 152 .direction_input = mcf_gpio_direction_input, 153 .direction_output = mcf_gpio_direction_output, 154 .get = mcf_gpio_get_value, 155 .set = mcf_gpio_set_value_fast, 156 .base = 58, 157 .ngpio = 4, 158 }, 159 .pddr = (void __iomem *) MCFGPIO_PDDR_PWM, 160 .podr = (void __iomem *) MCFGPIO_PODR_PWM, 161 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_PWM, 162 .setr = (void __iomem *) MCFGPIO_PPDSDR_PWM, 163 .clrr = (void __iomem *) MCFGPIO_PCLRR_PWM, 164 }, 165 { 166 .gpio_chip = { 167 .label = "FECI2C", 168 .request = mcf_gpio_request, 169 .free = mcf_gpio_free, 170 .direction_input = mcf_gpio_direction_input, 171 .direction_output = mcf_gpio_direction_output, 172 .get = mcf_gpio_get_value, 173 .set = mcf_gpio_set_value_fast, 174 .base = 64, 175 .ngpio = 4, 176 }, 177 .pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C, 178 .podr = (void __iomem *) MCFGPIO_PODR_FECI2C, 179 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, 180 .setr = (void __iomem *) MCFGPIO_PPDSDR_FECI2C, 181 .clrr = (void __iomem *) MCFGPIO_PCLRR_FECI2C, 182 }, 183 { 184 .gpio_chip = { 185 .label = "UART", 186 .request = mcf_gpio_request, 187 .free = mcf_gpio_free, 188 .direction_input = mcf_gpio_direction_input, 189 .direction_output = mcf_gpio_direction_output, 190 .get = mcf_gpio_get_value, 191 .set = mcf_gpio_set_value_fast, 192 .base = 72, 193 .ngpio = 8, 194 }, 195 .pddr = (void __iomem *) MCFGPIO_PDDR_UART, 196 .podr = (void __iomem *) MCFGPIO_PODR_UART, 197 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_UART, 198 .setr = (void __iomem *) MCFGPIO_PPDSDR_UART, 199 .clrr = (void __iomem *) MCFGPIO_PCLRR_UART, 200 }, 201 { 202 .gpio_chip = { 203 .label = "QSPI", 204 .request = mcf_gpio_request, 205 .free = mcf_gpio_free, 206 .direction_input = mcf_gpio_direction_input, 207 .direction_output = mcf_gpio_direction_output, 208 .get = mcf_gpio_get_value, 209 .set = mcf_gpio_set_value_fast, 210 .base = 80, 211 .ngpio = 6, 212 }, 213 .pddr = (void __iomem *) MCFGPIO_PDDR_QSPI, 214 .podr = (void __iomem *) MCFGPIO_PODR_QSPI, 215 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, 216 .setr = (void __iomem *) MCFGPIO_PPDSDR_QSPI, 217 .clrr = (void __iomem *) MCFGPIO_PCLRR_QSPI, 218 }, 219 { 220 .gpio_chip = { 221 .label = "TIMER", 222 .request = mcf_gpio_request, 223 .free = mcf_gpio_free, 224 .direction_input = mcf_gpio_direction_input, 225 .direction_output = mcf_gpio_direction_output, 226 .get = mcf_gpio_get_value, 227 .set = mcf_gpio_set_value_fast, 228 .base = 88, 229 .ngpio = 4, 230 }, 231 .pddr = (void __iomem *) MCFGPIO_PDDR_TIMER, 232 .podr = (void __iomem *) MCFGPIO_PODR_TIMER, 233 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, 234 .setr = (void __iomem *) MCFGPIO_PPDSDR_TIMER, 235 .clrr = (void __iomem *) MCFGPIO_PCLRR_TIMER, 236 }, 237 { 238 .gpio_chip = { 239 .label = "LCDDATAH", 240 .request = mcf_gpio_request, 241 .free = mcf_gpio_free, 242 .direction_input = mcf_gpio_direction_input, 243 .direction_output = mcf_gpio_direction_output, 244 .get = mcf_gpio_get_value, 245 .set = mcf_gpio_set_value_fast, 246 .base = 96, 247 .ngpio = 2, 248 }, 249 .pddr = (void __iomem *) MCFGPIO_PDDR_LCDDATAH, 250 .podr = (void __iomem *) MCFGPIO_PODR_LCDDATAH, 251 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAH, 252 .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAH, 253 .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDDATAH, 254 }, 255 { 256 .gpio_chip = { 257 .label = "LCDDATAM", 258 .request = mcf_gpio_request, 259 .free = mcf_gpio_free, 260 .direction_input = mcf_gpio_direction_input, 261 .direction_output = mcf_gpio_direction_output, 262 .get = mcf_gpio_get_value, 263 .set = mcf_gpio_set_value_fast, 264 .base = 104, 265 .ngpio = 8, 266 }, 267 .pddr = (void __iomem *) MCFGPIO_PDDR_LCDDATAM, 268 .podr = (void __iomem *) MCFGPIO_PODR_LCDDATAM, 269 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAM, 270 .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAM, 271 .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDDATAM, 272 }, 273 { 274 .gpio_chip = { 275 .label = "LCDDATAL", 276 .request = mcf_gpio_request, 277 .free = mcf_gpio_free, 278 .direction_input = mcf_gpio_direction_input, 279 .direction_output = mcf_gpio_direction_output, 280 .get = mcf_gpio_get_value, 281 .set = mcf_gpio_set_value_fast, 282 .base = 112, 283 .ngpio = 8, 284 }, 285 .pddr = (void __iomem *) MCFGPIO_PDDR_LCDDATAL, 286 .podr = (void __iomem *) MCFGPIO_PODR_LCDDATAL, 287 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAL, 288 .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDDATAL, 289 .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDDATAL, 290 }, 291 { 292 .gpio_chip = { 293 .label = "LCDCTLH", 294 .request = mcf_gpio_request, 295 .free = mcf_gpio_free, 296 .direction_input = mcf_gpio_direction_input, 297 .direction_output = mcf_gpio_direction_output, 298 .get = mcf_gpio_get_value, 299 .set = mcf_gpio_set_value_fast, 300 .base = 120, 301 .ngpio = 1, 302 }, 303 .pddr = (void __iomem *) MCFGPIO_PDDR_LCDCTLH, 304 .podr = (void __iomem *) MCFGPIO_PODR_LCDCTLH, 305 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLH, 306 .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLH, 307 .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDCTLH, 308 }, 309 { 310 .gpio_chip = { 311 .label = "LCDCTLL", 312 .request = mcf_gpio_request, 313 .free = mcf_gpio_free, 314 .direction_input = mcf_gpio_direction_input, 315 .direction_output = mcf_gpio_direction_output, 316 .get = mcf_gpio_get_value, 317 .set = mcf_gpio_set_value_fast, 318 .base = 128, 319 .ngpio = 8, 320 }, 321 .pddr = (void __iomem *) MCFGPIO_PDDR_LCDCTLL, 322 .podr = (void __iomem *) MCFGPIO_PODR_LCDCTLL, 323 .ppdr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLL, 324 .setr = (void __iomem *) MCFGPIO_PPDSDR_LCDCTLL, 325 .clrr = (void __iomem *) MCFGPIO_PCLRR_LCDCTLL, 326 }, 327}; 328 329static int __init mcf_gpio_init(void) 330{ 331 unsigned i = 0; 332 while (i < ARRAY_SIZE(mcf_gpio_chips)) 333 (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); 334 return 0; 335} 336 337core_initcall(mcf_gpio_init); 338