//#include "extmd_mt6252d.h" #include #include #include #include #include #include #include "cust_gpio_usage.h" #ifdef CONFIG_OF #include #include #include #include #else #include #endif #define EMD_MSG_INF(tag, fmt, args...) printk(KERN_ERR "[emd/" tag "]" fmt, ##args) #define POWER_ON_WAIT_RESET_TIME 1000 #define RESET_WAIT_RELEASE_TIME 10 #define POWER_ON_HOLD_TIME 5000 typedef struct _eint_inf{ unsigned int gpio_id; unsigned int irq_id; unsigned int intr_flag; unsigned int debounce_time; unsigned int irq_en_cnt; unsigned int irq_reg; void (*eint_cb)(void); spinlock_t lock; }eint_inf_t; extern void mt_eint_mask(unsigned int eint_num); extern void mt_eint_unmask(unsigned int eint_num); extern void mt_eint_set_hw_debounce(unsigned int eint_num, unsigned int ms); extern void mt_eint_registration(unsigned int eint_num, unsigned int flow, void (EINT_FUNC_PTR)(void), unsigned int is_auto_umask); eint_inf_t ext_md_exp_eint; eint_inf_t ext_md_wdt_eint; eint_inf_t ext_md_wk_eint; atomic_t traffic_on; atomic_t allow_wk_md; static const char *uart_port = "ttyMT1"; //should sync with user space extern unsigned int mtk_uart_freeze_enable(char *port, int enable); void cm_hold_wakeup_md_signal(void); int get_eint_info(const char *name, eint_inf_t *eint_item) { #ifdef CONFIG_OF struct device_node *node; char buf[64]; int ints[2]; if ((NULL==name) || (NULL==eint_item)) { EMD_MSG_INF("chr","%s: get invalid arguments:%p,%p\n", __func__, name, eint_item); return -1; } snprintf(buf, 64, "mediatek, %s-eint", name); EMD_MSG_INF("chr","%s: find:%s\n", __func__, buf); node = of_find_compatible_node(NULL, NULL, buf); if (node) { of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints)); eint_item->gpio_id = ints[0]; eint_item->debounce_time = ints[1]; eint_item->irq_id = irq_of_parse_and_map(node, 0); } else { EMD_MSG_INF("chr","%s: can't find %s\n", __func__, name); return -2; } #endif return 0; } int eint_var_init(void) { memset(&ext_md_exp_eint, 0, sizeof(ext_md_exp_eint)); spin_lock_init(&ext_md_exp_eint.lock); memset(&ext_md_wdt_eint, 0, sizeof(ext_md_wdt_eint)); spin_lock_init(&ext_md_wdt_eint.lock); memset(&ext_md_wk_eint, 0, sizeof(ext_md_wk_eint)); spin_lock_init(&ext_md_wk_eint.lock); #ifdef CONFIG_OF EMD_MSG_INF("chr","%s: CONFIG_OF en\n", __func__); if(get_eint_info("DT_EXT_MD_EXP", &ext_md_exp_eint) != 0) return -1; if(get_eint_info("DT_EXT_MD_WDT", &ext_md_wdt_eint) != 0) return -1; if(get_eint_info("DT_EXT_MD_WK_UP", &ext_md_wk_eint) != 0) return -1; #else EMD_MSG_INF("chr","%s: CONFIG_OF dis\n", __func__); // For exp ext_md_exp_eint.gpio_id = GPIO_EXT_MD_EXP; ext_md_exp_eint.debounce_time = CUST_EINT_DT_EXT_MD_EXP_DEBOUNCE_CN; ext_md_exp_eint.irq_id = CUST_EINT_DT_EXT_MD_EXP_NUM; ext_md_exp_eint.intr_flag = CUST_EINT_DT_EXT_MD_EXP_TYPE; // For wdt ext_md_wdt_eint.gpio_id = GPIO_EXT_MD_WD; ext_md_wdt_eint.debounce_time = CUST_EINT_DT_EXT_MD_WDT_DEBOUNCE_CN; ext_md_wdt_eint.irq_id = CUST_EINT_DT_EXT_MD_WDT_NUM; ext_md_wdt_eint.intr_flag = CUST_EINT_DT_EXT_MD_WDT_TYPE; // For wakeup ext_md_wk_eint.gpio_id = GPIO_EXT_MD_WK_AP; ext_md_wk_eint.debounce_time = CUST_EINT_DT_EXT_MD_WK_UP_DEBOUNCE_CN; ext_md_wk_eint.irq_id = CUST_EINT_DT_EXT_MD_WK_UP_NUM; ext_md_wk_eint.intr_flag = CUST_EINT_DT_EXT_MD_WK_UP_TYPE; #endif EMD_MSG_INF("chr","%s: Eint-EXP(%d,%d,%d,%x)\n", __func__, ext_md_exp_eint.gpio_id, ext_md_exp_eint.debounce_time, \ ext_md_exp_eint.irq_id, ext_md_exp_eint.intr_flag); EMD_MSG_INF("chr","%s: Eint-WDT(%d,%d,%d,%x)\n", __func__, ext_md_wdt_eint.gpio_id, ext_md_wdt_eint.debounce_time, \ ext_md_wdt_eint.irq_id, ext_md_wdt_eint.intr_flag); EMD_MSG_INF("chr","%s: Eint-WK UP(%d,%d,%d,%x)\n", __func__, ext_md_wk_eint.gpio_id, ext_md_wk_eint.debounce_time, \ ext_md_wk_eint.irq_id, ext_md_wk_eint.intr_flag); return 0; } void cm_enable_ext_md_wdt_irq(void) { #ifdef CONFIG_OF unsigned long flags; #endif EMD_MSG_INF("chr","cm_enable_ext_md_wdt_irq:DT_EXT_MD_WD(%d)\n",ext_md_wdt_eint.irq_id); #ifdef CONFIG_OF spin_lock_irqsave(&ext_md_wdt_eint.lock, flags); if(ext_md_wdt_eint.irq_reg) { if(ext_md_wdt_eint.irq_en_cnt==0) { enable_irq(ext_md_wdt_eint.irq_id); ext_md_wdt_eint.irq_en_cnt = 1; } } spin_unlock_irqrestore(&ext_md_wdt_eint.lock, flags); #else mt_eint_unmask(ext_md_wdt_eint.irq_id); #endif } void cm_disable_ext_md_wdt_irq(void) { #ifdef CONFIG_OF unsigned long flags; #endif EMD_MSG_INF("chr","cm_disable_ext_md_wdt_irq:CUST_EINT_DT_EXT_MD_WDT_NUM(%d)!\n",ext_md_wdt_eint.irq_id); #ifdef CONFIG_OF spin_lock_irqsave(&ext_md_wdt_eint.lock, flags); if(ext_md_wdt_eint.irq_reg) { if(ext_md_wdt_eint.irq_en_cnt>0) { disable_irq_nosync(ext_md_wdt_eint.irq_id); ext_md_wdt_eint.irq_en_cnt = 0; } } spin_unlock_irqrestore(&ext_md_wdt_eint.lock, flags); #else mt_eint_mask(ext_md_wdt_eint.irq_id); #endif } void cm_enable_ext_md_wakeup_irq(void) { #ifdef CONFIG_OF unsigned long flags; #endif EMD_MSG_INF("chr","cm_enable_ext_md_wakeup_irq,CUST_EINT_DT_EXT_MD_WK_UP_NUM(%d)\n",ext_md_wk_eint.irq_id); #ifdef CONFIG_OF spin_lock_irqsave(&ext_md_wk_eint.lock, flags); if(ext_md_wk_eint.irq_reg) { if(ext_md_wk_eint.irq_en_cnt==0) { enable_irq(ext_md_wk_eint.irq_id); ext_md_wk_eint.irq_en_cnt = 1; } } spin_unlock_irqrestore(&ext_md_wk_eint.lock, flags); #else mt_eint_unmask(ext_md_wk_eint.irq_id); #endif } void cm_disable_ext_md_wakeup_irq(void) { #ifdef CONFIG_OF unsigned long flags; #endif EMD_MSG_INF("chr","cm_disable_ext_md_wakeup_irq,CUST_EINT_DT_EXT_MD_WK_UP_NUM(%d)\n",ext_md_wk_eint.irq_id); #ifdef CONFIG_OF spin_lock_irqsave(&ext_md_wk_eint.lock, flags); if(ext_md_wk_eint.irq_reg) { if(ext_md_wk_eint.irq_en_cnt>0) { disable_irq_nosync(ext_md_wk_eint.irq_id); ext_md_wk_eint.irq_en_cnt = 0; } } spin_unlock_irqrestore(&ext_md_wk_eint.lock, flags); #else mt_eint_mask(ext_md_wk_eint.irq_id); #endif } void cm_enable_ext_md_exp_irq(void) { #ifdef CONFIG_OF unsigned long flags; #endif EMD_MSG_INF("chr","cm_enable_ext_md_exp_irq,CUST_EINT_DT_EXT_MD_EXP_NUM(%d)\n",ext_md_exp_eint.irq_id); #ifdef CONFIG_OF spin_lock_irqsave(&ext_md_exp_eint.lock, flags); if(ext_md_exp_eint.irq_reg) { if(ext_md_exp_eint.irq_en_cnt==0) { enable_irq(ext_md_exp_eint.irq_id); ext_md_exp_eint.irq_en_cnt = 1; } } spin_unlock_irqrestore(&ext_md_exp_eint.lock, flags); #else mt_eint_unmask(ext_md_exp_eint.irq_id); #endif } void cm_disable_ext_md_exp_irq(void) { #ifdef CONFIG_OF unsigned long flags; #endif EMD_MSG_INF("chr","cm_disable_ext_md_exp_irq,CUST_EINT_DT_EXT_MD_EXP_NUM(%d)\n",ext_md_exp_eint.irq_id); #ifdef CONFIG_OF spin_lock_irqsave(&ext_md_exp_eint.lock, flags); if(ext_md_exp_eint.irq_reg) { if(ext_md_exp_eint.irq_en_cnt>0) { disable_irq_nosync(ext_md_exp_eint.irq_id); ext_md_exp_eint.irq_en_cnt = 0; } } spin_unlock_irqrestore(&ext_md_exp_eint.lock, flags); #else mt_eint_mask(ext_md_exp_eint.irq_id); #endif } void cm_hold_rst_signal(void) { EMD_MSG_INF("chr","cm_hold_rst_signal1:GPIO_EXT_MD_RST(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); mt_set_gpio_dir(GPIO_EXT_MD_RST, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_RST, 0); EMD_MSG_INF("chr","cm_hold_rst_signal2:set evb GPIO_EXT_MD_RST(out)=%d!\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); #else mt_set_gpio_out(GPIO_EXT_MD_RST, 1); EMD_MSG_INF("chr","cm_hold_rst_signal2:set phone GPIO_EXT_MD_RST(out)=%d!\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); #endif } void cm_relese_rst_signal(void) { EMD_MSG_INF("chr","cm_relese_rst_signal1:GPIO_EXT_MD_RST(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); mt_set_gpio_dir(GPIO_EXT_MD_RST, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_RST, 1); EMD_MSG_INF("chr","cm_relese_rst_signal2:GPIO_EXT_MD_RST(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_RST)); mt_set_gpio_pull_enable(GPIO_EXT_MD_RST, 1); mt_set_gpio_dir(GPIO_EXT_MD_RST, 0); mt_set_gpio_pull_select(GPIO_EXT_MD_RST, 1); EMD_MSG_INF("chr","cm_relese_rst_signal3:set evb GPIO_EXT_MD_RST(in)=%d!\n",mt_get_gpio_in(GPIO_EXT_MD_RST)); #else mt_set_gpio_out(GPIO_EXT_MD_RST, 0); EMD_MSG_INF("chr","cm_relese_rst_signal3:set phoneGPIO_EXT_MD_RST(in)=%d!\n",mt_get_gpio_in(GPIO_EXT_MD_RST)); #endif } static int is_hold_rst=0; static int ignore_wdt_interrupt = 0; int cm_do_md_go(void) { int ret = -1; if (is_hold_rst) { is_hold_rst=0; unsigned int retry = 100; EMD_MSG_INF("chr","cm_do_md_go:1\n"); EMD_MSG_INF("chr","cm_do_md_go2:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); cm_relese_rst_signal(); EMD_MSG_INF("chr","cm_do_md_go3:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); // Check WDT pin to high while(retry>0){ retry--; if(mt_get_gpio_in(GPIO_EXT_MD_WD)==0) { msleep(10); } else { ret=100-retry; break; } } atomic_set(&traffic_on, 1); msleep(1000); // for use AP_WK_MD as EXT_MD_META, give 6261 bootloader sometime to read boot mode atomic_set(&allow_wk_md, 1); cm_hold_wakeup_md_signal(); EMD_MSG_INF("chr","cm_do_md_go4:GPIO_EXT_MD_RST(out)=%d,GPIO_EXT_MD_WD(in)=%d\n",mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_in(GPIO_EXT_MD_WD)); msleep(POWER_ON_HOLD_TIME); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); } mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 1); cm_enable_ext_md_wdt_irq(); cm_enable_ext_md_wakeup_irq(); cm_enable_ext_md_exp_irq(); //msleep(50); // WDT IRQ is level triggered now, no need this debounce ignore_wdt_interrupt = 0; return ret; } #ifdef CONFIG_MTK_DT_USB_SUPPORT #ifdef CONFIG_PM_RUNTIME void usb11_auto_resume(void); #endif #endif int cm_enter_md_download_mode(void) { #ifdef CONFIG_MTK_DT_USB_SUPPORT #ifdef CONFIG_PM_RUNTIME /* make sure usb device tree is waked up so that usb is ready */ usb11_auto_resume(); #endif #endif EMD_MSG_INF("chr","cm_do_md_power_on:set GPIO_EXT_MD_DL_KEY(%d)\n",GPIO_EXT_MD_DL_KEY); // Press download key to let md can enter download mode mt_set_gpio_dir(GPIO_EXT_MD_DL_KEY, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 0); EMD_MSG_INF("chr","cm_do_md_power_on:set evb GPIO_EXT_MD_DL_KEY=%d\n",mt_get_gpio_out(GPIO_EXT_MD_DL_KEY)); #else mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 1); EMD_MSG_INF("chr","cm_do_md_power_on:set phone GPIO_EXT_MD_DL_KEY=%d\n",mt_get_gpio_out(GPIO_EXT_MD_DL_KEY)); #endif mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 0); // Press power key mt_set_gpio_dir(GPIO_EXT_MD_PWR_KEY, 1); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 1); msleep(POWER_ON_WAIT_RESET_TIME); ignore_wdt_interrupt = 1; cm_hold_rst_signal(); msleep(RESET_WAIT_RELEASE_TIME); cm_relese_rst_signal(); // Hold on msleep(POWER_ON_HOLD_TIME); cm_enable_ext_md_wdt_irq(); cm_enable_ext_md_wakeup_irq(); cm_enable_ext_md_exp_irq(); return 0; } int cm_do_md_power_on(int bootmode) { EMD_MSG_INF("chr","cm_do_md_power_on\n"); cm_disable_ext_md_wdt_irq(); cm_disable_ext_md_wakeup_irq(); cm_disable_ext_md_exp_irq(); // Release download key to let md can enter normal boot mt_set_gpio_dir(GPIO_EXT_MD_DL_KEY, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 1); EMD_MSG_INF("chr","cm_do_md_power_on:set evb GPIO_EXT_MD_DL_KEY=%d\n",mt_get_gpio_out(GPIO_EXT_MD_DL_KEY)); #else mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 0); EMD_MSG_INF("chr","cm_do_md_power_on:set phone GPIO_EXT_MD_DL_KEY=%d\n",mt_get_gpio_out(GPIO_EXT_MD_DL_KEY)); #endif mt_set_gpio_dir(GPIO_EXT_MD_PWR_KEY, 1); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 1); msleep(POWER_ON_WAIT_RESET_TIME); ignore_wdt_interrupt = 1; cm_hold_rst_signal(); is_hold_rst = 1; EMD_MSG_INF("chr","cm_do_md_power_on:reset GPIO_EXT_MD_DL_KEY(%d),GPIO_EXT_MD_PWR_KEY(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_DL_KEY),mt_get_gpio_out(GPIO_EXT_MD_PWR_KEY)); if(bootmode) { #ifndef GPIO_EXT_USB_SW2 mt_set_gpio_dir(GPIO_EXT_MD_META, 1); mt_set_gpio_out(GPIO_EXT_MD_META, 1); EMD_MSG_INF("chr","cm_do_md_power_on:meta mode,phone GPIO_EXT_MD_META(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_META)); #else mt_set_gpio_pull_enable(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_out(GPIO_EXT_MD_DUMP, 1); EMD_MSG_INF("chr","cm_do_md_power_on:meta mode,evb GPIO_EXT_MD_DUMP(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_DUMP)); #endif } else { #ifndef GPIO_EXT_USB_SW2 mt_set_gpio_dir(GPIO_EXT_MD_META, 1); mt_set_gpio_out(GPIO_EXT_MD_META, 0); EMD_MSG_INF("chr","cm_do_md_power_on,phone GPIO_EXT_MD_META(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_META)); #else mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_out(GPIO_EXT_MD_DUMP, 0); EMD_MSG_INF("chr","cm_do_md_power_on,evb GPIO_EXT_MD_DUMP(%d)\n",mt_get_gpio_out(GPIO_EXT_MD_DUMP)); #endif } mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_dir(GPIO_EXT_MD_EXP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_EXP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_EXP, 1); mtk_uart_freeze_enable(uart_port,1); msleep(RESET_WAIT_RELEASE_TIME); msleep(270); EMD_MSG_INF("chr","cm_do_md_power_on: GPIO_EXT_MD_EXP(%d),GPIO_EXT_MD_WD(%d),GPIO_EXT_MD_RST(%d),GPIO_EXT_MD_PWR_KEY(%d)\n", \ mt_get_gpio_in(GPIO_EXT_MD_EXP),mt_get_gpio_in(GPIO_EXT_MD_WD),mt_get_gpio_out(GPIO_EXT_MD_RST),mt_get_gpio_out(GPIO_EXT_MD_PWR_KEY)); return 0; } void cm_dump_gpio(void) { unsigned int pin =0; pin=GPIO_EXT_MD_DL_KEY; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_DL_KEY: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_PWR_KEY; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_PWR_KEY: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_RST; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_RST: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_WD; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_WD: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_WK_AP; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_WK_AP: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_AP_WK_MD; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_AP_WK_MD: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_EXP; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_EXP: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); pin=GPIO_EXT_MD_DUMP; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_DUMP: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); #ifndef GPIO_EXT_USB_SW2 pin=GPIO_EXT_MD_META; EMD_MSG_INF("chr","cm_dump_gpio:GPIO_EXT_MD_META: dir(%d) in(%d),out(%d)\n", \ mt_get_gpio_dir(pin), mt_get_gpio_in(pin), mt_get_gpio_out(pin)); #endif } int cm_do_md_power_off(void) { EMD_MSG_INF("chr","cm_do_md_power_off\n"); atomic_set(&traffic_on, 0); atomic_set(&allow_wk_md, 0); // Release download key to let md can enter normal boot mt_set_gpio_dir(GPIO_EXT_MD_DL_KEY, 1); #ifdef GPIO_EXT_USB_SW2 mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 0);//set evb #else mt_set_gpio_out(GPIO_EXT_MD_DL_KEY, 1);//set phone #endif cm_disable_ext_md_wdt_irq(); cm_disable_ext_md_wakeup_irq(); cm_disable_ext_md_exp_irq(); mt_set_gpio_dir(GPIO_EXT_AP_WK_MD, 1); mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 0); #ifndef GPIO_EXT_USB_SW2 mt_set_gpio_dir(GPIO_EXT_MD_META, 1); mt_set_gpio_out(GPIO_EXT_MD_META, 0); #endif mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); //EMD_MSG_INF("chr","cm_do_md_power_off:GPIO_EXT_MD_PWR_KEY(%d)2\n",mt_get_gpio_out(GPIO_EXT_MD_PWR_KEY)); mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_dir(GPIO_EXT_MD_EXP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_EXP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_EXP, 0); mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 0); mt_set_gpio_pull_enable(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_DUMP, 1); cm_dump_gpio(); return 0; } void cm_hold_wakeup_md_signal(void) { if(atomic_read(&allow_wk_md)) { EMD_MSG_INF("chr","cm_hold_wakeup_md_signal:GPIO_EXT_AP_WK_MD=%d,0!\n",mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 0); } else { EMD_MSG_INF("chr","cm_hold_wakeup_md_signal:GPIO_EXT_AP_WK_MD=%d,ignore!\n",mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); } } void cm_release_wakeup_md_signal(void) { if(atomic_read(&allow_wk_md)) { mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 1); EMD_MSG_INF("chr","cm_release_wakeup_md_signal:GPIO_EXT_AP_WK_MD=%d,1!\n",mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); } else { EMD_MSG_INF("chr","cm_release_wakeup_md_signal:GPIO_EXT_AP_WK_MD=%d,ignore!\n",mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); } } int is_traffic_on(int type) { return atomic_read(&traffic_on); } void cm_gpio_setup(void) { EMD_MSG_INF("chr","cm_gpio_setup 1\n"); atomic_set(&traffic_on, 0); atomic_set(&allow_wk_md, 0); // MD wake up AP pin mt_set_gpio_pull_enable(GPIO_EXT_MD_WK_AP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_dir(GPIO_EXT_MD_WK_AP, 0); mt_set_gpio_mode(GPIO_EXT_MD_WK_AP, GPIO_EXT_MD_WK_AP_M_EINT); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_MD_WK_AP(%x)=%d\n",GPIO_EXT_MD_WK_AP,mt_get_gpio_out(GPIO_EXT_MD_WK_AP)); // AP wake up MD pin mt_set_gpio_mode(GPIO_EXT_AP_WK_MD, GPIO_EXT_AP_WK_MD_M_GPIO); // GPIO Mode mt_set_gpio_dir(GPIO_EXT_AP_WK_MD, 1); mt_set_gpio_out(GPIO_EXT_AP_WK_MD, 0); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_AP_WK_MD(%x)=%d\n",GPIO_EXT_AP_WK_MD,mt_get_gpio_out(GPIO_EXT_AP_WK_MD)); // Rest MD pin mt_set_gpio_mode(GPIO_EXT_MD_RST, GPIO_EXT_MD_RST_M_GPIO); //GPIO202 is reset pin mt_set_gpio_pull_enable(GPIO_EXT_MD_RST, 0); mt_set_gpio_pull_select(GPIO_EXT_MD_RST, 1); cm_relese_rst_signal(); EMD_MSG_INF("chr","cm_gpio_setup 4\n"); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_MD_RST(%x)=%d\n",GPIO_EXT_MD_RST,mt_get_gpio_out(GPIO_EXT_MD_RST)); // MD power key pin mt_set_gpio_mode(GPIO_EXT_MD_PWR_KEY, GPIO_EXT_MD_PWR_KEY_M_GPIO); //GPIO 200 is power key mt_set_gpio_pull_enable(GPIO_EXT_MD_PWR_KEY, 0); mt_set_gpio_dir(GPIO_EXT_MD_PWR_KEY, 1); mt_set_gpio_out(GPIO_EXT_MD_PWR_KEY, 0); EMD_MSG_INF("chr","cm_gpio_setup:GPIO_EXT_MD_PWR_KEY(%x)=%d\n",GPIO_EXT_MD_PWR_KEY,mt_get_gpio_out(GPIO_EXT_MD_PWR_KEY)); // MD WDT irq pin mt_set_gpio_pull_enable(GPIO_EXT_MD_WD, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_WD, 1); mt_set_gpio_dir(GPIO_EXT_MD_WD, 0); mt_set_gpio_mode(GPIO_EXT_MD_WD, GPIO_EXT_MD_WD_M_EINT); // EINT168 EMD_MSG_INF("chr","cm_gpio_setup GPIO_EXT_MD_WD(%x)(in)=%d\n",GPIO_EXT_MD_WD,mt_get_gpio_in(GPIO_EXT_MD_WD)); // MD Exception irq pin mt_set_gpio_pull_enable(GPIO_EXT_MD_EXP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_EXP, 1); mt_set_gpio_dir(GPIO_EXT_MD_EXP, 0); mt_set_gpio_mode(GPIO_EXT_MD_EXP, GPIO_EXT_MD_EXP_M_EINT); // EMD_MSG_INF("chr","cm_gpio_setup GPIO_EXT_MD_EXP(%x)(in)=%d\n",GPIO_EXT_MD_EXP,mt_get_gpio_in(GPIO_EXT_MD_EXP)); #ifndef GPIO_EXT_USB_SW2 mt_set_gpio_mode(GPIO_EXT_MD_META, GPIO_EXT_MD_META_M_GPIO); mt_set_gpio_dir(GPIO_EXT_MD_META, 1);// Using input floating mt_set_gpio_out(GPIO_EXT_MD_META, 0);// Default @ reset state EMD_MSG_INF("chr","cm_gpio_setup:phone GPIO_EXT_MD_META(%x)=%d\n",GPIO_EXT_MD_META,mt_get_gpio_out(GPIO_EXT_MD_META)); #else mt_set_gpio_pull_enable(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_pull_select(GPIO_EXT_MD_DUMP, 0); mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 1); mt_set_gpio_mode(GPIO_EXT_MD_DUMP, GPIO_EXT_MD_DUMP_M_GPIO); EMD_MSG_INF("chr","cm_gpio_setup:evb GPIO_EXT_MD_DUMP(%x)(in)=(%d)\n",GPIO_EXT_MD_DUMP,mt_get_gpio_in(GPIO_EXT_MD_DUMP)); #endif // Configure eint eint_var_init(); } void cm_ext_md_rst(void) { EMD_MSG_INF("chr","TODO: Dummy cm_ext_md_rst!\n"); } irqreturn_t ext_md_exp_eint_handler(unsigned irq, struct irq_desc *desc) { if(ext_md_exp_eint.eint_cb) ext_md_exp_eint.eint_cb(); if(ext_md_exp_eint.irq_en_cnt) { disable_irq_nosync(irq); ext_md_exp_eint.irq_en_cnt = 0; } return IRQ_HANDLED; } irqreturn_t ext_md_wk_eint_handler(unsigned irq, struct irq_desc *desc) { if(ext_md_wk_eint.eint_cb) ext_md_wk_eint.eint_cb(); if(ext_md_wk_eint.irq_en_cnt) { disable_irq_nosync(irq); ext_md_wk_eint.irq_en_cnt = 0; } return IRQ_HANDLED; } irqreturn_t ext_md_wdt_eint_handler(unsigned irq, struct irq_desc *desc) { if (ignore_wdt_interrupt){ EMD_MSG_INF("chr","emd_wdt-eint ignored\n"); return IRQ_HANDLED; } if(ext_md_wdt_eint.eint_cb) ext_md_wdt_eint.eint_cb(); if(ext_md_wdt_eint.irq_en_cnt) { disable_irq_nosync(irq); ext_md_wdt_eint.irq_en_cnt = 0; } return IRQ_HANDLED; } int cm_register_irq_cb(int type, void(*irq_cb)(void)) { #ifdef CONFIG_OF unsigned long flags; int ret=0; #endif switch(type) { case 0: //--- Ext MD wdt irq ------- #ifdef CONFIG_OF mt_gpio_set_debounce(ext_md_wdt_eint.irq_id, ext_md_wdt_eint.debounce_time*1000); spin_lock_irqsave(&ext_md_wdt_eint.lock, flags); ext_md_wdt_eint.eint_cb = irq_cb; ext_md_wdt_eint.irq_reg = 1; ext_md_wdt_eint.irq_en_cnt=1; spin_unlock_irqrestore(&ext_md_wdt_eint.lock, flags); ret = request_irq(ext_md_wdt_eint.irq_id, ext_md_wdt_eint_handler, IRQF_TRIGGER_NONE, "emd_wdt-eint", NULL); if(ret != 0) { EMD_MSG_INF("chr","emd_wdt-eint register fail\n"); spin_lock_irqsave(&ext_md_wdt_eint.lock, flags); ext_md_wdt_eint.eint_cb = NULL; ext_md_wdt_eint.irq_reg = 0; ext_md_wdt_eint.irq_en_cnt=0; spin_unlock_irqrestore(&ext_md_wdt_eint.lock, flags); } #else cm_disable_ext_md_wdt_irq(); mt_eint_set_hw_debounce(ext_md_wdt_eint.irq_id, ext_md_wdt_eint.debounce_time); mt_eint_registration(ext_md_wdt_eint.irq_id, ext_md_wdt_eint.intr_flag, irq_cb, 0); #endif break; case 1: //--- Ext MD wake up irq ------------ #ifdef CONFIG_OF mt_gpio_set_debounce(ext_md_wk_eint.irq_id, ext_md_wk_eint.debounce_time*1000); spin_lock_irqsave(&ext_md_wk_eint.lock, flags); ext_md_wk_eint.eint_cb = irq_cb; ext_md_wk_eint.irq_reg = 1; ext_md_wk_eint.irq_en_cnt=1; spin_unlock_irqrestore(&ext_md_wk_eint.lock, flags); ret = request_irq(ext_md_wk_eint.irq_id, ext_md_wk_eint_handler, IRQF_TRIGGER_NONE, "emd_wkup-eint", NULL); if(ret != 0) { EMD_MSG_INF("chr","emd_wkup-eint register fail\n"); spin_lock_irqsave(&ext_md_wk_eint.lock, flags); ext_md_wk_eint.eint_cb = NULL; ext_md_wk_eint.irq_reg = 0; ext_md_wk_eint.irq_en_cnt=0; spin_unlock_irqrestore(&ext_md_wk_eint.lock, flags); } #else cm_disable_ext_md_wakeup_irq(); mt_eint_set_hw_debounce(ext_md_wk_eint.irq_id, ext_md_wk_eint.debounce_time); mt_eint_registration(ext_md_wk_eint.irq_id, ext_md_wk_eint.intr_flag, irq_cb, 0); #endif break; case 2: //--- Ext MD exception irq ------------ #ifdef CONFIG_OF mt_gpio_set_debounce(ext_md_exp_eint.irq_id, ext_md_exp_eint.debounce_time*1000); spin_lock_irqsave(&ext_md_exp_eint.lock, flags); ext_md_exp_eint.eint_cb = irq_cb; ext_md_exp_eint.irq_reg = 1; ext_md_exp_eint.irq_en_cnt=1; spin_unlock_irqrestore(&ext_md_exp_eint.lock, flags); ret = request_irq(ext_md_exp_eint.irq_id, ext_md_exp_eint_handler, IRQF_TRIGGER_NONE, "emd_exp-eint", NULL); if(ret != 0) { EMD_MSG_INF("chr","emd_exp-eint register fail\n"); spin_lock_irqsave(&ext_md_exp_eint.lock, flags); ext_md_exp_eint.eint_cb = NULL; ext_md_exp_eint.irq_reg = 0; ext_md_exp_eint.irq_en_cnt=0; spin_unlock_irqrestore(&ext_md_exp_eint.lock, flags); } #else cm_disable_ext_md_exp_irq(); mt_eint_set_hw_debounce(ext_md_exp_eint.irq_id, ext_md_exp_eint.debounce_time); mt_eint_registration(ext_md_exp_eint.irq_id, ext_md_exp_eint.intr_flag, irq_cb, 0); #endif break; default: EMD_MSG_INF("chr","No support irq!!\n"); break; } return 0; } int cm_get_assertlog_status(void) { int val; mt_set_gpio_dir(GPIO_EXT_MD_DUMP, 0); val = mt_get_gpio_in(GPIO_EXT_MD_DUMP); EMD_MSG_INF("chr","cm_get_assertlog_status:GPIO_EXT_MD_EXP(in)=%d!\n",val); return val; }