summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/gpio-x1000.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/gpio-x1000.h')
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.h b/firmware/target/mips/ingenic_x1000/gpio-x1000.h
new file mode 100644
index 0000000000..f1a65b37b5
--- /dev/null
+++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.h
@@ -0,0 +1,110 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __GPIO_X1000_H__
23#define __GPIO_X1000_H__
24
25/* GPIO API
26 * --------
27 *
28 * To assign a new function to a GPIO, call gpio_config(). This uses the
29 * hardware's GPIO Z facility to atomically most GPIO registers at once,
30 * so it can be used to make any state transition safely. Since GPIO Z is
31 * protected by a mutex, you can't call gpio_config() from interrupt context.
32 *
33 * If you need to use GPIO Z directly, then use gpio_lock() and gpio_unlock()
34 * to acquire the mutex.
35 *
36 * Depending on the current GPIO state, certain state transitions are safe to
37 * perform without locking, as they only change one register:
38 *
39 * - for pins in GPIO_OUTPUT state:
40 * - use gpio_out_level() to change the output level
41 *
42 * - for pins in GPIO_IRQ_LEVEL or GPIO_IRQ_EDGE state:
43 * - use gpio_irq_level() to change the trigger level
44 * - use gpio_irq_mask() to mask/unmask the IRQ
45 *
46 * - for pins in GPIO_DEVICE or GPIO_INPUT state:
47 * - no special transitions allowed
48 *
49 * - in all states:
50 * - use gpio_set_pull() to change the pull-up/pull-down state
51 */
52
53#include "x1000/gpio.h"
54
55/* GPIO port numbers */
56#define GPIO_A 0
57#define GPIO_B 1
58#define GPIO_C 2
59#define GPIO_D 3
60#define GPIO_Z 7
61
62/* GPIO function bits */
63#define GPIO_F_PULL 16
64#define GPIO_F_INT 8
65#define GPIO_F_MASK 4
66#define GPIO_F_PAT1 2
67#define GPIO_F_PAT0 1
68
69/* GPIO function numbers */
70#define GPIO_DEVICE(i) ((i)&3)
71#define GPIO_OUTPUT(i) (0x4|((i)&1))
72#define GPIO_INPUT 0x16
73#define GPIO_IRQ_LEVEL(i) (0x1c|((i)&1))
74#define GPIO_IRQ_EDGE(i) (0x1e|((i)&1))
75
76extern void gpio_init(void);
77extern void gpio_lock(void);
78extern void gpio_unlock(void);
79extern void gpio_config(int port, unsigned pinmask, int func);
80
81static inline void gpio_out_level(int port, unsigned pinmask, int level)
82{
83 if(level)
84 jz_set(GPIO_PAT0(port), pinmask);
85 else
86 jz_clr(GPIO_PAT0(port), pinmask);
87}
88
89#define gpio_irq_level gpio_out_level
90
91static inline void gpio_irq_mask(int port, unsigned pinmask, int masked)
92{
93 if(masked)
94 jz_set(GPIO_MSK(port), pinmask);
95 else
96 jz_clr(GPIO_MSK(port), pinmask);
97}
98
99#define gpio_enable_irq(port, pinmask) gpio_irq_mask((port), (pinmask), 0)
100#define gpio_disable_irq(port, pinmask) gpio_irq_mask((port), (pinmask), 1)
101
102static inline void gpio_set_pull(int port, unsigned pinmask, int state)
103{
104 if(state)
105 jz_set(GPIO_PULL(port), pinmask);
106 else
107 jz_clr(GPIO_PULL(port), pinmask);
108}
109
110#endif /* __GPIO_X1000_H__ */