- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# drivers/sdmmc/card_detect.c

Go to the documentation of this file.

    00001
    00045 #include <debug.h>
    00046 #include <delayed_work.h>
    00047 #include <malloc.h>
    00048 #include <slist.h>
    00049 #include <workqueue.h>
    00050 #include <chip/portmux.h>
    00051 #include <gpio/gpio_irq_handler.h>
    00052 #include <sdmmc/sdmmc.h>
    00053
    00054 #include <app/timer.h>
    00055 #include <app/workqueue.h>
    00056
    00063 #define SDMMC_CD_DELAY_US       20000
    00064
    00065 struct sdmmc_cd {
    00066         struct sdmmc_slot               *slot;
    00067         gpio_pin_t                      pin;
    00068         struct workqueue_item           work;
    00069         struct delayed_work             dwork;
    00070         struct gpio_irq_handler         irqh;
    00071 };
    00072
    00073 static void sdmmc_cd_interrupt(void *data)
    00074 {
    00075         struct sdmmc_cd *cd = data;
    00076
    00077         gpio_disable_interrupt(cd->pin);
    00078
    00079         /* Wait for WP and CD signals to stabilize before detecting */
    00080         delayed_work_run_us(&cd->dwork, &cd->work, SDMMC_CD_DELAY_US);
    00081 }
    00082
    00083 static void sdmmc_cd_process(void *data)
    00084 {
    00085         struct sdmmc_cd *cd = data;
    00086         int             value;
    00087
    00088         gpio_clear_int_flag(cd->pin);
    00089         gpio_enable_interrupt(cd->pin);
    00090
    00091         value = !gpio_get_value(cd->pin);
    00092
    00093         dbg_verbose("Notify slot%u card detect %d!\n", cd->slot->id, value);
    00094         sdmmc_slot_notify_card_detect(cd->slot, value);
    00095 }
    00096
    00097 struct sdmmc_cd *sdmmc_cd_init(struct sdmmc_slot *slot, gpio_pin_t pin)
    00098 {
    00099         struct sdmmc_cd *cd;
    00100
    00101         cd = malloc(sizeof(struct sdmmc_cd));
    00102         if (cd == NULL) {
    00103                 dbg_error("sdmmc_cd_init: Out of memory!\n");
    00104                 return NULL;
    00105         }
    00106         cd->slot = slot;
    00107         cd->pin = pin;
    00108         workqueue_init_item(&cd->work, sdmmc_cd_process, cd);
    00109         delayed_work_init(&cd->dwork, &sdmmc_timer, &sdmmc_workqueue);
    00110
    00111         gpio_init_irq_handler(&cd->irqh, pin, sdmmc_cd_interrupt, cd);
    00112
    00113         gpio_register_irq_handler(&cd->irqh);
    00114
    00115         return cd;
    00116 }
    00117
    00118 void sdmmc_cd_enable(struct sdmmc_cd *cd)
    00119 {
    00120         /*
    00121          * Wait for pins to stabilize after power-on, and send initial
    00122          * slot notify event.
    00123          */
    00124         delayed_work_run_us(&cd->dwork, &cd->work, SDMMC_CD_DELAY_US);
    00125 }
    00126