static ssize_t xmm_onoff(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int pwr; int size; struct platform_device *device = to_platform_device(dev); mutex_lock(&xmm_onoff_mutex); pr_debug("%s\n", __func__); /* check input */ if (buf == NULL) { pr_err("%s: buf NULL\n", __func__); mutex_unlock(&xmm_onoff_mutex); return -EINVAL; } pr_debug("%s: count=%d\n", __func__, count); /* parse input */ size = sscanf(buf, "%d", &pwr); if (size != 1) { pr_err("%s: size=%d -EINVAL\n", __func__, size); mutex_unlock(&xmm_onoff_mutex); return -EINVAL; } if (power_onoff == pwr) { pr_err("%s: Ignored, due to same CP power state(%d)\n", __func__, power_onoff); mutex_unlock(&xmm_onoff_mutex); return -EINVAL; } power_onoff = pwr; pr_debug("%s power_onoff=%d\n", __func__, power_onoff); if (power_onoff == 0) xmm_power_off(device); else if (power_onoff == 1) xmm_power_on(device); mutex_unlock(&xmm_onoff_mutex); return count; }
static ssize_t xmm_power_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int state; int i; unsigned long flags; struct xmm_power_plat_data *plat = dev->platform_data; dev_info(dev, "Power set to %s\n", buf); if (sscanf(buf, "%d", &state) != 1) return -EINVAL; if (state == POWER_SET_ON) { xmm_power_change_state(XMM_POW_S_INIT_ON); free_reset_isr(dev); if (plat && plat->flashless) { /* For flashless, enable USB to enumerate with CP's bootrom */ enable_usb_hsic(true); msleep(usb_on_delay); } else { xmm_power_change_state(XMM_POW_S_WAIT_READY); } simcard_detect_enable(); xmm_power_on(); msleep(20); gpio_lowpower_set(NORMAL); gpio_set_value(GPIO_HOST_ACTIVE, 1); for (i=0; i<MAX_HSIC_RESET_RETRY; i++){ if (usb_enum_check1() == 0) break; enable_usb_hsic(false); msleep(10); enable_usb_hsic(true); msleep(usb_on_delay); } if (i == MAX_HSIC_RESET_RETRY){ /* Fail to enumarte, make caller to know */ dev_err(dev, "boot rom enum retry failed\n"); return -1; } } else if (state == POWER_SET_OFF){ free_reset_isr(dev); spin_lock_irqsave(&xmm_state_lock, flags); if (xmm_curr_power_state == XMM_POW_S_USB_L0) wake_unlock(&xmm_wakelock); xmm_power_change_state(XMM_POW_S_OFF); spin_unlock_irqrestore(&xmm_state_lock, flags); enable_usb_hsic(false); gpio_set_value(GPIO_HOST_ACTIVE, 0); gpio_set_value(GPIO_SLAVE_WAKEUP, 0); xmm_power_off(); gpio_lowpower_set(LOWPOWER); } else if (state == POWER_SET_DL_FINISH){ unsigned long tio = msecs_to_jiffies(5000); xmm_power_change_state(XMM_POW_S_WAIT_READY); enable_usb_hsic(false); gpio_set_value(GPIO_HOST_ACTIVE, 0); tio = wait_event_timeout(xmm_wait_q, (xmm_curr_power_state == XMM_POW_S_INIT_USB_ON), tio); if (tio == 0) { dev_err(dev, "Wait modem system on timeout\n"); return -1; } for (i=0; i<MAX_HSIC_RESET_RETRY; i++){ xmm_power_usb_on(); if (usb_enum_check2() == 0) break; enable_usb_hsic(false); msleep(10); } if (i == MAX_HSIC_RESET_RETRY) { /* Failed to enumarte, make caller to know */ dev_err(dev, "system enum retry failed\n"); return 0; } request_reset_isr(dev); } else if (state == POWER_SET_DEBUGON){ free_reset_isr(dev); xmm_power_on(); gpio_lowpower_set(NORMAL); } else if (state == POWER_SET_DEBUGOFF){ free_reset_isr(dev); xmm_power_off(); gpio_lowpower_set(LOWPOWER); } #if 1 /* Command for debug use */ else if (state == 5){ /* L0 to L2 */ xmm_power_change_state(XMM_POW_S_USB_L2); set_usb_hsic_suspend(true); } else if (state == 6){ /* L2 to L0 */ gpio_set_value(GPIO_SLAVE_WAKEUP, 1); } else if (state == 7){ /* to L3 */ enable_usb_hsic(false); gpio_set_value(GPIO_HOST_ACTIVE, 0); xmm_power_change_state(XMM_POW_S_USB_L3); } else if (state == 8){ /* L3 to L0 */ enable_usb_hsic(true); accu_mdelay(5); gpio_set_value(GPIO_SLAVE_WAKEUP, 1); if (usb_enum_check3() == 0) { xmm_power_change_state(XMM_POW_S_USB_L0); } } else if (state == 9){ pr_info("0\n"); accu_mdelay(1); pr_info("1\n"); accu_mdelay(2); pr_info("2\n"); accu_mdelay(3); pr_info("3\n"); accu_mdelay(4); pr_info("4\n"); accu_mdelay(5); pr_info("5\n"); accu_mdelay(10); pr_info("10\n"); accu_mdelay(20); pr_info("20\n"); } #endif return count; }