88 * 2017-10-20 ZYH add mode open drain and input pull down
99 * 2020-06-01 Du Huanpeng GPIO driver based on <components/drivers/include/drivers/pin.h>
1010 */
11-
12-
1311#include <rtthread.h>
1412#include <drivers/pin.h>
15- #include <rthw.h>
1613#include <ls2k1000.h>
17-
18- struct loongson_gpio {
19- rt_uint64_t GPIO0_OEN ;
20- rt_uint64_t GPIO1_OEN ; /* Reserved */
21- rt_uint64_t GPIO0_O ;
22- rt_uint64_t GPIO1_O ; /* Reserved */
23- rt_uint64_t GPIO0_I ;
24- rt_uint64_t GPIO1_I ; /* Reserved */
25- rt_uint64_t GPIO0_INTEN ;
26- rt_uint64_t GPIO1_INTEN ; /* Reserved */
27- };
14+ #include "drv_gpio.h"
2815
2916#ifdef RT_USING_PIN
17+ #define GPIO_IRQ_NUM (64)
18+ static struct gpio_irq_def _g_gpio_irq_tbl [GPIO_IRQ_NUM ];
3019
3120static void loongson_pin_mode (struct rt_device * device , rt_base_t pin , rt_base_t mode )
3221{
@@ -92,13 +81,36 @@ static int loongson_pin_read(struct rt_device *device, rt_base_t pin)
9281 return rc ;
9382}
9483
95- /* TODO: add GPIO interrupt */
84+ /* TODO: add GPIO interrupt */
9685static rt_err_t loongson_pin_attach_irq (struct rt_device * device , rt_int32_t pin , rt_uint32_t mode , void (* hdr )(void * args ), void * args )
9786{
87+ rt_uint8_t index ;
88+ rt_uint64_t m ;
9889 struct loongson_gpio * gpio ;
9990
10091 gpio = (void * )device -> user_data ;
10192
93+ if (pin < 4 )
94+ {
95+ index = pin ;
96+ }
97+ else if (pin < 32 )
98+ {
99+ index = 5 ;
100+ }
101+ else
102+ {
103+ index = 6 ;
104+ }
105+
106+ _g_gpio_irq_tbl [index ].irq_cb [pin ] = hdr ;
107+ _g_gpio_irq_tbl [index ].irq_arg [pin ] = args ;
108+ _g_gpio_irq_tbl [index ].irq_type [pin ] = mode ;
109+
110+ liointc_set_irq_mode (index , mode );
111+ m = (rt_uint64_t )1 << pin ;
112+ gpio -> GPIO0_INTEN |= m ;
113+
102114 return RT_EOK ;
103115}
104116static rt_err_t loongson_pin_detach_irq (struct rt_device * device , rt_int32_t pin )
@@ -107,6 +119,24 @@ static rt_err_t loongson_pin_detach_irq(struct rt_device *device, rt_int32_t pin
107119
108120 gpio = (void * )device -> user_data ;
109121
122+ rt_uint8_t index ;
123+ if (pin < 4 )
124+ {
125+ index = pin ;
126+ }
127+ else if (pin < 32 )
128+ {
129+ index = 5 ;
130+ }
131+ else
132+ {
133+ index = 6 ;
134+ }
135+ _g_gpio_irq_tbl [index ].irq_cb [pin ] = RT_NULL ;
136+ _g_gpio_irq_tbl [index ].irq_arg [pin ] = RT_NULL ;
137+ _g_gpio_irq_tbl [index ].irq_type [pin ] = RT_NULL ;
138+ _g_gpio_irq_tbl [index ].state [pin ] = RT_NULL ;
139+
110140 return RT_EOK ;
111141}
112142static rt_err_t loongson_pin_irq_enable (struct rt_device * device , rt_base_t pin , rt_uint32_t enabled )
@@ -115,9 +145,72 @@ static rt_err_t loongson_pin_irq_enable(struct rt_device *device, rt_base_t pin,
115145
116146 gpio = (void * )device -> user_data ;
117147
148+ rt_uint8_t index ;
149+ if (pin < 4 )
150+ {
151+ index = pin ;
152+ }
153+ else if (pin < 32 )
154+ {
155+ index = 5 ;
156+ }
157+ else
158+ {
159+ index = 6 ;
160+ }
161+
162+ if (enabled )
163+ _g_gpio_irq_tbl [index ].state [pin ] = 1 ;
164+ else
165+ _g_gpio_irq_tbl [index ].state [pin ] = 0 ;
118166 return RT_EOK ;
119167}
120168
169+ static void gpio_irq_handler (int irq , void * param )
170+ {
171+ struct gpio_irq_def * irq_def = (struct gpio_irq_def * )param ;
172+ rt_uint32_t pin ;
173+ rt_uint32_t value ;
174+ rt_uint32_t tmpvalue ;
175+
176+ if (irq == LS2K_GPIO0_INT_IRQ )
177+ {
178+ pin = 0 ;
179+ }
180+ else if (irq == LS2K_GPIO1_INT_IRQ )
181+ {
182+ pin = 1 ;
183+ }
184+ else if (irq == LS2K_GPIO2_INT_IRQ )
185+ {
186+ pin = 2 ;
187+ }
188+ else if (irq == LS2K_GPIO3_INT_IRQ )
189+ {
190+ pin = 3 ;
191+ }
192+ else if (irq == LS2K_GPIO_INTLO_IRQ )
193+ {
194+ pin = 4 ;
195+ }
196+ else
197+ {
198+ pin = 32 ;
199+ }
200+
201+ while (value )
202+ {
203+ if ((value & 0x1 ) && (irq_def -> irq_cb [pin ] != RT_NULL ))
204+ {
205+ if (irq_def -> state [pin ])
206+ {
207+ irq_def -> irq_cb [pin ](irq_def -> irq_arg [pin ]);
208+ }
209+ }
210+ pin ++ ;
211+ value = value >> 1 ;
212+ }
213+ }
121214
122215static struct rt_pin_ops loongson_pin_ops = {
123216 .pin_mode = loongson_pin_mode ,
@@ -139,6 +232,30 @@ int loongson_pin_init(void)
139232 loongson_gpio_priv = (void * )GPIO_BASE ;
140233 rc = rt_device_pin_register ("pin" , & loongson_pin_ops , loongson_gpio_priv );
141234
235+ //gpio0
236+ rt_hw_interrupt_install (LS2K_GPIO0_INT_IRQ , gpio_irq_handler , & _g_gpio_irq_tbl [0 ], "gpio0_irq" );
237+ rt_hw_interrupt_umask (LS2K_GPIO0_INT_IRQ );
238+
239+ //gpio1
240+ rt_hw_interrupt_install (LS2K_GPIO1_INT_IRQ , gpio_irq_handler , & _g_gpio_irq_tbl [1 ], "gpio1_irq" );
241+ rt_hw_interrupt_umask (LS2K_GPIO1_INT_IRQ );
242+
243+ //gpio2
244+ rt_hw_interrupt_install (LS2K_GPIO2_INT_IRQ , gpio_irq_handler , & _g_gpio_irq_tbl [2 ], "gpio2_irq" );
245+ rt_hw_interrupt_umask (LS2K_GPIO2_INT_IRQ );
246+
247+ //gpio3
248+ rt_hw_interrupt_install (LS2K_GPIO3_INT_IRQ , gpio_irq_handler , & _g_gpio_irq_tbl [3 ], "gpio3_irq" );
249+ rt_hw_interrupt_umask (LS2K_GPIO3_INT_IRQ );
250+
251+ //gpio4~gpio31
252+ rt_hw_interrupt_install (LS2K_GPIO_INTLO_IRQ , gpio_irq_handler , & _g_gpio_irq_tbl [4 ], "gpio4_irq" );
253+ rt_hw_interrupt_umask (LS2K_GPIO_INTLO_IRQ );
254+
255+ //gpio32~gpio63
256+ rt_hw_interrupt_install (LS2K_GPIO_INTHI_IRQ , gpio_irq_handler , & _g_gpio_irq_tbl [5 ], "gpio5_irq" );
257+ rt_hw_interrupt_umask (LS2K_GPIO_INTHI_IRQ );
258+
142259 return rc ;
143260}
144261INIT_BOARD_EXPORT (loongson_pin_init );
0 commit comments