source: svn/trunk/newcon3bcm2_21bu/dta/src/settop_api/bsettop_gpio.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 8.9 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2006, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile:  $
11 * $brcm_Revision:  $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log:  $
19 *
20 ***************************************************************************/
21
22#include "bchp_irq0.h"
23#include "bchp_int_id_irq0.h"
24#include "bint.h"
25#include "bchp_gio.h"
26
27#if (BCHP_CHIP==7552)
28#include "bchp_int_id_irq0_aon.h"
29#include "bchp_gio_aon.h"
30#endif
31
32#include "gist.h"
33#include "bsettop_gpio.h"
34
35BDBG_MODULE(bsettop_gpio);
36
37#define NUM_GPIO_PINS   105
38#define NUM_SGPIO_PINS  6
39#define NUM_AGPIO_PINS  21
40#define NUM_ASGPIO_PINS 2
41
42struct bgpio
43{
44        uint32_t offset;
45        uint32_t shift;
46        bgpio_type type;
47        int num;
48        bgpio_interrupt_mode intMode;
49        bsettop_callback user_callback;
50        void *user_callback_context;
51};
52
53struct bsettop_gpio
54{
55        bool init;
56        BINT_CallbackHandle hcallback; 
57        BINT_CallbackHandle haiocallback;       
58        bgpio_t gpios[NUM_GPIO_PINS];
59        bgpio_t sgpios[NUM_SGPIO_PINS];
60        bgpio_t agpios[NUM_AGPIO_PINS];
61        bgpio_t asgpios[NUM_ASGPIO_PINS];
62};
63
64static struct bsettop_gpio b_gpio;
65static void bgpio_p_get_offset_shift(bgpio_type type, int pin, uint32_t *offset, uint32_t *shift);
66
67bgpio_t bgpio_open(int gpio_num, const bgpio_settings *p_settings)
68{
69        bgpio_t gpio = NULL;
70        unsigned edge_conf = 0, edge_insensitive = 0, edge_level = 0, enabled = 1;
71        uint32_t reg;
72#if (BCHP_CHIP==7552)
73        int aio_pin = gpio_num;
74#endif
75
76        if (b_gpio.init == false) {
77                bgpio_init();
78        }
79
80        if (!p_settings) {
81                BDBG_ERR(("invalid setting parameter"));
82                goto error;
83        }
84
85#if (BCHP_CHIP==7552)
86        if (p_settings->type == eGPIO_AStandard)
87                aio_pin -= BGIO_PinId_eAgpio00;
88        else if (p_settings->type == eGPIO_ASpecial)
89                aio_pin -= BGIO_PinId_eAsgpio00;
90
91#endif
92       
93        if ((p_settings->type == eGPIO_Standard && gpio_num>=NUM_GPIO_PINS) ||
94                (p_settings->type == eGPIO_Special && gpio_num>=NUM_SGPIO_PINS) 
95#if (BCHP_CHIP==7552)
96                || (p_settings->type == eGPIO_AStandard && aio_pin >= NUM_AGPIO_PINS)
97                || (p_settings->type == eGPIO_ASpecial && aio_pin >= NUM_ASGPIO_PINS)
98#endif
99        )
100        {
101                BDBG_ERR(("invalid gpio pin number"));
102                goto error;
103        }
104               
105        gpio = BKNI_Malloc(sizeof(*gpio));
106        if (!gpio) {
107                BDBG_ERR(("fail to allocate gpio"));
108                goto error;
109        }
110
111        gpio->type = p_settings->type;
112        gpio->num = gpio_num;
113        gpio->intMode = p_settings->intMode;
114        gpio->user_callback = p_settings->user_callback;
115        gpio->user_callback_context = p_settings->user_callback_context;
116
117        bgpio_p_get_offset_shift(gpio->type, gpio->num, &gpio->offset, &gpio->shift);
118
119        if (gpio->type == eGPIO_Standard)
120        {
121                b_gpio.gpios[gpio_num] = gpio;
122        }
123#if (BCHP_CHIP==7552)
124        else if (gpio->type == eGPIO_AStandard)
125        {
126                b_gpio.agpios[aio_pin] = gpio;
127        }
128        else if (gpio->type == eGPIO_ASpecial)
129        {
130                b_gpio.asgpios[aio_pin] = gpio;
131        }
132#endif
133        else {
134                b_gpio.sgpios[gpio_num] = gpio;
135        }
136
137
138        reg = BREG_Read32(GetREG(), BCHP_GIO_IODIR_LO+gpio->offset);
139        if (p_settings->mode == eGPIO_Input) 
140                reg |= (1<<gpio->shift);
141        else 
142                reg &= ~(1<<gpio->shift);
143        BREG_Write32(GetREG(), BCHP_GIO_IODIR_LO+gpio->offset,reg);
144
145        reg = BREG_Read32(GetREG(), BCHP_GIO_ODEN_LO+gpio->offset);
146        if (p_settings->mode == eGPIO_OutputOpenDrain)
147                reg |= (1<<gpio->shift);
148        else
149                reg &= ~(1<<gpio->shift);       
150        BREG_Write32(GetREG(), BCHP_GIO_ODEN_LO+gpio->offset, reg);
151
152        switch (p_settings->intMode) {
153                case eGPIO_RisingEdge:
154                        edge_conf = 1;
155                        edge_insensitive = 0;
156                        edge_level = 0;
157                        break;
158                case eGPIO_FallingEdge:
159                        edge_conf = 0;
160                        edge_insensitive = 0;
161                        edge_level = 0;
162                        break;
163                case eGPIO_Edge:
164                        edge_conf = 0;
165                        edge_insensitive = 1;
166                        edge_level = 0;
167                        break;
168                case eGPIO_High:
169                        edge_conf = 1;
170                        edge_insensitive = 0;
171                        edge_level = 1;
172                        break;
173                case eGPIO_Low:
174                        edge_conf = 0;
175                        edge_insensitive = 0;
176                        edge_level = 1;
177                        break;
178                default:
179                        enabled = 0;
180        }
181
182        if (!enabled) {
183                reg = BREG_Read32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset);
184                reg &= ~(1<<gpio->shift);
185                BREG_Write32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset, reg);
186        }
187
188        /* set edge config */
189        reg = BREG_Read32(GetREG(), BCHP_GIO_EC_LO+gpio->offset);
190        if (edge_conf) 
191                reg |= (1<<gpio->shift);
192        else
193                reg &= ~(1<<gpio->shift);
194        BREG_Write32(GetREG(), BCHP_GIO_EC_LO+gpio->offset, reg);
195
196        /* set edge insensitive */
197        reg = BREG_Read32(GetREG(), BCHP_GIO_EI_LO+gpio->offset);
198        if (edge_insensitive) 
199                reg |= (1<<gpio->shift);
200        else
201                reg &= ~(1<<gpio->shift);
202        BREG_Write32(GetREG(), BCHP_GIO_EI_LO+gpio->offset, reg);
203
204        /* set level */
205        reg = BREG_Read32(GetREG(), BCHP_GIO_LEVEL_LO+gpio->offset);
206        if (edge_level) 
207                reg |= (1<<gpio->shift);
208        else
209                reg &= ~(1<<gpio->shift);
210        BREG_Write32(GetREG(), BCHP_GIO_LEVEL_LO+gpio->offset, reg);
211
212        /* set interrupt mask */
213        reg = BREG_Read32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset);
214        if (enabled)
215                reg |= (1<<gpio->shift);
216        else
217                reg &= ~(1<<gpio->shift);
218        BREG_Write32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset, reg);
219error:
220        return gpio;
221}
222
223void bgpio_close(bgpio_t gpio)
224{
225        BDBG_ASSERT(gpio);
226        if (gpio->type == eGPIO_Special)
227                b_gpio.sgpios[gpio->num] = NULL;
228        else
229                b_gpio.gpios[gpio->num] = NULL;
230
231        BKNI_Free(gpio);       
232}
233/*
234 * For level trigger interrupt, application should call this function to get additional level triggered interrupt
235 */
236void bgpio_enable_int(bgpio_t gpio)
237{
238        uint32_t reg;
239
240        BDBG_ASSERT(gpio);
241        reg = BREG_Read32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset);
242        reg |= (1<<gpio->shift);
243        BREG_Write32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset, reg);
244}
245
246static void bgpio_p_get_offset_shift(bgpio_type type, int pin, uint32_t *offset, uint32_t *shift)
247{
248        if (type == eGPIO_Standard) {
249                if (pin<32) {
250                        *offset = BCHP_GIO_ODEN_LO;
251                        *shift = pin;
252                }
253                else if (pin<64) {
254                        *offset = BCHP_GIO_ODEN_HI;
255                        *shift = pin-32;
256                }
257                else if (pin<90) {
258                        *offset = BCHP_GIO_ODEN_EXT;
259                        *shift = (pin-64) + 6; /*spio*/
260                }
261                else if (pin<105) {
262                        *offset = BCHP_GIO_ODEN_EXT_HI;
263                        *shift = pin-90;
264                }
265                *offset = *offset - BCHP_GIO_ODEN_LO;
266        }
267#if (BCHP_CHIP==7552)
268        else if (type == eGPIO_AStandard) {
269                *offset = BCHP_GIO_AON_ODEN_LO-BCHP_GIO_ODEN_LO;
270                *shift = pin-BGIO_PinId_eAgpio00;
271        }
272        else if (type == eGPIO_ASpecial) {
273                *offset = BCHP_GIO_AON_ODEN_EXT-BCHP_GIO_ODEN_LO;
274                *shift = pin-BGIO_PinId_eAsgpio00;
275        }
276#endif 
277        else if (type == eGPIO_Special) {
278                *offset = BCHP_GIO_ODEN_EXT-BCHP_GIO_ODEN_LO;
279                *shift = pin;
280
281        }
282}
283
284static void bgpio_p_int_callback(void *pParam1, int param2)
285{
286        uint32_t mask, stat;
287        bgpio_t gpio;
288        int i;
289        for (i=0; i<NUM_GPIO_PINS+NUM_SGPIO_PINS+NUM_AGPIO_PINS+NUM_ASGPIO_PINS; i++) {
290                if (i<NUM_SGPIO_PINS)
291                        gpio = b_gpio.sgpios[i];
292                else if (i<NUM_SGPIO_PINS+NUM_GPIO_PINS)
293                        gpio = b_gpio.gpios[i-NUM_SGPIO_PINS];
294                else if (i<NUM_SGPIO_PINS+NUM_GPIO_PINS+NUM_AGPIO_PINS)
295                        gpio = b_gpio.agpios[i-NUM_SGPIO_PINS-NUM_GPIO_PINS];
296                else
297                        gpio = b_gpio.asgpios[i-NUM_SGPIO_PINS-NUM_GPIO_PINS-NUM_AGPIO_PINS];
298
299                if (gpio) {
300                        stat = BREG_Read32(GetREG(), BCHP_GIO_STAT_LO+gpio->offset);
301                        mask = BREG_Read32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset);
302
303                        if (((stat>>gpio->shift)&1) && ((mask>>gpio->shift)&1)) {
304                                /* clear status immediately */
305                                BREG_Write32(GetREG(), BCHP_GIO_STAT_LO+gpio->offset, 1<<gpio->shift);
306
307                                if ((gpio->intMode == eGPIO_Low) || (gpio->intMode == eGPIO_High)) {
308                                        /* mask a level interrupt to prevent continous interrupt. application should reenable it */
309                                        mask &= ~(1<<gpio->shift);
310                                        BREG_Write32(GetREG(), BCHP_GIO_MASK_LO+gpio->offset, mask);
311                                }
312                                if (gpio->user_callback) {
313                                        (gpio->user_callback)(gpio->user_callback_context);
314                                }
315                        }
316                }
317        }
318}
319#ifndef BCHP_INT_ID_IRQ0_gio_irqen
320#define BCHP_INT_ID_IRQ0_gio_irqen BCHP_INT_ID_gio
321#endif
322void bgpio_init(void)
323{
324        BKNI_Memset(&b_gpio, 0, sizeof(b_gpio));
325
326    /* disable all gpio interrupt */
327        BREG_Write32(GetREG(), BCHP_GIO_MASK_LO, 0);
328        BREG_Write32(GetREG(), BCHP_GIO_STAT_LO, 0xffffffff);
329        BREG_Write32(GetREG(), BCHP_GIO_MASK_HI, 0);
330        BREG_Write32(GetREG(), BCHP_GIO_STAT_HI, 0xffffffff);
331        BREG_Write32(GetREG(), BCHP_GIO_MASK_EXT, 0);
332        BREG_Write32(GetREG(), BCHP_GIO_STAT_EXT, 0xffffffff);
333        BREG_Write32(GetREG(), BCHP_GIO_MASK_EXT_HI, 0);
334        BREG_Write32(GetREG(), BCHP_GIO_STAT_EXT_HI, 0xffffffff);
335
336#if (BCHP_CHIP==7552)
337        BREG_Write32(GetREG(), BCHP_GIO_AON_MASK_LO, 0);
338        BREG_Write32(GetREG(), BCHP_GIO_AON_STAT_LO, 0xFFFFFFFF);
339        BREG_Write32(GetREG(), BCHP_GIO_AON_MASK_EXT,0);
340        BREG_Write32(GetREG(), BCHP_GIO_AON_STAT_EXT, 0xFFFFFFF);
341
342        BINT_CreateCallback(&b_gpio.haiocallback,GetINT(), BCHP_INT_ID_IRQ0_AON_gio_irqen, bgpio_p_int_callback, NULL, 0);
343        BINT_EnableCallback(b_gpio.haiocallback);
344#endif
345        /* attach callback */
346        BINT_CreateCallback(&b_gpio.hcallback,GetINT(),BCHP_INT_ID_IRQ0_gio_irqen, bgpio_p_int_callback, NULL, 0);
347        BINT_EnableCallback(b_gpio.hcallback);
348               
349        b_gpio.init = true;
350}
351
Note: See TracBrowser for help on using the repository browser.