1010
1111#include "dev_pin_dm.h"
1212
13+ static rt_size_t pin_total_nr = 0 ;
14+ static struct rt_spinlock pin_lock = {};
15+ static rt_list_t pin_nodes = RT_LIST_OBJECT_INIT (pin_nodes );
16+
17+ static struct rt_device_pin * pin_device_find (rt_ubase_t pin )
18+ {
19+ struct rt_device_pin * gpio = RT_NULL , * gpio_tmp ;
20+
21+ rt_spin_lock (& pin_lock );
22+
23+ rt_list_for_each_entry (gpio_tmp , & pin_nodes , list )
24+ {
25+ if (pin >= gpio_tmp -> pin_start &&
26+ pin - gpio_tmp -> pin_start < gpio_tmp -> pin_nr )
27+ {
28+ gpio = gpio_tmp ;
29+ break ;
30+ }
31+ }
32+
33+ rt_spin_unlock (& pin_lock );
34+
35+ return gpio ;
36+ }
37+
38+ static void pin_api_mode (struct rt_device * device , rt_base_t pin , rt_uint8_t mode )
39+ {
40+ struct rt_device_pin * gpio = pin_device_find (pin );
41+
42+ if (gpio && gpio -> ops -> pin_mode )
43+ {
44+ gpio -> ops -> pin_mode (& gpio -> parent , pin - gpio -> pin_start , mode );
45+ }
46+ }
47+
48+ static void pin_api_write (struct rt_device * device , rt_base_t pin , rt_uint8_t value )
49+ {
50+ struct rt_device_pin * gpio = pin_device_find (pin );
51+
52+ if (gpio && gpio -> ops -> pin_write )
53+ {
54+ gpio -> ops -> pin_write (& gpio -> parent , pin - gpio -> pin_start , value );
55+ }
56+ }
57+
58+ static rt_int8_t pin_api_read (struct rt_device * device , rt_base_t pin )
59+ {
60+ struct rt_device_pin * gpio = pin_device_find (pin );
61+
62+ if (gpio && gpio -> ops -> pin_read )
63+ {
64+ return gpio -> ops -> pin_read (& gpio -> parent , pin - gpio -> pin_start );
65+ }
66+
67+ return - RT_EINVAL ;
68+ }
69+
70+ static rt_err_t pin_api_attach_irq (struct rt_device * device , rt_base_t pin ,
71+ rt_uint8_t mode , void (* hdr )(void * args ), void * args )
72+ {
73+ struct rt_device_pin * gpio = pin_device_find (pin );
74+
75+ if (gpio )
76+ {
77+ rt_base_t pin_index = pin - gpio -> pin_start ;
78+
79+ if (!gpio -> ops -> pin_attach_irq )
80+ {
81+ rt_err_t err ;
82+ struct rt_pin_irq_hdr * legacy_isr ;
83+
84+ if ((err = gpio -> ops -> pin_irq_mode (& gpio -> parent , pin_index , mode )))
85+ {
86+ return err ;
87+ }
88+
89+ legacy_isr = & gpio -> legacy_isr [pin_index ];
90+ legacy_isr -> pin = pin_index ;
91+ legacy_isr -> mode = mode ;
92+ legacy_isr -> hdr = hdr ;
93+ legacy_isr -> args = args ;
94+
95+ return RT_EOK ;
96+ }
97+ else
98+ {
99+ return gpio -> ops -> pin_attach_irq (& gpio -> parent , pin_index , mode , hdr , args );
100+ }
101+ }
102+
103+ return - RT_EINVAL ;
104+ }
105+
106+ static rt_err_t pin_api_detach_irq (struct rt_device * device , rt_base_t pin )
107+ {
108+ struct rt_device_pin * gpio = pin_device_find (pin );
109+
110+ if (gpio )
111+ {
112+ rt_base_t pin_index = pin - gpio -> pin_start ;
113+
114+ if (!gpio -> ops -> pin_detach_irq )
115+ {
116+ struct rt_pin_irq_hdr * legacy_isr ;
117+
118+ legacy_isr = & gpio -> legacy_isr [pin_index ];
119+ rt_memset (legacy_isr , 0 , sizeof (* legacy_isr ));
120+
121+ return RT_EOK ;
122+ }
123+ else
124+ {
125+ return gpio -> ops -> pin_detach_irq (& gpio -> parent , pin );
126+ }
127+ }
128+
129+ return - RT_EINVAL ;
130+ }
131+
132+ static rt_err_t pin_api_irq_enable (struct rt_device * device , rt_base_t pin ,
133+ rt_uint8_t enabled )
134+ {
135+ struct rt_device_pin * gpio = pin_device_find (pin );
136+
137+ if (gpio && gpio -> ops -> pin_irq_enable )
138+ {
139+ return gpio -> ops -> pin_irq_enable (& gpio -> parent , pin - gpio -> pin_start , enabled );
140+ }
141+
142+ return - RT_EINVAL ;
143+ }
144+
145+ static rt_base_t pin_api_get (const char * name )
146+ {
147+ rt_base_t res = - RT_EINVAL ;
148+ struct rt_device_pin * gpio ;
149+
150+ rt_spin_lock (& pin_lock );
151+
152+ rt_list_for_each_entry (gpio , & pin_nodes , list )
153+ {
154+ if (gpio -> ops -> pin_get && !(res = gpio -> ops -> pin_get (name )))
155+ {
156+ break ;
157+ }
158+ }
159+
160+ rt_spin_unlock (& pin_lock );
161+
162+ return res ;
163+ }
164+
165+ static rt_err_t pin_api_debounce (struct rt_device * device , rt_base_t pin ,
166+ rt_uint32_t debounce )
167+ {
168+ struct rt_device_pin * gpio = pin_device_find (pin );
169+
170+ if (gpio && gpio -> ops -> pin_debounce )
171+ {
172+ return gpio -> ops -> pin_debounce (& gpio -> parent , pin - gpio -> pin_start , debounce );
173+ }
174+
175+ return - RT_EINVAL ;
176+ }
177+
178+ static rt_err_t pin_api_irq_mode (struct rt_device * device , rt_base_t pin ,
179+ rt_uint8_t mode )
180+ {
181+ struct rt_device_pin * gpio = pin_device_find (pin );
182+
183+ if (gpio && gpio -> ops -> pin_irq_mode )
184+ {
185+ return gpio -> ops -> pin_irq_mode (& gpio -> parent , pin - gpio -> pin_start , mode );
186+ }
187+
188+ return - RT_EINVAL ;
189+ }
190+
191+ static const struct rt_pin_ops pin_api_dm_ops =
192+ {
193+ .pin_mode = pin_api_mode ,
194+ .pin_write = pin_api_write ,
195+ .pin_read = pin_api_read ,
196+ .pin_attach_irq = pin_api_attach_irq ,
197+ .pin_detach_irq = pin_api_detach_irq ,
198+ .pin_irq_enable = pin_api_irq_enable ,
199+ .pin_get = pin_api_get ,
200+ .pin_debounce = pin_api_debounce ,
201+ .pin_irq_mode = pin_api_irq_mode ,
202+ };
203+
204+ rt_err_t pin_api_init (struct rt_device_pin * gpio , rt_size_t pin_nr )
205+ {
206+ rt_err_t err = RT_EOK ;
207+
208+ if (!gpio || !gpio -> ops )
209+ {
210+ return - RT_EINVAL ;
211+ }
212+
213+ rt_spin_lock (& pin_lock );
214+
215+ if (rt_list_isempty (& pin_nodes ))
216+ {
217+ rt_spin_unlock (& pin_lock );
218+ rt_device_pin_register ("gpio" , & pin_api_dm_ops , RT_NULL );
219+ rt_spin_lock (& pin_lock );
220+ }
221+
222+ gpio -> pin_start = pin_total_nr ;
223+ gpio -> pin_nr = pin_nr ;
224+ pin_total_nr += pin_nr ;
225+
226+ rt_list_init (& gpio -> list );
227+ rt_list_insert_before (& pin_nodes , & gpio -> list );
228+
229+ rt_spin_unlock (& pin_lock );
230+
231+ return err ;
232+ }
233+
13234static void pin_dm_irq_mask (struct rt_pic_irq * pirq )
14235{
15236 struct rt_device_pin * gpio = pirq -> pic -> priv_data ;
@@ -78,7 +299,8 @@ static int pin_dm_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
78299 return irq ;
79300}
80301
81- static rt_err_t pin_dm_irq_parse (struct rt_pic * pic , struct rt_ofw_cell_args * args , struct rt_pic_irq * out_pirq )
302+ static rt_err_t pin_dm_irq_parse (struct rt_pic * pic ,
303+ struct rt_ofw_cell_args * args , struct rt_pic_irq * out_pirq )
82304{
83305 rt_err_t err = RT_EOK ;
84306
@@ -95,7 +317,7 @@ static rt_err_t pin_dm_irq_parse(struct rt_pic *pic, struct rt_ofw_cell_args *ar
95317 return err ;
96318}
97319
98- static struct rt_pic_ops pin_dm_ops =
320+ const static struct rt_pic_ops pin_dm_ops =
99321{
100322 .name = "GPIO" ,
101323 .irq_enable = pin_dm_irq_mask ,
@@ -113,13 +335,15 @@ rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin)
113335
114336 if (gpio )
115337 {
338+ rt_ubase_t pin_index = pin ;
116339 struct rt_pin_irqchip * irqchip = & gpio -> irqchip ;
117340
118- if (pin >= irqchip -> pin_range [ 0 ] && pin <= irqchip -> pin_range [ 1 ] )
341+ if (pin_index < gpio -> pin_nr )
119342 {
120343 struct rt_pic_irq * pirq ;
344+ struct rt_pin_irq_hdr * legacy_isr ;
121345
122- pirq = rt_pic_find_irq (& irqchip -> parent , pin - irqchip -> pin_range [ 0 ] );
346+ pirq = rt_pic_find_irq (& irqchip -> parent , pin_index );
123347
124348 if (pirq -> irq >= 0 )
125349 {
@@ -129,6 +353,13 @@ rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin)
129353 {
130354 err = - RT_EINVAL ;
131355 }
356+
357+ legacy_isr = & gpio -> legacy_isr [pin_index ];
358+
359+ if (legacy_isr -> hdr )
360+ {
361+ legacy_isr -> hdr (legacy_isr -> args );
362+ }
132363 }
133364 else
134365 {
@@ -143,32 +374,39 @@ rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin)
143374 return err ;
144375}
145376
146- rt_err_t pin_pic_init (struct rt_device_pin * gpio )
377+ rt_err_t pin_pic_init (struct rt_device_pin * gpio , int pin_irq )
147378{
148379 rt_err_t err ;
149380
150381 if (gpio )
151382 {
152383 struct rt_pin_irqchip * irqchip = & gpio -> irqchip ;
384+ struct rt_pic * pic = & irqchip -> parent ;
153385
154- if (irqchip -> pin_range [0 ] >= 0 && irqchip -> pin_range [1 ] >= irqchip -> pin_range [0 ])
386+ irqchip -> irq = pin_irq ;
387+
388+ if (!gpio -> pin_nr )
155389 {
156- struct rt_pic * pic = & irqchip -> parent ;
157- rt_size_t pin_nr = irqchip -> pin_range [ 1 ] - irqchip -> pin_range [ 0 ] + 1 ;
390+ return - RT_EINVAL ;
391+ }
158392
159- pic -> priv_data = gpio ;
160- pic -> ops = & pin_dm_ops ;
161- /* Make sure the type of gpio for pic */
162- gpio -> parent .parent .type = RT_Object_Class_Device ;
163- rt_pic_default_name (& irqchip -> parent );
393+ gpio -> legacy_isr = rt_calloc (gpio -> pin_nr , sizeof (* gpio -> legacy_isr ));
164394
165- err = rt_pic_linear_irq (pic , pin_nr );
166- rt_pic_user_extends (pic );
167- }
168- else
395+ if (!gpio -> legacy_isr )
169396 {
170- err = - RT_EINVAL ;
397+ return - RT_ENOMEM ;
171398 }
399+
400+ pic -> priv_data = gpio ;
401+ pic -> ops = & pin_dm_ops ;
402+ /* Make sure the type of gpio for pic */
403+ gpio -> parent .parent .type = RT_Object_Class_Device ;
404+ rt_pic_default_name (& irqchip -> parent );
405+
406+ err = rt_pic_linear_irq (pic , gpio -> pin_nr );
407+ rt_pic_user_extends (pic );
408+
409+ err = RT_EOK ;
172410 }
173411 else
174412 {
0 commit comments