pinmux.c revision 035e111f9a9b29843bc899f03d56f19d94bebb53
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 89 spin_lock_irqsave(&pinmux_lock, flags); 90 91 /* Save internal data for recovery */ 92 memcpy(saved, pins, sizeof pins); 93 94 crisv32_pinmux_init(); /* must be done before we read rw_hwprot */ 95 96 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); 97 reg_clkgen_rw_clk_ctrl clk_ctrl = REG_RD(clkgen, regi_clkgen, 98 rw_clk_ctrl); 99 100 switch (function) { 101 case pinmux_eth: 102 clk_ctrl.eth = regk_clkgen_yes; 103 clk_ctrl.dma0_1_eth = regk_clkgen_yes; 104 ret = crisv32_pinmux_alloc(PORT_B, 8, 23, pinmux_fixed); 105 ret |= crisv32_pinmux_alloc(PORT_B, 24, 25, pinmux_fixed); 106 hwprot.eth = hwprot.eth_mdio = regk_pinmux_yes; 107 break; 108 case pinmux_geth: 109 ret = crisv32_pinmux_alloc(PORT_B, 0, 7, pinmux_fixed); 110 hwprot.geth = regk_pinmux_yes; 111 break; 112 case pinmux_tg_cmos: 113 clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes; 114 ret = crisv32_pinmux_alloc(PORT_B, 27, 29, pinmux_fixed); 115 hwprot.tg_clk = regk_pinmux_yes; 116 break; 117 case pinmux_tg_ccd: 118 clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes; 119 ret = crisv32_pinmux_alloc(PORT_B, 27, 31, pinmux_fixed); 120 ret |= crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_fixed); 121 hwprot.tg = hwprot.tg_clk = regk_pinmux_yes; 122 break; 123 case pinmux_vout: 124 clk_ctrl.strdma0_2_video = regk_clkgen_yes; 125 ret = crisv32_pinmux_alloc(PORT_A, 8, 18, pinmux_fixed); 126 hwprot.vout = hwprot.vout_sync = regk_pinmux_yes; 127 break; 128 case pinmux_ser1: 129 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 130 ret = crisv32_pinmux_alloc(PORT_A, 24, 25, pinmux_fixed); 131 hwprot.ser1 = regk_pinmux_yes; 132 break; 133 case pinmux_ser2: 134 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 135 ret = crisv32_pinmux_alloc(PORT_A, 26, 27, pinmux_fixed); 136 hwprot.ser2 = regk_pinmux_yes; 137 break; 138 case pinmux_ser3: 139 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 140 ret = crisv32_pinmux_alloc(PORT_A, 28, 29, pinmux_fixed); 141 hwprot.ser3 = regk_pinmux_yes; 142 break; 143 case pinmux_ser4: 144 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 145 ret = crisv32_pinmux_alloc(PORT_A, 30, 31, pinmux_fixed); 146 hwprot.ser4 = regk_pinmux_yes; 147 break; 148 case pinmux_sser: 149 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes; 150 ret = crisv32_pinmux_alloc(PORT_A, 19, 23, pinmux_fixed); 151 hwprot.sser = regk_pinmux_yes; 152 break; 153 case pinmux_pio: 154 hwprot.pio = regk_pinmux_yes; 155 ret = 0; 156 break; 157 case pinmux_pwm0: 158 ret = crisv32_pinmux_alloc(PORT_A, 30, 30, pinmux_fixed); 159 hwprot.pwm0 = regk_pinmux_yes; 160 break; 161 case pinmux_pwm1: 162 ret = crisv32_pinmux_alloc(PORT_A, 31, 31, pinmux_fixed); 163 hwprot.pwm1 = regk_pinmux_yes; 164 break; 165 case pinmux_pwm2: 166 ret = crisv32_pinmux_alloc(PORT_B, 26, 26, pinmux_fixed); 167 hwprot.pwm2 = regk_pinmux_yes; 168 break; 169 case pinmux_i2c0: 170 ret = crisv32_pinmux_alloc(PORT_A, 0, 1, pinmux_fixed); 171 hwprot.i2c0 = regk_pinmux_yes; 172 break; 173 case pinmux_i2c1: 174 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 175 hwprot.i2c1 = regk_pinmux_yes; 176 break; 177 case pinmux_i2c1_3wire: 178 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 179 ret |= crisv32_pinmux_alloc(PORT_A, 7, 7, pinmux_fixed); 180 hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_yes; 181 break; 182 case pinmux_i2c1_sda1: 183 ret = crisv32_pinmux_alloc(PORT_A, 2, 4, pinmux_fixed); 184 hwprot.i2c1 = hwprot.i2c1_sda1 = regk_pinmux_yes; 185 break; 186 case pinmux_i2c1_sda2: 187 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 188 ret |= crisv32_pinmux_alloc(PORT_A, 5, 5, pinmux_fixed); 189 hwprot.i2c1 = hwprot.i2c1_sda2 = regk_pinmux_yes; 190 break; 191 case pinmux_i2c1_sda3: 192 ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed); 193 ret |= crisv32_pinmux_alloc(PORT_A, 6, 6, pinmux_fixed); 194 hwprot.i2c1 = hwprot.i2c1_sda3 = regk_pinmux_yes; 195 break; 196 default: 197 ret = -EINVAL; 198 break; 199 } 200 201 if (!ret) { 202 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); 203 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); 204 } else 205 memcpy(pins, saved, sizeof pins); 206 207 spin_unlock_irqrestore(&pinmux_lock, flags); 208 209 return ret; 210} 211 212void 213crisv32_pinmux_set(int port) 214{ 215 int i; 216 int gpio_val = 0; 217 int iop_val = 0; 218 int pin = port * PORT_PINS; 219 220 for (i = 0; (i < PORT_PINS) && (pin < PINS); i++, pin++) { 221 if (pins[pin] == pinmux_gpio) 222 gpio_val |= (1 << i); 223 else if (pins[pin] == pinmux_iop) 224 iop_val |= (1 << i); 225 } 226 227 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_gio_pa + 4 * port, 228 gpio_val); 229 REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_iop_pa + 4 * port, 230 iop_val); 231 232#ifdef DEBUG 233 crisv32_pinmux_dump(); 234#endif 235} 236 237int 238crisv32_pinmux_dealloc(int port, int first_pin, int last_pin) 239{ 240 int i; 241 unsigned long flags; 242 243 crisv32_pinmux_init(); 244 245 if (port > PORTS) 246 return -EINVAL; 247 248 spin_lock_irqsave(&pinmux_lock, flags); 249 250 for (i = first_pin; i <= last_pin; i++) 251 pins[port * PORT_PINS + i] = pinmux_none; 252 253 crisv32_pinmux_set(port); 254 spin_unlock_irqrestore(&pinmux_lock, flags); 255 256 return 0; 257} 258 259int 260crisv32_pinmux_dealloc_fixed(enum fixed_function function) 261{ 262 int ret = -EINVAL; 263 char saved[sizeof pins]; 264 unsigned long flags; 265 266 spin_lock_irqsave(&pinmux_lock, flags); 267 268 /* Save internal data for recovery */ 269 memcpy(saved, pins, sizeof pins); 270 271 crisv32_pinmux_init(); /* must be done before we read rw_hwprot */ 272 273 reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); 274 275 switch (function) { 276 case pinmux_eth: 277 ret = crisv32_pinmux_dealloc(PORT_B, 8, 23); 278 ret |= crisv32_pinmux_dealloc(PORT_B, 24, 25); 279 ret |= crisv32_pinmux_dealloc(PORT_B, 0, 7); 280 hwprot.eth = hwprot.eth_mdio = hwprot.geth = regk_pinmux_no; 281 break; 282 case pinmux_tg_cmos: 283 ret = crisv32_pinmux_dealloc(PORT_B, 27, 29); 284 hwprot.tg_clk = regk_pinmux_no; 285 break; 286 case pinmux_tg_ccd: 287 ret = crisv32_pinmux_dealloc(PORT_B, 27, 31); 288 ret |= crisv32_pinmux_dealloc(PORT_C, 0, 15); 289 hwprot.tg = hwprot.tg_clk = regk_pinmux_no; 290 break; 291 case pinmux_vout: 292 ret = crisv32_pinmux_dealloc(PORT_A, 8, 18); 293 hwprot.vout = hwprot.vout_sync = regk_pinmux_no; 294 break; 295 case pinmux_ser1: 296 ret = crisv32_pinmux_dealloc(PORT_A, 24, 25); 297 hwprot.ser1 = regk_pinmux_no; 298 break; 299 case pinmux_ser2: 300 ret = crisv32_pinmux_dealloc(PORT_A, 26, 27); 301 hwprot.ser2 = regk_pinmux_no; 302 break; 303 case pinmux_ser3: 304 ret = crisv32_pinmux_dealloc(PORT_A, 28, 29); 305 hwprot.ser3 = regk_pinmux_no; 306 break; 307 case pinmux_ser4: 308 ret = crisv32_pinmux_dealloc(PORT_A, 30, 31); 309 hwprot.ser4 = regk_pinmux_no; 310 break; 311 case pinmux_sser: 312 ret = crisv32_pinmux_dealloc(PORT_A, 19, 23); 313 hwprot.sser = regk_pinmux_no; 314 break; 315 case pinmux_pwm0: 316 ret = crisv32_pinmux_dealloc(PORT_A, 30, 30); 317 hwprot.pwm0 = regk_pinmux_no; 318 break; 319 case pinmux_pwm1: 320 ret = crisv32_pinmux_dealloc(PORT_A, 31, 31); 321 hwprot.pwm1 = regk_pinmux_no; 322 break; 323 case pinmux_pwm2: 324 ret = crisv32_pinmux_dealloc(PORT_B, 26, 26); 325 hwprot.pwm2 = regk_pinmux_no; 326 break; 327 case pinmux_i2c0: 328 ret = crisv32_pinmux_dealloc(PORT_A, 0, 1); 329 hwprot.i2c0 = regk_pinmux_no; 330 break; 331 case pinmux_i2c1: 332 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 333 hwprot.i2c1 = regk_pinmux_no; 334 break; 335 case pinmux_i2c1_3wire: 336 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 337 ret |= crisv32_pinmux_dealloc(PORT_A, 7, 7); 338 hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_no; 339 break; 340 case pinmux_i2c1_sda1: 341 ret = crisv32_pinmux_dealloc(PORT_A, 2, 4); 342 hwprot.i2c1_sda1 = regk_pinmux_no; 343 break; 344 case pinmux_i2c1_sda2: 345 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 346 ret |= crisv32_pinmux_dealloc(PORT_A, 5, 5); 347 hwprot.i2c1_sda2 = regk_pinmux_no; 348 break; 349 case pinmux_i2c1_sda3: 350 ret = crisv32_pinmux_dealloc(PORT_A, 2, 3); 351 ret |= crisv32_pinmux_dealloc(PORT_A, 6, 6); 352 hwprot.i2c1_sda3 = regk_pinmux_no; 353 break; 354 default: 355 ret = -EINVAL; 356 break; 357 } 358 359 if (!ret) 360 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); 361 else 362 memcpy(pins, saved, sizeof pins); 363 364 spin_unlock_irqrestore(&pinmux_lock, flags); 365 366 return ret; 367} 368 369void 370crisv32_pinmux_dump(void) 371{ 372 int i, j; 373 int pin = 0; 374 375 crisv32_pinmux_init(); 376 377 for (i = 0; i < PORTS; i++) { 378 pin++; 379 printk(KERN_DEBUG "Port %c\n", 'A'+i); 380 for (j = 0; (j < PORT_PINS) && (pin < PINS); j++, pin++) 381 printk(KERN_DEBUG 382 " Pin %d = %d\n", j, pins[i * PORT_PINS + j]); 383 } 384} 385 386__initcall(crisv32_pinmux_init); 387