Home | History | Annotate | Download | only in arch_msm7k
      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