1 /* 2 * arch/powerpc/sysdev/qe_lib/qe_io.c 3 * 4 * QE Parallel I/O ports configuration routines 5 * 6 * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved. 7 * 8 * Author: Li Yang <LeoLi@freescale.com> 9 * Based on code from Shlomi Gridish <gridish@freescale.com> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the 13 * Free Software Foundation; either version 2 of the License, or (at your 14 * option) any later version. 15 */ 16 17 #include <linux/stddef.h> 18 #include <linux/kernel.h> 19 #include <linux/errno.h> 20 #include <linux/module.h> 21 #include <linux/ioport.h> 22 23 #include <asm/io.h> 24 #include <soc/fsl/qe/qe.h> 25 #include <asm/prom.h> 26 #include <sysdev/fsl_soc.h> 27 28 #undef DEBUG 29 30 static struct qe_pio_regs __iomem *par_io; 31 static int num_par_io_ports = 0; 32 33 int par_io_init(struct device_node *np) 34 { 35 struct resource res; 36 int ret; 37 const u32 *num_ports; 38 39 /* Map Parallel I/O ports registers */ 40 ret = of_address_to_resource(np, 0, &res); 41 if (ret) 42 return ret; 43 par_io = ioremap(res.start, resource_size(&res)); 44 45 num_ports = of_get_property(np, "num-ports", NULL); 46 if (num_ports) 47 num_par_io_ports = *num_ports; 48 49 return 0; 50 } 51 52 void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir, 53 int open_drain, int assignment, int has_irq) 54 { 55 u32 pin_mask1bit; 56 u32 pin_mask2bits; 57 u32 new_mask2bits; 58 u32 tmp_val; 59 60 /* calculate pin location for single and 2 bits information */ 61 pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1))); 62 63 /* Set open drain, if required */ 64 tmp_val = in_be32(&par_io->cpodr); 65 if (open_drain) 66 out_be32(&par_io->cpodr, pin_mask1bit | tmp_val); 67 else 68 out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val); 69 70 /* define direction */ 71 tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ? 72 in_be32(&par_io->cpdir2) : 73 in_be32(&par_io->cpdir1); 74 75 /* get all bits mask for 2 bit per port */ 76 pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS - 77 (pin % (QE_PIO_PINS / 2) + 1) * 2)); 78 79 /* Get the final mask we need for the right definition */ 80 new_mask2bits = (u32) (dir << (QE_PIO_PINS - 81 (pin % (QE_PIO_PINS / 2) + 1) * 2)); 82 83 /* clear and set 2 bits mask */ 84 if (pin > (QE_PIO_PINS / 2) - 1) { 85 out_be32(&par_io->cpdir2, 86 ~pin_mask2bits & tmp_val); 87 tmp_val &= ~pin_mask2bits; 88 out_be32(&par_io->cpdir2, new_mask2bits | tmp_val); 89 } else { 90 out_be32(&par_io->cpdir1, 91 ~pin_mask2bits & tmp_val); 92 tmp_val &= ~pin_mask2bits; 93 out_be32(&par_io->cpdir1, new_mask2bits | tmp_val); 94 } 95 /* define pin assignment */ 96 tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ? 97 in_be32(&par_io->cppar2) : 98 in_be32(&par_io->cppar1); 99 100 new_mask2bits = (u32) (assignment << (QE_PIO_PINS - 101 (pin % (QE_PIO_PINS / 2) + 1) * 2)); 102 /* clear and set 2 bits mask */ 103 if (pin > (QE_PIO_PINS / 2) - 1) { 104 out_be32(&par_io->cppar2, 105 ~pin_mask2bits & tmp_val); 106 tmp_val &= ~pin_mask2bits; 107 out_be32(&par_io->cppar2, new_mask2bits | tmp_val); 108 } else { 109 out_be32(&par_io->cppar1, 110 ~pin_mask2bits & tmp_val); 111 tmp_val &= ~pin_mask2bits; 112 out_be32(&par_io->cppar1, new_mask2bits | tmp_val); 113 } 114 } 115 EXPORT_SYMBOL(__par_io_config_pin); 116 117 int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, 118 int assignment, int has_irq) 119 { 120 if (!par_io || port >= num_par_io_ports) 121 return -EINVAL; 122 123 __par_io_config_pin(&par_io[port], pin, dir, open_drain, assignment, 124 has_irq); 125 return 0; 126 } 127 EXPORT_SYMBOL(par_io_config_pin); 128 129 int par_io_data_set(u8 port, u8 pin, u8 val) 130 { 131 u32 pin_mask, tmp_val; 132 133 if (port >= num_par_io_ports) 134 return -EINVAL; 135 if (pin >= QE_PIO_PINS) 136 return -EINVAL; 137 /* calculate pin location */ 138 pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin)); 139 140 tmp_val = in_be32(&par_io[port].cpdata); 141 142 if (val == 0) /* clear */ 143 out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val); 144 else /* set */ 145 out_be32(&par_io[port].cpdata, pin_mask | tmp_val); 146 147 return 0; 148 } 149 EXPORT_SYMBOL(par_io_data_set); 150 151 int par_io_of_config(struct device_node *np) 152 { 153 struct device_node *pio; 154 const phandle *ph; 155 int pio_map_len; 156 const unsigned int *pio_map; 157 158 if (par_io == NULL) { 159 printk(KERN_ERR "par_io not initialized\n"); 160 return -1; 161 } 162 163 ph = of_get_property(np, "pio-handle", NULL); 164 if (ph == NULL) { 165 printk(KERN_ERR "pio-handle not available\n"); 166 return -1; 167 } 168 169 pio = of_find_node_by_phandle(*ph); 170 171 pio_map = of_get_property(pio, "pio-map", &pio_map_len); 172 if (pio_map == NULL) { 173 printk(KERN_ERR "pio-map is not set!\n"); 174 return -1; 175 } 176 pio_map_len /= sizeof(unsigned int); 177 if ((pio_map_len % 6) != 0) { 178 printk(KERN_ERR "pio-map format wrong!\n"); 179 return -1; 180 } 181 182 while (pio_map_len > 0) { 183 par_io_config_pin((u8) pio_map[0], (u8) pio_map[1], 184 (int) pio_map[2], (int) pio_map[3], 185 (int) pio_map[4], (int) pio_map[5]); 186 pio_map += 6; 187 pio_map_len -= 6; 188 } 189 of_node_put(pio); 190 return 0; 191 } 192 EXPORT_SYMBOL(par_io_of_config); 193