1 /* 2 * Copyright (c) 2008, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <boot/boot.h> 30 #include <msm7k/gpio.h> 31 32 /* gross */ 33 34 typedef struct gpioregs gpioregs; 35 36 struct gpioregs 37 { 38 unsigned out; 39 unsigned in; 40 unsigned int_status; 41 unsigned int_clear; 42 unsigned int_en; 43 unsigned int_edge; 44 unsigned int_pos; 45 unsigned oe; 46 }; 47 48 static gpioregs GPIO_REGS[] = { 49 { 50 .out = GPIO_OUT_0, 51 .in = GPIO_IN_0, 52 .int_status = GPIO_INT_STATUS_0, 53 .int_clear = GPIO_INT_CLEAR_0, 54 .int_en = GPIO_INT_EN_0, 55 .int_edge = GPIO_INT_EDGE_0, 56 .int_pos = GPIO_INT_POS_0, 57 .oe = GPIO_OE_0, 58 }, 59 { 60 .out = GPIO_OUT_1, 61 .in = GPIO_IN_1, 62 .int_status = GPIO_INT_STATUS_1, 63 .int_clear = GPIO_INT_CLEAR_1, 64 .int_en = GPIO_INT_EN_1, 65 .int_edge = GPIO_INT_EDGE_1, 66 .int_pos = GPIO_INT_POS_1, 67 .oe = GPIO_OE_1, 68 }, 69 { 70 .out = GPIO_OUT_2, 71 .in = GPIO_IN_2, 72 .int_status = GPIO_INT_STATUS_2, 73 .int_clear = GPIO_INT_CLEAR_2, 74 .int_en = GPIO_INT_EN_2, 75 .int_edge = GPIO_INT_EDGE_2, 76 .int_pos = GPIO_INT_POS_2, 77 .oe = GPIO_OE_2, 78 }, 79 { 80 .out = GPIO_OUT_3, 81 .in = GPIO_IN_3, 82 .int_status = GPIO_INT_STATUS_3, 83 .int_clear = GPIO_INT_CLEAR_3, 84 .int_en = GPIO_INT_EN_3, 85 .int_edge = GPIO_INT_EDGE_3, 86 .int_pos = GPIO_INT_POS_3, 87 .oe = GPIO_OE_3, 88 }, 89 { 90 .out = GPIO_OUT_4, 91 .in = GPIO_IN_4, 92 .int_status = GPIO_INT_STATUS_4, 93 .int_clear = GPIO_INT_CLEAR_4, 94 .int_en = GPIO_INT_EN_4, 95 .int_edge = GPIO_INT_EDGE_4, 96 .int_pos = GPIO_INT_POS_4, 97 .oe = GPIO_OE_4, 98 }, 99 }; 100 101 static gpioregs *find_gpio(unsigned n, unsigned *bit) 102 { 103 if(n > 106) return 0; 104 if(n > 94) { 105 *bit = 1 << (n - 95); 106 return GPIO_REGS + 4; 107 } 108 if(n > 67) { 109 *bit = 1 << (n - 68); 110 return GPIO_REGS + 3; 111 } 112 if(n > 42) { 113 *bit = 1 << (n - 43); 114 return GPIO_REGS + 2; 115 } 116 if(n > 15) { 117 *bit = 1 << (n - 16); 118 return GPIO_REGS + 1; 119 } 120 *bit = 1 << n; 121 return GPIO_REGS + 0; 122 } 123 124 void gpio_output_enable(unsigned n, unsigned out) 125 { 126 gpioregs *r; 127 unsigned b; 128 unsigned v; 129 130 if((r = find_gpio(n, &b)) == 0) return; 131 132 v = readl(r->oe); 133 if(out) { 134 writel(v | b, r->oe); 135 } else { 136 writel(v & (~b), r->oe); 137 } 138 } 139 140 void gpio_write(unsigned n, unsigned on) 141 { 142 gpioregs *r; 143 unsigned b; 144 unsigned v; 145 146 if((r = find_gpio(n, &b)) == 0) return; 147 148 v = readl(r->out); 149 if(on) { 150 writel(v | b, r->out); 151 } else { 152 writel(v & (~b), r->out); 153 } 154 } 155 156 int gpio_read(unsigned n) 157 { 158 gpioregs *r; 159 unsigned b; 160 161 if((r = find_gpio(n, &b)) == 0) return 0; 162 163 return (readl(r->in) & b) ? 1 : 0; 164 } 165 166 void gpio_dir(int nr, int out) 167 { 168 gpio_output_enable(nr, out); 169 } 170 171 void gpio_set(int nr, int set) 172 { 173 gpio_write(nr, set); 174 } 175 176 int gpio_get(int nr) 177 { 178 return gpio_read(nr); 179 } 180 181 182