1 /* 2 * Copyright (C) 2006 Freescale Semiconductor, Inc. 3 * 4 * Dave Liu <daveliu@freescale.com> 5 * based on source code of Shlomi Gridish 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23 #include "common.h" 24 #include "asm/errno.h" 25 #include "asm/io.h" 26 #include "asm/immap_83xx.h" 27 28 #define NUM_OF_PINS 32 29 void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) 30 { 31 u32 pin_2bit_mask; 32 u32 pin_2bit_dir; 33 u32 pin_2bit_assign; 34 u32 pin_1bit_mask; 35 u32 tmp_val; 36 volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; 37 volatile qepio83xx_t *par_io = (volatile qepio83xx_t *)&im->qepio; 38 39 /* Caculate pin location and 2bit mask and dir */ 40 pin_2bit_mask = (u32)(0x3 << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); 41 pin_2bit_dir = (u32)(dir << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); 42 43 /* Setup the direction */ 44 tmp_val = (pin > (NUM_OF_PINS/2) - 1) ? \ 45 in_be32(&par_io->ioport[port].dir2) : 46 in_be32(&par_io->ioport[port].dir1); 47 48 if (pin > (NUM_OF_PINS/2) -1) { 49 out_be32(&par_io->ioport[port].dir2, ~pin_2bit_mask & tmp_val); 50 out_be32(&par_io->ioport[port].dir2, pin_2bit_dir | tmp_val); 51 } else { 52 out_be32(&par_io->ioport[port].dir1, ~pin_2bit_mask & tmp_val); 53 out_be32(&par_io->ioport[port].dir1, pin_2bit_dir | tmp_val); 54 } 55 56 /* Calculate pin location for 1bit mask */ 57 pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); 58 59 /* Setup the open drain */ 60 tmp_val = in_be32(&par_io->ioport[port].podr); 61 if (open_drain) { 62 out_be32(&par_io->ioport[port].podr, pin_1bit_mask | tmp_val); 63 } else { 64 out_be32(&par_io->ioport[port].podr, ~pin_1bit_mask & tmp_val); 65 } 66 67 /* Setup the assignment */ 68 tmp_val = (pin > (NUM_OF_PINS/2) - 1) ? 69 in_be32(&par_io->ioport[port].ppar2): 70 in_be32(&par_io->ioport[port].ppar1); 71 pin_2bit_assign = (u32)(assign 72 << (NUM_OF_PINS - (pin%(NUM_OF_PINS/2)+1)*2)); 73 74 /* Clear and set 2 bits mask */ 75 if (pin > (NUM_OF_PINS/2) - 1) { 76 out_be32(&par_io->ioport[port].ppar2, ~pin_2bit_mask & tmp_val); 77 out_be32(&par_io->ioport[port].ppar2, pin_2bit_assign | tmp_val); 78 } else { 79 out_be32(&par_io->ioport[port].ppar1, ~pin_2bit_mask & tmp_val); 80 out_be32(&par_io->ioport[port].ppar1, pin_2bit_assign | tmp_val); 81 } 82 } 83