static void modem_detect(struct work_struct *work) { struct cbp_reset *cbp_rst_ind = NULL; int ret; int level = 0; LOGPRT(LOG_NOTICE, "%s %d .\n",__func__,__LINE__); cbp_rst_ind = container_of(work, struct cbp_reset, reset_work); if((cbp_rst_ind->host == NULL)){/*for first detection and ipoh*/ LOGPRT(LOG_NOTICE, "%s %d modem_detect_card.\n",__func__,__LINE__); ret = modem_detect_card(cbp_rst_ind); if (ret){ LOGPRT(LOG_ERR, "%s: modem detect failed.\n", __func__); } } else{/*for device reset*/ level = !!oem_gpio_get_value(cbp_rst_ind->rst_ind_gpio); if(level == cbp_rst_ind->rst_ind_polar){ LOGPRT(LOG_NOTICE, "%s %d power on sdio host\n", __func__, __LINE__); oem_wake_host(1); } else{ LOGPRT(LOG_NOTICE, "%s %d power off sdio host\n", __func__, __LINE__); //oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 1); modem_reset_handler(); oem_wake_host(0); } } }
static irqreturn_t modem_reset_indication_irq(int irq, void *data) { if(GPIO_OEM_VALID(cbp_rst_ind_gpio )){ printk("%s %d oem_gpio_get_value(GPIO_VIATEL_MDM_RST_IND)=%d \n",__func__,__LINE__,oem_gpio_get_value(cbp_rst_ind_gpio)); if(oem_gpio_get_value(cbp_rst_ind_gpio)){ if(first_irq_flag == 1){ printk("%s %d first irq read rest_gpio is high,return. \n",__func__,__LINE__); return IRQ_HANDLED; } wake_lock_timeout(&vmdata->wlock, MDM_RST_LOCK_TIME * HZ); modem_notify_event(MDM_EVT_NOTIFY_RESET_ON); via_modem_state = MODEM_STATE_POWER; via_monitor_uevent_notify(MODEM_STATE_POWER); }else{ if(first_irq_flag == 1){ printk("%s %d set first_irq_flag=0. \n",__func__,__LINE__); first_irq_flag = 0; } modem_notify_event(MDM_EVT_NOTIFY_RESET_OFF); } } irq_set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); gpio_irq_cbp_rst_ind(); oem_gpio_irq_unmask(cbp_rst_ind_gpio); return IRQ_HANDLED; }
static irqreturn_t gpio_irq_flow_ctrl(int irq, void *data) { struct cbp_wait_event *cbp_flow_ctrl = (struct cbp_wait_event *)data; int level; //hr_t1 = sched_clock(); level = !!oem_gpio_get_value(cbp_flow_ctrl->wait_gpio); //oem_gpio_set_irq_type(cbp_flow_ctrl->wait_gpio, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING); //oem_gpio_set_irq_type(cbp_flow_ctrl->wait_gpio, IRQF_TRIGGER_FALLING ); //oem_gpio_set_irq_type(cbp_flow_ctrl->wait_gpio, IRQ_TYPE_LEVEL_LOW |IRQ_TYPE_LEVEL_HIGH); oem_gpio_irq_unmask(cbp_flow_ctrl->wait_gpio); if(level == cbp_flow_ctrl->wait_polar){ atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_ENABLE); //LOGPRT(LOG_DEBUG, "%s: flow control is enable, please write later!\n", __func__); } else{ atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE); //LOGPRT(LOG_DEBUG, "%s: %d flow control is disable, can write now!\n", __func__,flw_count); wake_up(&cbp_flow_ctrl->wait_q); } //hr_t2 = sched_clock(); //printk("[sdio] t1=%llu,t2 =%llu,delta=%llu \n",hr_t1, hr_t2, hr_t2-hr_t1); return IRQ_HANDLED; }
ssize_t modem_reset_show( struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int reset = 0; int ret = 0; if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST_IND)){ reset = !!oem_gpio_get_value(GPIO_VIATEL_MDM_RST_IND); }else if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){ reset = !!oem_gpio_get_value(GPIO_VIATEL_MDM_RST); } if(reset){ ret += sprintf(buf + ret, "reset\n"); }else{ ret += sprintf(buf + ret, "work\n"); } return ret; }
static int oem_gpio_get_cbp_rst_ind_value() { if( cbp_reset_ind_connect_to_codec ) { //connected to hi6402, use task context gpio api return oem_gpio_get_value_cansleep(cbp_rst_ind_gpio); } else { //connected to soc, use interrupt context gpio api return oem_gpio_get_value(cbp_rst_ind_gpio); } }
void gpio_irq_cbp_rst_ind(void) { int level = 0; level = !!oem_gpio_get_value(cbp_rst_ind->rst_ind_gpio); if(level != cbp_rst_ind->rst_ind_polar){/*1:cbp reset happened*/ cbp_power_state = 0; wake_up(&cbp_flow_ctrl->wait_q); wake_up(&cbp_data_ack->wait_q); } queue_work(cbp_rst_ind->reset_wq, &cbp_rst_ind->reset_work); }
static irqreturn_t modem_power_indication_irq(int irq, void *data) { if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_IND)){ oem_gpio_set_irq_type(GPIO_VIATEL_MDM_PWR_IND, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); if(oem_gpio_get_value(GPIO_VIATEL_MDM_PWR_IND)){ modem_notify_event(MDM_EVT_NOTIFY_POWER_ON); }else{ modem_notify_event(MDM_EVT_NOTIFY_POWER_OFF); } } return IRQ_HANDLED; }
ssize_t modem_hderr_show( struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int ret = 0; int level = 0; if(GPIO_OEM_VALID(GPIO_VIATEL_CRASH_CBP)){ level = !!oem_gpio_get_value(GPIO_VIATEL_CRASH_CBP); } ret += sprintf(buf, "%d\n", level); return ret; }
ssize_t modem_boot_select_show( struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int ret = 0; int level = 0; if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_BOOT_SEL)){ level = !!oem_gpio_get_value(GPIO_VIATEL_MDM_BOOT_SEL); } ret += sprintf(buf, "%d\n", level); return ret; }
int oem_gpio_set_irq_type(int gpio, unsigned int type) { int irq, level; irq = oem_gpio_to_irq(gpio); if(irq < 0){ return irq; } level = oem_gpio_get_value(gpio); if(type == IRQ_TYPE_EDGE_BOTH){ if(level){ type = IRQ_TYPE_EDGE_FALLING; }else{ type = IRQ_TYPE_EDGE_RISING; } } if(type == IRQ_TYPE_LEVEL_MASK){ if(level){ type = IRQ_TYPE_LEVEL_LOW; }else{ type = IRQ_TYPE_LEVEL_HIGH; } } mt65xx_eint_set_hw_debounce(irq, 3); switch(type){ case IRQ_TYPE_EDGE_RISING: mt65xx_eint_set_sens(irq, MT65xx_EDGE_SENSITIVE); mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_HIGH); break; case IRQ_TYPE_EDGE_FALLING: mt65xx_eint_set_sens(irq, MT65xx_EDGE_SENSITIVE); mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_LOW); break; case IRQ_TYPE_LEVEL_HIGH: mt65xx_eint_set_sens(irq, MT65xx_LEVEL_SENSITIVE); mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_HIGH); break; case IRQ_TYPE_LEVEL_LOW: mt65xx_eint_set_sens(irq, MT65xx_LEVEL_SENSITIVE); mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_LOW); break; default: return -EINVAL; } return 0; }
ssize_t modem_power_show( struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int power = 0; int ret = 0; if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_IND)){ power = !!oem_gpio_get_value(GPIO_VIATEL_MDM_PWR_IND); }else if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){ printk("No MDM_PWR_IND, just detect MDM_PWR_EN\n"); power = !!oem_gpio_get_value(GPIO_VIATEL_MDM_PWR_EN); }else if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){ printk("No MDM_PWR_IND, just detect MDM_PWR_RST\n"); power = !!oem_gpio_get_value(GPIO_VIATEL_MDM_RST); } if(power){ ret += sprintf(buf + ret, "on\n"); }else{ ret += sprintf(buf + ret, "off\n"); } return ret; }
void gpio_irq_cbp_rst_ind(void) { int level = 0; atomic_set(&cbp_rst_ind_finished, 1); level = !!oem_gpio_get_value(cbp_data.gpio_rst_ind); if (level != cbp_data.gpio_rst_ind_polar ) { /*1:cbp reset happened*/ cbp_power_state = 0; wake_up(&cbp_data_ack->wait_q); wake_up(&cbp_flow_ctrl->wait_q); } else { mdelay(50); //VIA bootloader first pull RST_IND low, next initialize spi cbp_power_state = 1; } }
ssize_t modem_via_backup_show(struct device *dev, struct device_attribute *attr, char *buf) { int reset = 0; int ret = 0; if(GPIO_OEM_VALID(cbp_backup_gpio)) { reset = !!oem_gpio_get_value(cbp_backup_gpio); } if(reset) { return snprintf(buf,PAGE_SIZE,"via_backup_on\n"); } else { return snprintf(buf,PAGE_SIZE,"via_backup_off\n"); } }
static irqreturn_t gpio_irq_flow_ctrl(int irq, void *data) { struct cbp_wait_event *cbp_flow_ctrl = (struct cbp_wait_event *)data; int level; level = !!oem_gpio_get_value(cbp_flow_ctrl->wait_gpio); oem_gpio_irq_unmask(cbp_flow_ctrl->wait_gpio); if(level == cbp_flow_ctrl->wait_polar){ atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_ENABLE); } else{ atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE); wake_up(&cbp_flow_ctrl->wait_q); } return IRQ_HANDLED; }
static irqreturn_t modem_reset_indication_irq(int irq, void *data) { printk("%s %d \n",__FUNCTION__,__LINE__); if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST_IND)){ oem_gpio_set_irq_type(GPIO_VIATEL_MDM_RST_IND, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); if(oem_gpio_get_value(GPIO_VIATEL_MDM_RST_IND)){ printk("%s %d ON\n",__FUNCTION__,__LINE__); wake_lock_timeout(&vmdata->wlock, MDM_RST_LOCK_TIME * HZ); modem_notify_event(MDM_EVT_NOTIFY_RESET_ON); }else{ printk("%s %d OFF\n",__FUNCTION__,__LINE__); modem_notify_event(MDM_EVT_NOTIFY_RESET_OFF); } } gpio_irq_cbp_rst_ind(); oem_gpio_irq_unmask(GPIO_VIATEL_MDM_RST_IND); return IRQ_HANDLED; }
static irqreturn_t gpio_irq_via_spi_tx_rx_fifo_empty_ack(int irq, void *data) { struct cbp_wait_event *cbp_data_ack = (struct cbp_wait_event *)data; int level; int ret = -1; ret = irq_set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); level = !!oem_gpio_get_value(cbp_data_ack->wait_gpio); hwlog_debug("%s enter, level = %d.\n", __func__, level); atomic_set(&cbp_data_ack->state, MODEM_ST_READY); wake_up(&cbp_data_ack->wait_q); oem_gpio_irq_unmask(cbp_data_ack->wait_gpio); return IRQ_HANDLED; }
static irqreturn_t gpio_irq_data_ack(int irq, void *data) { struct cbp_wait_event *cbp_data_ack = (struct cbp_wait_event *)data; int level; //unsigned long long hr_t1,hr_t2; //hr_t1 = sched_clock(); level = !!oem_gpio_get_value(cbp_data_ack->wait_gpio); //LOGPRT(LOG_NOTICE, "%s enter, level = %d!\n", __func__, level); if(level == cbp_data_ack->wait_polar){ atomic_set(&cbp_data_ack->state, MODEM_ST_READY); wake_up(&cbp_data_ack->wait_q); } oem_gpio_irq_unmask(cbp_data_ack->wait_gpio); //hr_t2 = sched_clock(); //printk("[sdio]ack: t1=%llu,t2 =%llu,delta=%llu \n",hr_t1, hr_t2, hr_t2-hr_t1); return IRQ_HANDLED; }
ssize_t modem_sim_switch_show(struct device *dev, struct device_attribute *attr, char *buf) { int reset = 0; int ret = 0; if(GPIO_OEM_VALID(cbp_sim_switch_gpio)) { reset = !!oem_gpio_get_value(cbp_sim_switch_gpio); } if(reset) { ret += sprintf(buf + ret, "sim_to_VIA\n"); } else { ret += sprintf(buf + ret, "sim_to_Balong\n"); } return ret; }
int modem_err_indication_usr(int revocery) { printk("%s %d revocery=%d\n",__func__,__LINE__,revocery); if(revocery){ printk("%s %d MDM_EVT_NOTIFY_HD_ERR\n",__func__,__LINE__); /*1, check the rst_ind*/ /*2, set GPIO_7_3 low*/ pr_err("%s %d rst_ind %d\n", __func__, __LINE__, oem_gpio_get_value(cbp_rst_ind_gpio)); oem_gpio_direction_output(cbp_backup_gpio, 1); mdelay(150); oem_gpio_direction_output(cbp_backup_gpio, 0); //cbp_need_apr = 1; set_time_stamp(); //schedule_delayed_work(&apr_log_wk, 0); modem_notify_event(MDM_EVT_NOTIFY_HD_ERR); } else{ printk("%s %d MDM_EVT_NOTIFY_HD_ENHANCE\n",__func__,__LINE__); modem_notify_event(MDM_EVT_NOTIFY_HD_ENHANCE); } return 0; }