1 /*
2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /******************************************************************************
17 * @file dw_gpio.c
18 * @brief CSI Source File for GPIO Driver
19 * @version V1.0
20 * @date 02. June 2017
21 ******************************************************************************/
22
23 #include <csi_config.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include "drv_gpio.h"
27 #include "drv_pmu.h"
28 #include "dw_gpio.h"
29 #include "csi_core.h"
30 #include "pin_name.h"
31 #if defined CONFIG_CHIP_ERAGON3 || defined CONFIG_CHIP_SMARTH_MMU || defined CONFIG_CHIP_SMARTH_610 || defined CONFIG_CHIP_SMARTH_610M
32 #include <drv_intc.h>
33 #endif
34
35 extern int32_t drv_pin_config_mode(port_name_e port, uint8_t offset, gpio_mode_e pin_mode);
36
37 #define ERR_GPIO(errno) (CSI_DRV_ERRNO_GPIO_BASE | errno)
38 #define GPIO_NULL_PARAM_CHK(para) HANDLE_PARAM_CHK(para, ERR_GPIO(DRV_ERROR_PARAMETER))
39
40 typedef void *gpio_port_handle_t;
41
42 typedef struct {
43 #ifdef CONFIG_LPM
44 uint8_t gpio_power_status;
45 uint32_t gpio_regs_saved[7];
46 #endif
47 uint32_t base; ///< handle register base
48 uint32_t irq; ///< irq of this handle
49 uint32_t pin_num; ///< pin number of this handle
50 gpio_mode_e mode; ///< gpio mode
51 gpio_direction_e dir; ///< gpio direction
52 uint32_t mask; ///< gpio mask bit
53 uint32_t value; ///< gpio value
54 } dw_gpio_priv_t;
55
56 typedef struct {
57 uint8_t portidx;
58 uint8_t idx;
59 gpio_event_cb_t cb;
60 } dw_gpio_pin_priv_t;
61
62 extern int32_t target_gpio_port_init(port_name_e port, uint32_t *base, uint32_t *irq, uint32_t *pin_num);
63 extern int32_t target_gpio_pin_init(int32_t gpio_pin, uint32_t *port_idx);
64
65 static dw_gpio_priv_t gpio_handle[CONFIG_GPIO_NUM];
66 static dw_gpio_pin_priv_t gpio_pin_handle[CONFIG_GPIO_PIN_NUM];
67
68 //
69 // Functions
70 //
gpio_set_direction(void * port,gpio_direction_e direction)71 static int32_t gpio_set_direction(
72 void *port,
73 gpio_direction_e direction
74 )
75 {
76 dw_gpio_priv_t *gpio_priv = port;
77 dw_gpio_reg_t *gpio_reg = (dw_gpio_reg_t *)(gpio_priv->base);
78
79 if (direction == GPIO_DIRECTION_INPUT) {
80 gpio_reg->SWPORT_DDR &= (~gpio_priv->mask);
81 } else if (direction == GPIO_DIRECTION_OUTPUT) {
82 gpio_reg->SWPORT_DDR |= gpio_priv->mask;
83 } else {
84 return ERR_GPIO(GPIO_ERROR_DIRECTION);
85 }
86
87 return 0;
88 }
89
90 /*
91 * Read the status of the chosen port.
92 * Parameters:
93 * port: use to chose a I/O port among Port A, B, or C.
94 * return: the value of the corresponding Port.
95 */
96
gpio_read(void * port,uint32_t * value)97 static int32_t gpio_read(void *port, uint32_t *value)
98 {
99 dw_gpio_priv_t *gpio_priv = port;
100 dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(gpio_priv->base + 0x30);
101 *value = gpio_control_reg->EXT_PORTA;
102 return 0;
103 }
104
105
106 /*
107 * Write an output value to corresponding Port.
108 * Parameters:
109 * port: use to choose a I/O port among Port A, B, or C.
110 * output: value that will be written to the corresponding Port.
111 * return: SUCCESS
112 */
113
gpio_write(void * port,uint32_t mask)114 static int32_t gpio_write(void *port, uint32_t mask)
115 {
116 dw_gpio_priv_t *gpio_priv = port;
117 dw_gpio_reg_t *gpio_reg = (dw_gpio_reg_t *)(gpio_priv->base);
118
119 uint32_t value = gpio_reg->SWPORT_DR;
120
121 value &= ~(mask);
122 value |= gpio_priv->value;
123 gpio_reg->SWPORT_DR = value;
124 return 0;
125 }
126
127 /**
128 * Configure a GPIO gpio_set_irq_mode.
129 * @param[in] pin the addr store the pin num.
130 * @param[in] _irqmode the irqmode of gpio
131 * @return zero on success. -1 on failure.
132 */
gpio_set_irq_mode(gpio_pin_handle_t pin,gpio_irq_mode_e irq_mode)133 static int32_t gpio_set_irq_mode(gpio_pin_handle_t pin, gpio_irq_mode_e irq_mode)
134 {
135 dw_gpio_pin_priv_t *gpio_pin_priv = pin;
136
137 /* convert portidx to port handle */
138 dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
139
140 dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
141 uint32_t offset = gpio_pin_priv->idx;
142 uint32_t mask = 1 << offset;
143
144 switch (irq_mode) {
145 /* rising edge interrupt mode */
146 case GPIO_IRQ_MODE_RISING_EDGE:
147 gpio_control_reg->INTTYPE_LEVEL |= mask;
148 gpio_control_reg->INT_POLARITY |= mask;
149 break;
150
151 /* falling edge interrupt mode */
152 case GPIO_IRQ_MODE_FALLING_EDGE:
153 gpio_control_reg->INTTYPE_LEVEL |= mask;
154 gpio_control_reg->INT_POLARITY &= (~mask);
155 break;
156
157 /* low level interrupt mode */
158 case GPIO_IRQ_MODE_LOW_LEVEL:
159 gpio_control_reg->INTTYPE_LEVEL &= (~mask);
160 gpio_control_reg->INT_POLARITY &= (~mask);
161 break;
162
163 /* high level interrupt mode */
164 case GPIO_IRQ_MODE_HIGH_LEVEL:
165 gpio_control_reg->INTTYPE_LEVEL &= (~mask);
166 gpio_control_reg->INT_POLARITY |= mask;
167 break;
168
169 /* double edge interrupt mode */
170 case GPIO_IRQ_MODE_DOUBLE_EDGE:
171 return ERR_GPIO(DRV_ERROR_UNSUPPORTED);
172
173 default:
174 return ERR_GPIO(GPIO_ERROR_IRQ_MODE);
175 }
176
177 return 0;
178 }
179
180 /*
181 * Clear one or more interrupts of PortA.
182 * Parameters:
183 * pinno:
184 * return: SUCCESS.
185 */
186
gpio_irq_clear(gpio_pin_handle_t pin,uint32_t idx)187 static void gpio_irq_clear(gpio_pin_handle_t pin, uint32_t idx)
188 {
189 dw_gpio_pin_priv_t *gpio_pin_priv = pin;
190
191 /* convert portidx to port handle */
192 dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
193
194 dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
195
196 gpio_control_reg->PORTA_EOI = idx;
197 }
198
199
200 /*
201 * Enable one or more interrupts of PortA.
202 * Parameters:
203 * pinno:
204 * return: SUCCESS.
205 */
gpio_irq_enable(gpio_pin_handle_t pin)206 static void gpio_irq_enable(gpio_pin_handle_t pin)
207 {
208 dw_gpio_pin_priv_t *gpio_pin_priv = pin;
209
210 /* convert portidx to port handle */
211 dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
212
213 dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
214 uint32_t offset = gpio_pin_priv->idx;
215 uint32_t val = gpio_control_reg->INTEN;
216 val |= (1 << offset);
217 gpio_control_reg->INTEN = val;
218 }
219
220
221 /*
222 * Disable one or more interrupts of PortA.
223 * Parameters:
224 * pinno:
225 * return: SUCCESS.
226 */
227
gpio_irq_disable(gpio_pin_handle_t pin)228 static void gpio_irq_disable(gpio_pin_handle_t pin)
229 {
230 dw_gpio_pin_priv_t *gpio_pin_priv = pin;
231 uint32_t offset = gpio_pin_priv->idx;
232
233 /* convert portidx to port handle */
234 dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
235
236 dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(port_handle->base + 0x30);
237 uint32_t val = gpio_control_reg->INTEN;
238 val &= ~(1 << offset);
239 gpio_control_reg->INTEN = val;
240 }
241
dw_gpio_irqhandler(int idx)242 void dw_gpio_irqhandler(int idx)
243 {
244 if (idx >= CONFIG_GPIO_NUM) {
245 return;
246 }
247
248 dw_gpio_control_reg_t *gpio_control_reg = (dw_gpio_control_reg_t *)(gpio_handle[idx].base + 0x30);
249
250 uint32_t value = gpio_control_reg->INTSTATUS;
251 uint8_t i;
252
253 /* find the interrupt pin */
254 for (i = 0; i < 32; i++) {
255 if (value & (1U << i)) {
256 uint32_t pin_idx = i;
257
258 #ifndef CONFIG_CHIP_DANICA
259 uint8_t j;
260
261 if (idx > 0) {
262 for (j = 0; j < idx; j++) {
263 pin_idx += gpio_handle[j].pin_num;
264 }
265 }
266
267 if (pin_idx >= CONFIG_GPIO_PIN_NUM) {
268 return;
269 }
270
271 #endif
272 dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)&gpio_pin_handle[pin_idx];
273
274 gpio_irq_clear(gpio_pin_priv, (1 << i)); //clear the gpio interrupt
275
276 /* execute the callback function */
277 if ((gpio_event_cb_t)(gpio_pin_priv->cb)) {
278 ((gpio_event_cb_t)(gpio_pin_priv->cb))(pin_idx);
279 }
280 }
281 }
282 }
283
284 /**
285 \brief Initialize GPIO module. 1. Initializes the resources needed for the GPIO handle 2.registers event callback function
286 3.get gpio_port_handle
287 \param[in] port port_name.
288 \return gpio_port_handle
289 */
csi_gpio_port_initialize(int32_t port)290 gpio_port_handle_t csi_gpio_port_initialize(int32_t port)
291 {
292 dw_gpio_priv_t *gpio_priv = NULL;
293
294 /* obtain the gpio port information */
295 uint32_t base = 0u;
296 uint32_t pin_num;
297 uint32_t irq;
298 int32_t idx = target_gpio_port_init(port, &base, &irq, &pin_num);
299
300 if (idx < 0 || idx >= CONFIG_GPIO_NUM) {
301 return NULL;
302 }
303
304 gpio_priv = &gpio_handle[idx];
305
306 gpio_priv->base = base;
307 gpio_priv->irq = irq;
308 gpio_priv->pin_num = pin_num;
309
310 #ifdef CONFIG_LPM
311 csi_gpio_power_control(gpio_priv, DRV_POWER_FULL);
312 #endif
313
314 #if defined CONFIG_CHIP_ERAGON3 || defined CONFIG_CHIP_SMARTH_MMU || defined CONFIG_CHIP_SMARTH_610 || defined CONFIG_CHIP_SMARTH_610M
315 csi_intc_enable_irq(gpio_priv->irq);
316 #else
317 csi_vic_enable_irq(gpio_priv->irq);
318 #endif
319
320 return (gpio_port_handle_t)gpio_priv;
321 }
322
323 /**
324 \brief De-initialize GPIO handle. stops operation and releases the software resources used by the handle
325 \param[in] handle gpio port handle to operate.
326 \return error code
327 */
csi_gpio_port_uninitialize(gpio_port_handle_t handle)328 int32_t csi_gpio_port_uninitialize(gpio_port_handle_t handle)
329 {
330 GPIO_NULL_PARAM_CHK(handle);
331
332 dw_gpio_priv_t *gpio_priv = handle;
333
334 #if defined CONFIG_CHIP_ERAGON3 || defined CONFIG_CHIP_SMARTH_MMU || defined CONFIG_CHIP_SMARTH_610 || defined CONFIG_CHIP_SMARTH_610M
335 csi_intc_disable_irq(gpio_priv->irq);
336 #else
337 csi_vic_disable_irq(gpio_priv->irq);
338 #endif
339 #ifdef CONFIG_LPM
340 csi_gpio_power_control(gpio_priv, DRV_POWER_OFF);
341 #endif
342
343 return 0;
344 }
345
346 /**
347 \brief config multiple pin within one handle
348 \param[in] handle gpio port handle to operate.
349 \param[in] mask the bitmask to identify which bits in the handle should be included (0 - ignore)
350 \param[in] mode \ref gpio_mode_e
351 \param[in] dir \ref gpio_direction_e
352 \return error code
353 */
csi_gpio_port_config(gpio_port_handle_t handle,uint32_t mask,gpio_mode_e mode,gpio_direction_e dir)354 int32_t csi_gpio_port_config(gpio_port_handle_t handle, uint32_t mask, gpio_mode_e mode, gpio_direction_e dir)
355 {
356 GPIO_NULL_PARAM_CHK(handle);
357
358 dw_gpio_priv_t *gpio_priv = handle;
359
360 /*config the gpio mode direction mask bits */
361 switch (mode) {
362 case GPIO_MODE_PULLNONE:
363 gpio_priv->mode = mode;
364 break;
365
366 case GPIO_MODE_PULLUP:
367 case GPIO_MODE_PULLDOWN:
368 case GPIO_MODE_OPEN_DRAIN:
369 case GPIO_MODE_PUSH_PULL:
370 return ERR_GPIO(DRV_ERROR_UNSUPPORTED);
371
372 default:
373 return ERR_GPIO(GPIO_ERROR_MODE);
374 }
375
376 gpio_priv->dir = dir;
377 gpio_priv->mask = mask;
378 uint32_t ret = gpio_set_direction(gpio_priv, dir);
379
380 return ret;
381 }
382
383 /**
384 \brief Write value to the handle(write value to multiple pins on one handle at the same time)
385 \param[in] handle gpio port handle to operate.
386 \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
387 \param[in] value the value to be set
388 \return error code
389 */
csi_gpio_port_write(gpio_port_handle_t handle,uint32_t mask,uint32_t value)390 int32_t csi_gpio_port_write(gpio_port_handle_t handle, uint32_t mask, uint32_t value)
391 {
392 GPIO_NULL_PARAM_CHK(handle);
393
394 uint32_t port_value = mask & value;
395
396 dw_gpio_priv_t *gpio_priv = handle;
397 gpio_priv->value = port_value;
398 gpio_write(gpio_priv, mask);
399
400 return 0;
401
402 }
403
404 /**
405 \brief Read the current value on the handle(read value of multiple pins on one handle at the same time)
406 \param[in] handle gpio port handle to operate.
407 \param[in] mask The bitmask to identify which bits in the handle should be included (0 - ignore)
408 \param[out] value an integer with each bit corresponding to an associated handle pin setting
409 \return error code
410 */
csi_gpio_port_read(gpio_port_handle_t handle,uint32_t mask,uint32_t * value)411 int32_t csi_gpio_port_read(gpio_port_handle_t handle, uint32_t mask, uint32_t *value)
412 {
413 GPIO_NULL_PARAM_CHK(handle);
414 GPIO_NULL_PARAM_CHK(value);
415
416 uint32_t port_value = 0;
417
418 gpio_read(handle, &port_value);
419 *value = (mask & port_value);
420
421 return 0;
422
423 }
424
425 #ifdef CONFIG_LPM
manage_clock(gpio_pin_handle_t handle,uint8_t enable)426 static void manage_clock(gpio_pin_handle_t handle, uint8_t enable)
427 {
428 dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)handle;
429 uint8_t device[] = {CLOCK_MANAGER_GPIO0, CLOCK_MANAGER_GPIO1};
430
431 drv_clock_manager_config(device[gpio_pin_priv->portidx], enable);
432 }
433
do_prepare_sleep_action(void * handle)434 static void do_prepare_sleep_action(void *handle)
435 {
436 dw_gpio_priv_t *gpio_handle = handle;
437 uint32_t *gbase = (uint32_t *)(gpio_handle->base);
438 uint32_t *control_base = (uint32_t *)(gpio_handle->base + 0x30);
439 registers_save(gpio_handle->gpio_regs_saved, gbase, 3);
440 registers_save(&gpio_handle->gpio_regs_saved[3], control_base, 4);
441 }
442
do_wakeup_sleep_action(void * handle)443 static void do_wakeup_sleep_action(void *handle)
444 {
445 dw_gpio_priv_t *gpio_handle = handle;
446 uint32_t *gbase = (uint32_t *)(gpio_handle->base);
447 uint32_t *control_base = (uint32_t *)(gpio_handle->base + 0x30);
448 registers_restore(gbase, gpio_handle->gpio_regs_saved, 3);
449 registers_restore(control_base, &gpio_handle->gpio_regs_saved[3], 4);
450 }
451 #endif
452
453 /**
454 \brief Initialize GPIO handle.
455 \param[in] gpio_pin Pointer to the int32_t.
456 \param[in] cb_event Pointer to \ref gpio_event_cb_t.
457 \param[in] arg Pointer to \ref arg used for the callback.
458 \return gpio_pin_handle
459 */
csi_gpio_pin_initialize(int32_t gpio_pin,gpio_event_cb_t cb_event)460 gpio_pin_handle_t csi_gpio_pin_initialize(int32_t gpio_pin, gpio_event_cb_t cb_event)
461 {
462
463 if (gpio_pin < 0 || gpio_pin >= CONFIG_GPIO_PIN_NUM) {
464 return NULL;
465 }
466
467 uint32_t i;
468
469 for (i = 0; i < CONFIG_GPIO_NUM; i++) {
470 csi_gpio_port_initialize(i);
471 }
472
473 /* obtain the gpio pin information */
474 uint32_t port_idx;
475 int32_t pin_idx = target_gpio_pin_init(gpio_pin, &port_idx);
476
477 if (pin_idx < 0) {
478 return NULL;
479 }
480
481 int32_t idx = pin_idx;
482
483 for (i = 0; i < port_idx; i++) {
484 idx += (gpio_handle[i].pin_num);
485 }
486
487 dw_gpio_pin_priv_t *gpio_pin_priv = &(gpio_pin_handle[idx]);
488 gpio_pin_priv->portidx = port_idx;
489
490
491 gpio_pin_priv->idx = pin_idx;
492 gpio_pin_priv->cb = cb_event;
493
494 return (gpio_pin_handle_t)gpio_pin_priv;
495 }
496
497 /**
498 \brief De-initialize GPIO pin handle. stops operation and releases the software resources used by the handle
499 \param[in] handle gpio pin handle to operate.
500 \return error code
501 */
csi_gpio_pin_uninitialize(gpio_pin_handle_t handle)502 int32_t csi_gpio_pin_uninitialize(gpio_pin_handle_t handle)
503 {
504 if (handle == NULL) {
505 return ERR_GPIO(DRV_ERROR_PARAMETER);
506 }
507
508 dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)handle;
509 gpio_pin_priv->cb = NULL;
510
511 gpio_irq_disable(handle);
512
513 return 0;
514 }
515
516 /**
517 \brief control gpio power.
518 \param[in] idx gpio index.
519 \param[in] state power state.\ref csi_power_stat_e.
520 \return error code
521 */
csi_gpio_power_control(gpio_pin_handle_t handle,csi_power_stat_e state)522 int32_t csi_gpio_power_control(gpio_pin_handle_t handle, csi_power_stat_e state)
523 {
524 GPIO_NULL_PARAM_CHK(handle);
525
526 #ifdef CONFIG_LPM
527 dw_gpio_pin_priv_t *gpio_pin_priv = (dw_gpio_pin_priv_t *)handle;
528 power_cb_t callback = {
529 .wakeup = do_wakeup_sleep_action,
530 .sleep = do_prepare_sleep_action,
531 .manage_clock = manage_clock
532 };
533 return drv_soc_power_control(&gpio_handle[gpio_pin_priv->portidx], state, &callback);
534 #else
535 return ERR_GPIO(DRV_ERROR_UNSUPPORTED);
536 #endif
537 }
538
539 /**
540 \brief config pin mode
541 \param[in] pin gpio pin handle to operate.
542 \param[in] mode \ref gpio_mode_e
543 \return error code
544 */
csi_gpio_pin_config_mode(gpio_pin_handle_t handle,gpio_mode_e mode)545 int32_t csi_gpio_pin_config_mode(gpio_pin_handle_t handle,
546 gpio_mode_e mode)
547 {
548 GPIO_NULL_PARAM_CHK(handle);
549
550 /* config the gpio pin mode direction mask bits */
551 dw_gpio_pin_priv_t *gpio_pin_priv = handle;
552
553 uint8_t offset = gpio_pin_priv->idx;
554
555 int32_t ret = drv_pin_config_mode(gpio_pin_priv->portidx, offset, mode);
556
557 return ret;
558 }
559 /**
560 \brief config pin direction
561 \param[in] pin gpio pin handle to operate.
562 \param[in] dir \ref gpio_direction_e
563 \return error code
564 */
csi_gpio_pin_config_direction(gpio_pin_handle_t handle,gpio_direction_e dir)565 int32_t csi_gpio_pin_config_direction(gpio_pin_handle_t handle,
566 gpio_direction_e dir)
567 {
568 GPIO_NULL_PARAM_CHK(handle);
569
570 /* config the gpio pin mode direction mask bits */
571 dw_gpio_pin_priv_t *gpio_pin_priv = handle;
572
573 /* convert portidx to port handle */
574 dw_gpio_priv_t *gpio_priv = &gpio_handle[gpio_pin_priv->portidx];
575
576 gpio_priv->dir = dir;
577 gpio_priv->mask = 1 << gpio_pin_priv->idx;
578
579 uint32_t ret = gpio_set_direction(gpio_priv, dir);
580
581 if (ret) {
582 return ret;
583 }
584
585 return 0;
586 }
587
588 /**
589 \brief config pin
590 \param[in] handle gpio pin handle to operate.
591 \param[in] mode \ref gpio_mode_e
592 \param[in] dir \ref gpio_direction_e
593 \return error code
594 */
csi_gpio_pin_config(gpio_pin_handle_t handle,gpio_mode_e mode,gpio_direction_e dir)595 int32_t csi_gpio_pin_config(gpio_pin_handle_t handle,
596 gpio_mode_e mode,
597 gpio_direction_e dir)
598 {
599 GPIO_NULL_PARAM_CHK(handle);
600
601 /* config the gpio pin mode direction mask bits */
602 dw_gpio_pin_priv_t *gpio_pin_priv = handle;
603
604 /* convert portidx to port handle */
605 dw_gpio_priv_t *gpio_priv = &gpio_handle[gpio_pin_priv->portidx];
606
607 gpio_priv->mode = mode;
608 gpio_priv->dir = dir;
609 gpio_priv->mask = 1 << gpio_pin_priv->idx;
610
611 uint32_t ret = gpio_set_direction(gpio_priv, dir);
612
613 if (ret) {
614 return ret;
615 }
616
617 return 0;
618
619 }
620
621 /**
622 \brief Set one or zero to the selected GPIO pin.
623 \param[in] handle gpio pin handle to operate.
624 \param[in] value the value to be set
625 \return error code
626 */
csi_gpio_pin_write(gpio_pin_handle_t handle,bool value)627 int32_t csi_gpio_pin_write(gpio_pin_handle_t handle, bool value)
628 {
629 GPIO_NULL_PARAM_CHK(handle);
630
631 dw_gpio_pin_priv_t *gpio_pin_priv = handle;
632
633 /* convert portidx to port handle */
634 dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
635
636 uint8_t offset = gpio_pin_priv->idx;
637 uint32_t port_value = (uint32_t)value << offset;
638
639 port_handle->value = port_value;
640 gpio_write(port_handle, (1 << offset));
641
642 return 0;
643
644 }
645
646 /**
647 \brief Get the value of selected GPIO pin.
648 \param[in] handle gpio pin handle to operate.
649 \param[out] value buf to store the pin value
650 \return error code
651 */
csi_gpio_pin_read(gpio_pin_handle_t handle,bool * value)652 int32_t csi_gpio_pin_read(gpio_pin_handle_t handle, bool *value)
653 {
654 GPIO_NULL_PARAM_CHK(handle);
655 GPIO_NULL_PARAM_CHK(value);
656
657 dw_gpio_pin_priv_t *gpio_pin_priv = handle;
658 uint32_t port_value;
659 uint8_t offset = gpio_pin_priv->idx;
660
661 /* convert portidx to port handle */
662 dw_gpio_priv_t *port_handle = &gpio_handle[gpio_pin_priv->portidx];
663
664 gpio_read(port_handle, &port_value);
665 *value = (port_value & (1 << offset)) >> offset;
666
667 return 0;
668 }
669
670 /**
671 \brief set GPIO interrupt mode.
672 \param[in] handle gpio pin handle to operate.
673 \param[in] mode the irq mode to be set
674 \param[in] enable the enable flag
675 \return error code
676 */
csi_gpio_pin_set_irq(gpio_pin_handle_t handle,gpio_irq_mode_e mode,bool enable)677 int32_t csi_gpio_pin_set_irq(gpio_pin_handle_t handle, gpio_irq_mode_e mode, bool enable)
678 {
679 GPIO_NULL_PARAM_CHK(handle);
680
681 uint32_t ret = 0;
682
683 if (enable) {
684 ret = gpio_set_irq_mode(handle, mode);
685
686 if (ret) {
687 return ret;
688 }
689
690 gpio_irq_enable(handle);
691
692 } else {
693 gpio_irq_disable(handle);
694
695 }
696
697 return ret;
698
699 }
700