3333 * Pre-processor Definitions
3434 ****************************************************************************/
3535
36- #ifdef CONFIG_IOEXPANDER_INT_ENABLE
37- #warning "FT2232H doesn't support GPIO Interrupts!"
38- #endif
36+ #define SIM_GPIOCHIP_WDOG_DELAY USEC2TICK(500)
3937
4038/****************************************************************************
4139 * Private Types
@@ -68,6 +66,16 @@ static int sim_ft2232h_gpio_writepin(struct ioexpander_dev_s *dev,
6866 uint8_t pin , bool value );
6967static int sim_ft2232h_gpio_readpin (struct ioexpander_dev_s * dev ,
7068 uint8_t pin , bool * value );
69+
70+ #ifdef CONFIG_IOEXPANDER_INT_ENABLE
71+ static void * sim_ft2232h_gpio_attach (struct ioexpander_dev_s * dev ,
72+ uint16_t pinset ,
73+ ioe_callback_t callback ,
74+ void * arg );
75+ static int sim_ft2232h_gpio_detach (struct ioexpander_dev_s * dev ,
76+ void * handle );
77+ #endif
78+
7179static void sim_ft2232h_deferred_init (FAR void * arg );
7280
7381/****************************************************************************
@@ -82,8 +90,8 @@ static struct ioexpander_ops_s g_sim_ft2232h_gpio_ops =
8290 .ioe_readpin = sim_ft2232h_gpio_readpin ,
8391 .ioe_readbuf = sim_ft2232h_gpio_readpin ,
8492#ifdef CONFIG_IOEXPANDER_INT_ENABLE
85- .ioe_attach = NULL ,
86- .ioe_detach = NULL ,
93+ .ioe_attach = sim_ft2232h_gpio_attach ,
94+ .ioe_detach = sim_ft2232h_gpio_detach ,
8795#endif
8896};
8997
@@ -143,7 +151,47 @@ static int sim_ft2232h_gpio_direction(struct ioexpander_dev_s *dev,
143151static int sim_ft2232h_gpio_option (struct ioexpander_dev_s * dev , uint8_t pin ,
144152 int option , void * val )
145153{
146- return - ENOTSUP ;
154+ struct sim_ft2232h_gpio_dev_s * priv = (struct sim_ft2232h_gpio_dev_s * )dev ;
155+ uint16_t cfgset = 0 ;
156+ int ret = 0 ;
157+
158+ if (option == IOEXPANDER_OPTION_INTCFG )
159+ {
160+ switch ((uintptr_t )val )
161+ {
162+ case IOEXPANDER_VAL_FALLING :
163+ cfgset = GPIOCHIP_LINE_FLAG_FALLING ;
164+ break ;
165+
166+ case IOEXPANDER_VAL_RISING :
167+ cfgset = GPIOCHIP_LINE_FLAG_RISING ;
168+ break ;
169+
170+ case IOEXPANDER_VAL_BOTH :
171+ cfgset = GPIOCHIP_LINE_FLAG_BOTH ;
172+ break ;
173+
174+ case IOEXPANDER_VAL_DISABLE :
175+ cfgset = GPIOCHIP_LINE_FLAG_DISABLE ;
176+ break ;
177+
178+ default :
179+ return - ENOTSUP ;
180+ }
181+
182+ ret = host_ft2232h_gpio_irq_request (priv -> dev , pin , cfgset );
183+ if (ret < 0 )
184+ {
185+ gpioerr ("ERROR: Failed to request event: %s\n" , strerror (errno ));
186+ }
187+ }
188+ else
189+ {
190+ gpioinfo ("ft2232h_gpio io option not support\n" );
191+ return - ENOTSUP ;
192+ }
193+
194+ return ret ;
147195}
148196
149197/****************************************************************************
@@ -192,6 +240,61 @@ static int sim_ft2232h_gpio_readpin(struct ioexpander_dev_s *dev,
192240 return host_ft2232h_gpio_readpin (priv -> dev , pin , value );
193241}
194242
243+ #ifdef CONFIG_IOEXPANDER_INT_ENABLE
244+
245+ /****************************************************************************
246+ * Name: sim_ft2232h_gpio_attach
247+ *
248+ * Returned Value:
249+ * 0 for success, other for fail.
250+ ****************************************************************************/
251+
252+ static void * sim_ft2232h_gpio_attach (struct ioexpander_dev_s * dev ,
253+ ioe_pinset_t pinset ,
254+ ioe_callback_t callback ,
255+ void * arg )
256+ {
257+ struct sim_ft2232h_gpio_dev_s * priv = (struct sim_ft2232h_gpio_dev_s * )dev ;
258+ void * handle = NULL ;
259+ int i ;
260+
261+ for (i = 0 ; i < CONFIG_IOEXPANDER_NPINS ; i ++ )
262+ {
263+ if (pinset & (1 << i ))
264+ {
265+ priv -> cb [i ].cbarg = arg ;
266+ handle = & priv -> cb [i ];
267+ priv -> cb [i ].cbfunc = callback ;
268+ }
269+ }
270+
271+ return handle ;
272+ }
273+
274+ /****************************************************************************
275+ * Name: sim_ft2232h_gpio_detach
276+ *
277+ * Returned Value:
278+ * 0 for success, other for fail.
279+ ****************************************************************************/
280+
281+ static int sim_ft2232h_gpio_detach (struct ioexpander_dev_s * dev , void * handle )
282+ {
283+ struct sim_ft2232h_gpio_dev_s * priv = (struct sim_ft2232h_gpio_dev_s * )dev ;
284+ struct sim_ft2232h_gpio_callback_s * cb = handle ;
285+
286+ if (priv == NULL || cb == NULL )
287+ {
288+ gpioerr ("ERROR: Invalid handle\n" );
289+ return - EINVAL ;
290+ }
291+
292+ cb -> cbfunc = NULL ;
293+ cb -> cbarg = NULL ;
294+ return 0 ;
295+ }
296+ #endif
297+
195298/****************************************************************************
196299 * Name: sim_ft2232h_gpio_register_gpio
197300 *
@@ -242,6 +345,64 @@ sim_ft2232h_gpio_register_gpio(struct sim_ft2232h_gpio_dev_s *priv)
242345 return 0 ;
243346}
244347
348+ /****************************************************************************
349+ * Name: sim_ft2232h_gpio_irq_process
350+ *
351+ * Description:
352+ * work to poll irq event for ft2232h_gpio device
353+ *
354+ * Input Parameters:
355+ * priv - A pointer to instance of sim ft2232h_gpio device.
356+ *
357+ * Returned Value:
358+ * None.
359+ *
360+ ****************************************************************************/
361+
362+ static void sim_ft2232h_gpio_irq_process (struct sim_ft2232h_gpio_dev_s * priv )
363+ {
364+ int line ;
365+
366+ for (line = 0 ; line < FT2232_GPIO_NPINS ; line ++ )
367+ {
368+ if (host_ft2232h_gpio_irq_active (priv -> dev , line ))
369+ {
370+ if (priv -> cb [line ].cbfunc )
371+ {
372+ priv -> cb [line ].cbfunc ((struct ioexpander_dev_s * )priv ,
373+ line , priv -> cb [line ].cbarg );
374+ }
375+ }
376+ }
377+ }
378+
379+ /****************************************************************************
380+ * Name: sim_ft2232h_gpio_interrupt
381+ *
382+ * Description:
383+ * wdog timer function for ft2232h_gpio device
384+ *
385+ * Input Parameters:
386+ * arg - A pointer to instance of sim ft2232h_gpio device.
387+ *
388+ * Returned Value:
389+ * None.
390+ *
391+ ****************************************************************************/
392+
393+ static void sim_ft2232h_gpio_interrupt (wdparm_t arg )
394+ {
395+ struct sim_ft2232h_gpio_dev_s * priv = (struct sim_ft2232h_gpio_dev_s * )arg ;
396+
397+ if (priv )
398+ {
399+ sim_ft2232h_gpio_irq_process (priv );
400+
401+ wd_start (& priv -> wdog , SIM_GPIOCHIP_WDOG_DELAY ,
402+ sim_ft2232h_gpio_interrupt , (wdparm_t )priv );
403+ }
404+ }
405+
245406/****************************************************************************
246407 * Name: sim_ft2232h_deferred_init
247408 *
@@ -306,6 +467,9 @@ int sim_ft2232h_gpio_initialize(uint8_t pins_dir)
306467 return - ENODEV ;
307468 }
308469
470+ wd_start (& priv -> wdog , SIM_GPIOCHIP_WDOG_DELAY ,
471+ sim_ft2232h_gpio_interrupt , (wdparm_t )priv );
472+
309473 g_ft2232h_gpio = (struct ioexpander_dev_s * )priv ;
310474
311475 /* Defer gpio registration to work queue */
0 commit comments