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
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
00122
00123
00124 delayed_work_run_us(&cd->dwork, &cd->work, SDMMC_CD_DELAY_US);
00125 }
00126