1/* 2 * Allocator for I/O pins. All pins are allocated to GPIO at bootup. 3 * Unassigned pins and GPIO pins can be allocated to a fixed interface 4 * or the I/O processor instead. 5 * 6 * Copyright (c) 2005-2007 Axis Communications AB. 7 */ 8 9#include <linux/init.h> 10#include <linux/errno.h> 11#include <linux/kernel.h> 12#include <linux/string.h> 13#include <linux/spinlock.h> 14#include <hwregs/reg_map.h> 15#include <hwregs/reg_rdwr.h> 16#include <pinmux.h> 17#include <hwregs/pinmux_defs.h> 18#include <hwregs/clkgen_defs.h> 19 20#undef DEBUG 21 22#define PINS 80 23#define PORT_PINS 32 24#define PORTS 3 25 26static char pins[PINS]; 27static DEFINE_SPINLOCK(pinmux_lock); 28 29static void crisv32_pinmux_set(int port); 30 31int 32crisv32_pinmux_init(void) 33{ 34 static int initialized; 35 36 if (!initialized) { 37 initialized = 1; 38 REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0); 39 crisv32_pinmux_alloc(PORT_A, 0, 31, pinmux_gpio); 40 crisv32_pinmux_alloc(PORT_B, 0, 31, pinmux_gpio); 41 crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_gpio); 42 } 43 44 return 0; 45} 46 47int 48crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode) 49{ 50 int i; 51 unsigned long flags; 52 53 crisv32_pinmux_init(); 54 55 if (port >= PORTS) 56 return -EINVAL; 57 58 spin_lock_irqsave(&pinmux_lock, flags); 59 60 for (i = first_pin; i <= last_pin; i++) { 61 if ((pins[port * PORT_PINS + i] != pinmux_none) && 62 (pins[port * PORT_PINS + i] != pinmux_gpio) && 63 (pins[port * PORT_PINS + i] != mode)) { 64 spin_unlock_irqrestore(&pinmux_lock, flags); 65#ifdef DEBUG 66 panic("Pinmux alloc failed!\n"); 67#endif 68 return -EPERM; 69 } 70 } 71 72 for (i = first_pin; i <= last_pin; i++) 73 pins[port * PORT_PINS + i] = mode; 74 75 crisv32_pinmux_set(port); 76 77 spin_unlock_irqrestore(&pinmux_lock, flags); 78 79 return 0; 80} 81 82int 83crisv32_pinmux_alloc_fixed(enum fixed_function function) 84{ 85 int ret = -EINVAL; 86 char saved[sizeof pins]; 87 unsigned long flags; 88 reg_pinmux_rw_hwprot hwprot; 89 reg_clkgen_rw_clk_ctrl clk_ctrl; 90 91 spin_lock_irqsave(&pinmux_lock, flags); 92 93 /* Save internal data for recovery */ 94 memcpy(saved, pins, sizeof pins); 95 96 crisv32_pinmux_init(); /* must be done before we read rw_hwprot */ 97 98 hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); 99 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); 100 101 switch (function) { 102 case pinmux_eth: 103 clk_ctrl.eth = regk_clkgen_yes; 104 clk_ctrl.dma0_1_eth = regk_clkgen_yes; 105 ret = crisv32_pinmux_alloc(PORT_B, 8, 23, pinmux_fixed); 106 ret |= crisv32_pinmux_alloc(PORT_B, 24, 25, pinmux_fixed); 107 hwprot.eth = hwprot.eth_mdio = regk_pinmux_yes; 108 break; 109 case pinmux_geth: 110 ret = crisv32_pinmux_alloc(PORT_B, 0, 7, pinmux_fixed); 111 hwprot.geth = regk_pinmux_yes; 112 break; 113 case pinmux_tg_cmos: 114 clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes; 115 ret = crisv32_pinmux_alloc(PORT_B, 27, 29, pinmux_fixed); 116 hwprot.tg_clk = regk_pinmux_yes; 117 break; 118 case pinmux_tg_ccd: 119 clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes; 120 ret = crisv32_pinmux_alloc(PORT_B, 27, 31, pinmux_fixed); 121 ret |= crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_fixed); 122 hwprot.tg = hwprot.tg_clk = regk_pinmux_yes; 123 break; 124 case pinmux_vout: 125 clk_ctrl.strdma0_2_video = regk_clkgen_yes; 126 ret = crisv32_pinmux_alloc(PORT_A, 8, 18, pinmux_fixed); 127 hwprot.vout = hwprot.vout_sync = regk_pinmux_yes; 128 break; 129 case pinmux_ser1: 130 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 131 ret = crisv32_pinmux_alloc(PORT_A, 24, 25, pinmux_fixed); 132 hwprot.ser1 = regk_pinmux_yes; 133 break; 134 case pinmux_ser2: 135 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 136 ret = crisv32_pinmux_alloc(PORT_A, 26, 27, pinmux_fixed); 137 hwprot.ser2 = regk_pinmux_yes; 138 break; 139 case pinmux_ser3: 140 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 141 ret = crisv32_pinmux_alloc(PORT_A, 28, 29, pinmux_fixed); 142 hwprot.ser3 = regk_pinmux_yes; 143 break; 144 case pinmux_ser4: 145 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 146 ret = crisv32_pinmux_alloc(PORT_A, 30, 31, pinmux_fixed); 147 hwprot.ser4 = regk_pinmux_yes; 148 break; 149 case pinmux_sser: 150 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 151 ret = crisv32_pinmux_alloc(PORT_A, 19, 23, pinmux_fixed); 152 hwprot.sser = regk_pinmux_yes; 153 break; 154 case pinmux_pio: 155 hwprot.pio = regk_pinmux_yes; 156 ret = 0; 157 break; 158 case pinmux_pwm0: 159 ret = crisv32_pinmux_alloc(PORT_A, 30, 30, pinmux_fixed); 160 hwprot.pwm0 = regk_pinmux_yes; 161 break; 162 case pinmux_pwm1: 163 ret = crisv32_pinmux_alloc(PORT_A, 31, 31, pinmux_fixed); 164 hwprot.pwm1 = regk_pinmux_yes; 165 break; 166 case pinmux_pwm2: 167 ret = crisv32_pinmux_alloc(PORT_B, 26, 26, pinmux_fixed); 168 hwprot.pwm2 = regk_pinmux_yes; 169 break; 170 case pinmux_i2c0: 171 ret = crisv32_pinmux_alloc(PORT_A, 0, 1, pinmux_fixed); 172 hwprot.i2c0 = regk_pinmux_yes; 173 break; 174 case pinmux_i2c1: 175 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 176 hwprot.i2c1 = regk_pinmux_yes; 177 break; 178 case pinmux_i2c1_3wire: 179 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 180 ret |= crisv32_pinmux_alloc(PORT_A, 7, 7, pinmux_fixed); 181 hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_yes; 182 break; 183 case pinmux_i2c1_sda1: 184 ret = crisv32_pinmux_alloc(PORT_A, 2, 4, pinmux_fixed); 185 hwprot.i2c1 = hwprot.i2c1_sda1 = regk_pinmux_yes; 186 break; 187 case pinmux_i2c1_sda2: 188 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 189 ret |= crisv32_pinmux_alloc(PORT_A, 5, 5, pinmux_fixed); 190 hwprot.i2c1 = hwprot.i2c1_sda2 = regk_pinmux_yes; 191 break; 192 case pinmux_i2c1_sda3: 193 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 194 ret |= crisv32_pinmux_alloc(PORT_A, 6, 6, pinmux_fixed); 195 hwprot.i2c1 = hwprot.i2c1_sda3 = regk_pinmux_yes; 196 break; 197 default: 198 ret = -EINVAL; 199 break; 200 } 201 202 if (!ret) { 203 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); 204 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); 205 } else 206 memcpy(pins, saved, sizeof pins); 207 208 spin_unlock_irqrestore(&pinmux_lock, flags); 209 210 return ret; 211} 212 213void 214crisv32_pinmux_set(int port) 215{ 216 int i; 217 int gpio_val = 0; 218 int iop_val = 0; 219 int pin = port * PORT_PINS; 220 221 for (i = 0; (i < PORT_PINS) && (pin < PINS); i++, pin++) { 222 if (pins[pin] == pinmux_gpio) 223 gpio_val |= (1 << i); 224 else if (pins[pin] == pinmux_iop) 225 iop_val |= (1 << i); 226 } 227 228 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_gio_pa + 4 * port, 229 gpio_val); 230 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_iop_pa + 4 * port, 231 iop_val); 232 233#ifdef DEBUG 234 crisv32_pinmux_dump(); 235#endif 236} 237 238int 239crisv32_pinmux_dealloc(int port, int first_pin, int last_pin) 240{ 241 int i; 242 unsigned long flags; 243 244 crisv32_pinmux_init(); 245 246 if (port > PORTS || port < 0) 247 return -EINVAL; 248 249 spin_lock_irqsave(&pinmux_lock, flags); 250 251 for (i = first_pin; i <= last_pin; i++) 252 pins[port * PORT_PINS + i] = pinmux_none; 253 254 crisv32_pinmux_set(port); 255 spin_unlock_irqrestore(&pinmux_lock, flags); 256 257 return 0; 258} 259 260int 261crisv32_pinmux_dealloc_fixed(enum fixed_function function) 262{ 263 int ret = -EINVAL; 264 char saved[sizeof pins]; 265 unsigned long flags; 266 reg_pinmux_rw_hwprot hwprot; 267 268 spin_lock_irqsave(&pinmux_lock, flags); 269 270 /* Save internal data for recovery */ 271 memcpy(saved, pins, sizeof pins); 272 273 crisv32_pinmux_init(); /* must be done before we read rw_hwprot */ 274 275 hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); 276 277 switch (function) { 278 case pinmux_eth: 279 ret = crisv32_pinmux_dealloc(PORT_B, 8, 23); 280 ret |= crisv32_pinmux_dealloc(PORT_B, 24, 25); 281 ret |= crisv32_pinmux_dealloc(PORT_B, 0, 7); 282 hwprot.eth = hwprot.eth_mdio = hwprot.geth = regk_pinmux_no; 283 break; 284 case pinmux_tg_cmos: 285 ret = crisv32_pinmux_dealloc(PORT_B, 27, 29); 286 hwprot.tg_clk = regk_pinmux_no; 287 break; 288 case pinmux_tg_ccd: 289 ret = crisv32_pinmux_dealloc(PORT_B, 27, 31); 290 ret |= crisv32_pinmux_dealloc(PORT_C, 0, 15); 291 hwprot.tg = hwprot.tg_clk = regk_pinmux_no; 292 break; 293 case pinmux_vout: 294 ret = crisv32_pinmux_dealloc(PORT_A, 8, 18); 295 hwprot.vout = hwprot.vout_sync = regk_pinmux_no; 296 break; 297 case pinmux_ser1: 298 ret = crisv32_pinmux_dealloc(PORT_A, 24, 25); 299 hwprot.ser1 = regk_pinmux_no; 300 break; 301 case pinmux_ser2: 302 ret = crisv32_pinmux_dealloc(PORT_A, 26, 27); 303 hwprot.ser2 = regk_pinmux_no; 304 break; 305 case pinmux_ser3: 306 ret = crisv32_pinmux_dealloc(PORT_A, 28, 29); 307 hwprot.ser3 = regk_pinmux_no; 308 break; 309 case pinmux_ser4: 310 ret = crisv32_pinmux_dealloc(PORT_A, 30, 31); 311 hwprot.ser4 = regk_pinmux_no; 312 break; 313 case pinmux_sser: 314 ret = crisv32_pinmux_dealloc(PORT_A, 19, 23); 315 hwprot.sser = regk_pinmux_no; 316 break; 317 case pinmux_pwm0: 318 ret = crisv32_pinmux_dealloc(PORT_A, 30, 30); 319 hwprot.pwm0 = regk_pinmux_no; 320 break; 321 case pinmux_pwm1: 322 ret = crisv32_pinmux_dealloc(PORT_A, 31, 31); 323 hwprot.pwm1 = regk_pinmux_no; 324 break; 325 case pinmux_pwm2: 326 ret = crisv32_pinmux_dealloc(PORT_B, 26, 26); 327 hwprot.pwm2 = regk_pinmux_no; 328 break; 329 case pinmux_i2c0: 330 ret = crisv32_pinmux_dealloc(PORT_A, 0, 1); 331 hwprot.i2c0 = regk_pinmux_no; 332 break; 333 case pinmux_i2c1: 334 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 335 hwprot.i2c1 = regk_pinmux_no; 336 break; 337 case pinmux_i2c1_3wire: 338 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 339 ret |= crisv32_pinmux_dealloc(PORT_A, 7, 7); 340 hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_no; 341 break; 342 case pinmux_i2c1_sda1: 343 ret = crisv32_pinmux_dealloc(PORT_A, 2, 4); 344 hwprot.i2c1_sda1 = regk_pinmux_no; 345 break; 346 case pinmux_i2c1_sda2: 347 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 348 ret |= crisv32_pinmux_dealloc(PORT_A, 5, 5); 349 hwprot.i2c1_sda2 = regk_pinmux_no; 350 break; 351 case pinmux_i2c1_sda3: 352 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 353 ret |= crisv32_pinmux_dealloc(PORT_A, 6, 6); 354 hwprot.i2c1_sda3 = regk_pinmux_no; 355 break; 356 default: 357 ret = -EINVAL; 358 break; 359 } 360 361 if (!ret) 362 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); 363 else 364 memcpy(pins, saved, sizeof pins); 365 366 spin_unlock_irqrestore(&pinmux_lock, flags); 367 368 return ret; 369} 370 371void 372crisv32_pinmux_dump(void) 373{ 374 int i, j; 375 int pin = 0; 376 377 crisv32_pinmux_init(); 378 379 for (i = 0; i < PORTS; i++) { 380 pin++; 381 printk(KERN_DEBUG "Port %c\n", 'A'+i); 382 for (j = 0; (j < PORT_PINS) && (pin < PINS); j++, pin++) 383 printk(KERN_DEBUG 384 " Pin %d = %d\n", j, pins[i * PORT_PINS + j]); 385 } 386} 387 388__initcall(crisv32_pinmux_init); 389