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, 0); //For low power, we switch UART GPIO when power off md mt_set_gpio_mode(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_mode(GPIO_UART_UTXD1_PIN, 0); mt_set_gpio_mode(GPIO_UART_URTS1_PIN, 0); mt_set_gpio_mode(GPIO_UART_UCTS1_PIN, 0); mt_set_gpio_dir(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_URXD1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_dir(GPIO_UART_UTXD1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_UTXD1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_UTXD1_PIN, 0); mt_set_gpio_dir(GPIO_UART_URTS1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_URTS1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_URTS1_PIN, 0); mt_set_gpio_dir(GPIO_UART_UCTS1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_UCTS1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_UCTS1_PIN, 0); EMD_MSG_INF("chr","uart gpio pull down\n"); cm_dump_gpio(); return 0; }
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_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); //For low power, we switch UART GPIO when power off md, so restore here according to dws default setting. mt_set_gpio_mode(GPIO_UART_URXD1_PIN, 1); mt_set_gpio_mode(GPIO_UART_UTXD1_PIN, 1); mt_set_gpio_mode(GPIO_UART_URTS1_PIN, 1); mt_set_gpio_mode(GPIO_UART_UCTS1_PIN, 1); mt_set_gpio_dir(GPIO_UART_URXD1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_URXD1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_URXD1_PIN, 1); mt_set_gpio_dir(GPIO_UART_UTXD1_PIN, 1); mt_set_gpio_out(GPIO_UART_UTXD1_PIN, 1); mt_set_gpio_dir(GPIO_UART_URTS1_PIN, 1); mt_set_gpio_out(GPIO_UART_URTS1_PIN, 1); mt_set_gpio_dir(GPIO_UART_UCTS1_PIN, 0); mt_set_gpio_pull_enable(GPIO_UART_UCTS1_PIN, 1); mt_set_gpio_pull_select(GPIO_UART_UCTS1_PIN, 1); EMD_MSG_INF("chr","uart gpio restore\n"); 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; }
static long emd_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; unsigned int sim_mode=0, boot_mode=0; int value; emd_dev_client_t *client=(emd_dev_client_t *)file->private_data; switch (cmd) { case CCCI_IOC_GET_MD_STATE: EMD_MSG_INF("chr", "Get md state ioctl called by %s\n", current->comm); if(arg!=0) { value = get_curr_emd_state(); value+='0'; // Make number to charactor ret = put_user((unsigned int)value, (unsigned int __user *)arg); }else{ EMD_MSG_INF("chr", "Get md state ioctl: arg is null\n"); } break; case CCCI_IOC_DO_START_MD: EMD_MSG_INF("chr", "Start md ioctl called by %s\n", current->comm); if(copy_from_user(&boot_mode, (void __user *)arg, sizeof(unsigned int))) { EMD_MSG_INF("chr", "CCCI_IOC_DO_START_MD: copy_from_user fail!\n"); ret = -EFAULT; } else { ret = emd_power_on(boot_mode); EMD_MSG_INF("chr", "CCCI_IOC_DO_START_MD,%d\n",boot_mode); } break; case CCCI_IOC_ENTER_MD_DL_MODE: EMD_MSG_INF("chr", "Enter md download md ioctl called by %s\n", current->comm); ret = enter_md_download_mode(); break; case CCCI_IOC_MD_RESET: EMD_MSG_INF("chr", "Reset on md ioctl called by %s\n", current->comm); ret = emd_request_reset(); break; case CCCI_IOC_POWER_ON_MD: EMD_MSG_INF("chr", "Power on md ioctl called by %s\n", current->comm); if(copy_from_user(&boot_mode, (void __user *)arg, sizeof(unsigned int))) { EMD_MSG_INF("chr", "CCCI_IOC_POWER_ON_MD: copy_from_user fail!\n"); ret = -EFAULT; } else { ret = emd_power_on(boot_mode); EMD_MSG_INF("chr", "CCCI_IOC_POWER_ON_MD(%x): %d\n", boot_mode, ret); } break; case CCCI_IOC_ENTER_DEEP_FLIGHT: EMD_MSG_INF("chr", "Enter MD flight mode ioctl called by %s\n", current->comm); ret = emd_send_enter_flight_mode(); break; case CCCI_IOC_LEAVE_DEEP_FLIGHT: EMD_MSG_INF("chr","Leave MD flight mode ioctl called by %s\n", current->comm); ret = emd_send_leave_flight_mode(); break; case CCCI_IOC_GET_MD_ASSERTLOG: emd_aseert_log_wait_timeout=0; EMD_MSG_INF("chr","CCCI_IOC_GET_MD_ASSERTLOG ioctl called by %s, sub_dev=%d\n", current->comm,client->sub_dev_id); if(wait_event_interruptible(emd_aseert_log_wait, emd_aseert_log_wait_timeout) == -ERESTARTSYS) ret = -EINTR; else { EMD_MSG_INF("chr","sub_dev=%d call CCCI_IOC_GET_MD_ASSERTLOG is exit\n", client->sub_dev_id); emd_aseert_log_wait_timeout = 0; } break; case CCCI_IOC_GET_MD_ASSERTLOG_STATUS: EMD_MSG_INF("chr","CCCI_IOC_GET_MD_ASSERTLOG_STATUS ioctl called by %s, sub_dev=%d\n", current->comm,client->sub_dev_id); value = cm_get_assertlog_status(); if (copy_to_user((int *)arg, &value, sizeof(int))) { return -EACCES; } EMD_MSG_INF("chr", "CCCI_IOC_GET_MD_ASSERTLOG_STATUS %d\n", value); break; case CCCI_IOC_SIM_SWITCH: if(copy_from_user(&sim_mode, (void __user *)arg, sizeof(unsigned int))) { EMD_MSG_INF("chr", "IOC_SIM_SWITCH: copy_from_user fail!\n"); ret = -EFAULT; } else { ret = switch_sim_mode(0,(char*)&sim_mode,sizeof(unsigned int));//switch_sim_mode(sim_mode); EMD_MSG_INF("chr", "IOC_SIM_SWITCH(%x): %d\n", sim_mode, ret); } break; case CCCI_IOC_SIM_SWITCH_TYPE: value = get_sim_switch_type(); ret = put_user(value, (unsigned int __user *)arg); break; case CCCI_IOC_STORE_SIM_MODE: EMD_MSG_INF("chr","store sim mode ioctl called by %s!\n", current->comm); if(copy_from_user(&sim_mode, (void __user *)arg, sizeof(unsigned int))) { EMD_MSG_INF("chr","store sim mode fail: copy_from_user fail!\n"); ret = -EFAULT; } else { EMD_MSG_INF("chr","storing sim mode(%d) in kernel space!\n", sim_mode); exec_ccci_kern_func_by_md_id(0, ID_STORE_SIM_SWITCH_MODE, (char *)&sim_mode, sizeof(unsigned int)); } break; case CCCI_IOC_GET_SIM_MODE: EMD_MSG_INF("chr", "get sim mode ioctl called by %s\n", current->comm); exec_ccci_kern_func_by_md_id(0, ID_GET_SIM_SWITCH_MODE, (char *)&sim_mode, sizeof(unsigned int)); ret = put_user(sim_mode, (unsigned int __user *)arg); break; case CCCI_IOC_IGNORE_MD_EXCP: EMD_MSG_INF("chr", "ignore md excp ioctl called by %s\n", current->comm); cm_disable_ext_md_wdt_irq(); cm_disable_ext_md_wakeup_irq(); cm_disable_ext_md_exp_irq(); break; default: ret = -EMD_ERR_UN_DEF_CMD; EMD_MSG_INF("chr","undefined ioctl called by %s\n", current->comm); break; } return ret; }