int fsa9480_reset_ic(void) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = chip->client; /* Disable Interrupt Write 0x01 to 0x1B Register <= Reset IC Write 0x40 to 0x05 Register <= Mask interrupt1 Write 0x20 to 0x06 Register <= Mask interrupt2 Write 0x2F to 0x25 Register <= Mask interrupt charger Write 0x1E to 0x02 Register <= Initialize control register Enable Interrupt */ printk(KERN_WARNING "[FSA9480] %s. TSU8111 will be reset\n", __func__); fsa9480_detect_dev(usbsw, 2); disable_irq(client->irq); fsa9480_write_reg(client, 0x1B, 0x01); msleep(1); fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x40); fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x20); fsa9480_write_reg(client, FSA9480_REG_CHG_INT_MASK, 0xc0); fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); enable_irq(client->irq); printk(KERN_WARNING "[FSA9480] %s. TSU8111 reset...Done\n", __func__); return 0; }
static void fsa9480_set_switch(const char *buf) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; unsigned int value; unsigned int path = 0; value = fsa9480_read_reg(client, FSA9480_REG_CTRL); if (!strncmp(buf, "VAUDIO", 6)) { path = SW_VAUDIO; value &= ~CON_MANUAL_SW; } else if (!strncmp(buf, "UART", 4)) { path = SW_UART; value &= ~CON_MANUAL_SW; } else if (!strncmp(buf, "AUDIO", 5)) { path = SW_AUDIO; value &= ~CON_MANUAL_SW; } else if (!strncmp(buf, "DHOST", 5)) { path = SW_DHOST; value &= ~CON_MANUAL_SW; } else if (!strncmp(buf, "AUTO", 4)) { path = SW_AUTO; value |= CON_MANUAL_SW; } else { printk(KERN_ERR "Wrong command\n"); return; } usbsw->mansw = path; fsa9480_write_reg(client, FSA9480_REG_MANSW1, path); fsa9480_write_reg(client, FSA9480_REG_CTRL, value); }
/* SW RESET for TI USB:To fix no USB recog problem after jig attach&detach*/ static void TI_SWreset(struct fsa9480_usbsw *usbsw) { #if 0 // TODO: struct i2c_client *client = usbsw->client; printk("[FSA9480] TI_SWreset ...Start\n"); disable_irq(client->irq); /*Hold SCL&SDA Low more than 30ms*/ gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO64),0); gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO66),0); msleep(31); /*Make SCL&SDA High again*/ gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO64),1); gpio_direction_output(mfp_to_gpio(MFP_PIN_GPIO66),1); /*Should I make this input setting? Not Sure*/ //gpio_direction_input(mfp_to_gpio(MFP_PIN_GPIO64)); //gpio_direction_input(mfp_to_gpio(MFP_PIN_GPIO66)); /*Write SOME Init register value again*/ fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x20); fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); enable_irq(client->irq); #endif // TODO: printk("[FSA9480] TI_SWreset ...Done\n"); }
static void TSU8111_Charger_Enable(void) { u8 val1,dev1; int ret = 0; struct i2c_client *client = chip->client; pr_info("%s\n",__func__); fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL2, 0x89); // set EOC current 130mA, Full 4.18V fsa9480_read_reg(client, FSA9480_REG_DEV_T1, &dev1); if( (dev1 & (FSA9480_DEV_T1_CHARGER_MASK|DEV_USB_CHG)) || (dev1==DEV_VBUS)) fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL3, 0xD9); // 650mA else fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL3, 0xD5); // 450mA fsa9480_read_reg(client, FSA9480_REG_CHG_CTRL1, &val1); val1 &= ~CH_DIS; val1 |= FCMEN; // Set Fast Charge Timer 6 Hour val1 &= ~0x03; val1 |= 0x01; pr_info("%s. Register(%d) = (0x%X)\n", __func__, FSA9480_REG_CHG_CTRL1, val1); ret = fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL1, val1); if (ret < 0) { printk("[FSA9480] I2C write fail\n"); } return ; }
static void TSU8111_Charger_BackCHG_Enable(void) { u8 val1,dev1; int ret = 0; struct i2c_client *client = chip->client; pr_info("%s\n",__func__); fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL2, 0x19); // set EOC current 60mA, Full 4.18V fsa9480_read_reg(client, FSA9480_REG_DEV_T1, &dev1); if( dev1 & FSA9480_DEV_T1_CHARGER_MASK) fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL3, 0xD9); // 650mA else fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL3, 0xD5); // 450mA fsa9480_read_reg(client, FSA9480_REG_CHG_CTRL1, &val1); val1 &= ~CH_DIS; val1 |= FCMEN; pr_info("%s. Register(%d) = (0x%X)\n", __func__, FSA9480_REG_CHG_CTRL1, val1); ret = fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL1, val1); if (ret < 0) { printk("[FSA9480] I2C write fail\n"); } return ; }
void fsa9480_force_sleep(void) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; u8 value = 0; //wake_unlock(&JIGConnect_idle_wake); wake_unlock(&JIGConnect_suspend_wake); #ifdef CONFIG_KONA_PI_MGR pi_mgr_qos_request_update(&qos_node, PI_MGR_QOS_DEFAULT_VALUE); #endif if(muic_type==muicTypeFSA880) { fsa9480_read_reg(client, FSA9480_REG_MANSW2, &value); fsa9480_write_reg(client, FSA9480_REG_MANSW2, 0x00); fsa9480_read_reg(client, FSA9480_REG_CTRL, &value); fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x00); } else { fsa9480_read_reg(client, FSA9480_REG_CTRL, &value); value &= ~MANUAL_SWITCH; fsa9480_write_reg(client, FSA9480_REG_CTRL, value); fsa9480_read_reg(client, FSA9480_REG_MANSW2, &value); value &= ~MANSW2_JIG; fsa9480_write_reg(client, FSA9480_REG_MANSW2, value); } }
static void DisableFSA9480Interrupts(void) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; printk ("DisableFSA9480Interrupts-2\n"); fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0xFF); fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x1F); } // DisableFSA9480Interrupts()
/*MHL call this function to change VAUDIO path*/ void FSA9480_CheckAndHookAudioDock(void) { struct fsa9480_platform_data *pdata = chip->pdata; struct i2c_client *client = chip->client; printk("[FSA9480] %s: FSA9485 VAUDIO\n",__func__); isMHLconnected = 0; isDeskdockconnected = 1; if (pdata->mhl_cb) pdata->mhl_cb(FSA9480_DETACHED); EnableFSA9480Interrupts(); if(chip->id == 0) chip->mansw = VAUDIO_9485; else chip->mansw = VAUDIO; /*make ID change report*/ fsa9480_write_reg(client,FSA9480_REG_CTRL, 0x16); if(pdata->deskdock_cb) pdata->deskdock_cb(FSA9480_ATTACHED); }
static void EnableFSA9480Interrupts(void) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; u8 intr, intr2; printk ("EnableFSA9480Interrupts\n"); /*clear interrupts*/ fsa9480_read_reg(client, FSA9480_REG_INT1, &intr); fsa9480_read_reg(client, FSA9480_REG_INT2, &intr2); fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x00); fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x00); } //EnableFSA9480Interrupts()
static int fsa9480_resume(struct i2c_client *client) { printk("[FSA9480] fsa9480_resume disable_irq_wake...\n"); disable_irq_wake(client->irq); #if 0 if(isManual==1) { if(muic_type==muicTypeFSA880) fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x04); else fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); isManual=0; } #endif return 0; }
static void fsa9480_id_open(void) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; pr_alert("fsa9480 id_open\n"); fsa9480_write_reg(client, 0x1B, 1); }
static ssize_t fsa9480_set_syssleep(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; u8 value = 0; if (!strncmp(buf, "1", 1)) { //wake_unlock(&JIGConnect_idle_wake); wake_unlock(&JIGConnect_suspend_wake); #ifdef CONFIG_KONA_PI_MGR pi_mgr_qos_request_update(&qos_node, PI_MGR_QOS_DEFAULT_VALUE); #endif if(muic_type==muicTypeFSA880) { fsa9480_read_reg(client, FSA9480_REG_MANSW2, &value); fsa9480_write_reg(client, FSA9480_REG_MANSW2, 0x00); fsa9480_read_reg(client, FSA9480_REG_CTRL, &value); fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x00); } else { fsa9480_read_reg(client, FSA9480_REG_CTRL, &value); value &= ~MANUAL_SWITCH; fsa9480_write_reg(client, FSA9480_REG_CTRL, value); fsa9480_read_reg(client, FSA9480_REG_MANSW2, &value); value &= ~MANSW2_JIG; fsa9480_write_reg(client, FSA9480_REG_MANSW2, value); } //isManual=1; } else { fsa9480_read_reg(client, FSA9480_REG_CTRL, &value); value |= MANUAL_SWITCH; fsa9480_write_reg(client, FSA9480_REG_CTRL, value); } return count; }
static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_usbsw *usbsw; int ret = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; chip = usbsw; i2c_set_clientdata(client, usbsw); ret = fsa9480_irq_init(usbsw); if (ret) goto fail1; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "failed to create fsa9480 attribute group\n"); goto fail2; } /* ADC Detect Time: 500ms */ fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x6); if (chip->pdata->reset_cb) chip->pdata->reset_cb(); /* device detection */ fsa9480_detect_dev(usbsw, INT_ATTACH); pm_runtime_set_active(&client->dev); return 0; fail2: if (client->irq) free_irq(client->irq, usbsw); fail1: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; }
static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) { struct fsa9480_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; int ret; int intr; unsigned int ctrl = CON_MASK; /* clear interrupt */ fsa9480_read_irq(client, &intr); /* unmask interrupt (attach/detach only) */ fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0xfc); fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x1f); usbsw->mansw = fsa9480_read_reg(client, FSA9480_REG_MANSW1); if (usbsw->mansw) ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */ fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); if (pdata && pdata->cfg_gpio) pdata->cfg_gpio(); if (client->irq) { ret = request_threaded_irq(client->irq, NULL, fsa9480_irq_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "fsa9480 micro USB", usbsw); if (ret) { dev_err(&client->dev, "failed to reqeust IRQ\n"); return ret; } device_init_wakeup(&client->dev, pdata->wakeup); } return 0; }
void fsa9480_set_switch(const char *buf) { struct fsa9480_usbsw *usbsw = chip; struct i2c_client *client = usbsw->client; u8 value = 0; unsigned int path = 0; fsa9480_read_reg(client, FSA9480_REG_CTRL, &value); if (!strncmp(buf, "VAUDIO", 6)) { if(usbsw->id == 0) path = VAUDIO_9485; else path = VAUDIO; value &= ~MANUAL_SWITCH; } else if (!strncmp(buf, "UART", 4)) { path = UART; value &= ~MANUAL_SWITCH; } else if (!strncmp(buf, "AUDIO", 5)) { if(usbsw->id == 0) path = AUDIO_9485; else path = AUDIO; value &= ~MANUAL_SWITCH; } else if (!strncmp(buf, "DHOST", 5)) { path = DHOST; value &= ~MANUAL_SWITCH; } else if (!strncmp(buf, "AUTO", 4)) { path = AUTO; value |= MANUAL_SWITCH; } else { printk(KERN_ERR "Wrong command\n"); return; } usbsw->mansw = path; fsa9480_write_reg(client, FSA9480_REG_MANSW1, path); fsa9480_write_reg(client, FSA9480_REG_CTRL, value); }
//TI Switch Test :(USB)->Uart->USB static void TI_Switch(void) { struct i2c_client *client = chip->client; printk("[FSA9480] TI_Switch ...Start\n"); disable_irq(client->irq); if(chip->dev1 & DEV_USB) printk("[FSA9480] Waring! previous status is NOT USB attached!! \n"); //Set Manual switching fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1B); // Manual to UART fsa9480_write_reg(client, FSA9480_REG_MANSW1, 0x6C); // 011 011 00 msleep(1000); //Manual to USB fsa9480_write_reg(client, FSA9480_REG_MANSW1, 0x24); // 001 001 00 // Set Auto switching by interrupt fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); enable_irq(client->irq); printk("[FSA9480] TI_Switch ...Done\n"); }
static void TSU8111_Charger_Disable(void) { u8 val1; int ret = 0; struct i2c_client *client = chip->client; pr_info("%s\n",__func__); fsa9480_read_reg(client, FSA9480_REG_CHG_CTRL1, &val1); val1 |= CH_DIS; pr_info("%s. Register(%d) = (0x%X)\n", __func__, FSA9480_REG_CHG_CTRL1, val1); ret = fsa9480_write_reg(client, FSA9480_REG_CHG_CTRL1, val1); if (ret < 0) { printk("[FSA9480] I2C write fail\n"); } return ; }
void FSA9480_EnableIntrruptByMHL(bool _bDo) { struct fsa9480_platform_data *pdata = chip->pdata; struct i2c_client *client = chip->client; char buf[16]; if(true == _bDo) { fsa9480_write_reg(client,FSA9480_REG_CTRL, 0x1E); EnableFSA9480Interrupts(); } else { DisableFSA9480Interrupts(); } fsa9480_get_switch(buf); printk("[%s] fsa switch status = %s\n",__func__, buf); }
//extern void mv_usb_connect_change(int status); // khMa static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw, u8 intr) { u8 val1, val2;// , ctrl,temp; //struct fsa9480_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; printk("[FSA9480] fsa9480_detect_dev !!!!!\n"); #if 0 // Not for TI /*reset except CP USB and AV dock*/ if ((usbsw->mansw != AUDIO) && (usbsw->mansw != AUDIO_9485) && (usbsw->mansw != VAUDIO) && (usbsw->mansw != VAUDIO_9485)) { /*reset UIC when mansw is not set*/ printk("[FSA9480] %s: reset UIC mansw is 0x%x\n",__func__,usbsw->mansw); fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); usbsw->mansw = AUTO; } #endif fsa9480_read_reg(client, FSA9480_REG_DEV_T1, &val1); fsa9480_read_reg(client, FSA9480_REG_DEV_T2, &val2); printk("intr: 0x%x, dev1: 0x%x, dev2: 0x%x\n",intr, val1, val2); #if 0//Not for TI fsa9480_read_reg(client, FSA9480_REG_CTRL, &ctrl); dev_info(&client->dev, "intr: 0x%x, dev1: 0x%x, dev2: 0x%x, ctrl: 0x%x\n", intr, val1, val2,ctrl); #endif if((intr==0x01) &&(val1==0x00) && (val2==0x00) && (isProbe == 0)) { printk("[FSA9480] (intr==0x01) &&(val1==0x00) && (val2==0x00) !!!!!\n"); fsa9480_read_adc_value(); if(muic_type==muicTypeTI6111) { msleep(50); fsa9480_read_reg(client, FSA9480_REG_DEV_T1, &val1); fsa9480_read_reg(client, FSA9480_REG_DEV_T2, &val2); //TI_SWreset(usbsw); //return; } } else if(intr==0x03) { printk("[FSA9480] error read INT register !!!!!\n"); intr = (1 << 1); // change to DETACH } /* Attached */ if (intr & (1 << 0)) { if (val1 & FSA9480_DEV_T1_USB_MASK ) { printk("[FSA9480] FSA9480_USB ATTACHED*****\n"); #if defined (VBUS_DETECT) /* Enable clock to AP USB block */ pxa_vbus_handler(VBUS_HIGH); #endif #if defined(CONFIG_SPA) if(spa_external_event) { spa_external_event(SPA_CATEGORY_DEVICE, SPA_DEVICE_EVENT_USB_ATTACHED); } #elif defined(CONFIG_BATTERY_D2083) if(spa_external_event) { spa_external_event(D2083_CATEGORY_DEVICE, D2083_EVENT_USB_ATTACHED); } #endif send_usb_attach_event(); } if (val1 & FSA9480_DEV_T1_UART_MASK || val2 & FSA9480_DEV_T2_UART_MASK) { //if (pdata->uart_cb) // pdata->uart_cb(FSA9480_ATTACHED); } if (val1 & FSA9480_DEV_T1_CHARGER_MASK || val1==DEV_VBUS || val2 & DEV_JIG_USB_OFF) { printk("[FSA9480] Charger ATTACHED*****\n"); #if defined(CONFIG_SPA) if(spa_external_event) { spa_external_event(SPA_CATEGORY_DEVICE, SPA_DEVICE_EVENT_TA_ATTACHED); } #elif defined(CONFIG_BATTERY_D2083) if(spa_external_event) { spa_external_event(D2083_CATEGORY_DEVICE, D2083_EVENT_TA_ATTACHED); } #endif } if (val2 & FSA9480_DEV_T2_JIG_MASK) { printk("[FSA9480] JIG ATTACHED*****\n"); //wake_lock(&JIGConnect_idle_wake); wake_lock(&JIGConnect_suspend_wake); #ifdef CONFIG_KONA_PI_MGR pi_mgr_qos_request_update(&qos_node, 0); #endif #if defined(CONFIG_SPA) if(spa_external_event) { spa_external_event(SPA_CATEGORY_DEVICE, SPA_DEVICE_EVENT_JIG_ATTACHED); } #elif defined(CONFIG_BATTERY_D2083) if(spa_external_event) { spa_external_event(D2083_CATEGORY_DEVICE, D2083_EVENT_JIG_ATTACHED); } #endif } } else if (intr & (1 << 1)) { /* DETACH */ if(usbsw->dev1 & FSA9480_DEV_T1_USB_MASK) { printk("[FSA9480] FSA9480_USB Detached*****\n"); #if defined (VBUS_DETECT) /* Disable clock to AP USB block */ pxa_vbus_handler(VBUS_LOW); #endif #if defined(CONFIG_SPA) if(spa_external_event) { spa_external_event(SPA_CATEGORY_DEVICE, SPA_DEVICE_EVENT_USB_DETACHED); } #elif defined(CONFIG_BATTERY_D2083) if(spa_external_event) { spa_external_event(D2083_CATEGORY_DEVICE, D2083_EVENT_USB_DETACHED); } #endif send_usb_detach_event(); } if (usbsw->dev1 & FSA9480_DEV_T1_UART_MASK || usbsw->dev2 & FSA9480_DEV_T2_UART_MASK) { //if (pdata->uart_cb) // pdata->uart_cb(FSA9480_DETACHED); } if (usbsw->dev1 & FSA9480_DEV_T1_CHARGER_MASK || usbsw->dev1==DEV_VBUS || usbsw->dev2 & DEV_JIG_USB_OFF) { printk("[FSA9480] Charger Detached*****\n"); #if defined(CONFIG_SPA) if(spa_external_event) { spa_external_event(SPA_CATEGORY_DEVICE, SPA_DEVICE_EVENT_TA_DETACHED); } #elif defined(CONFIG_BATTERY_D2083) if(spa_external_event) { spa_external_event(D2083_CATEGORY_DEVICE, D2083_EVENT_TA_DETACHED); } #endif } if (usbsw->dev2 & FSA9480_DEV_T2_JIG_MASK) { printk("[FSA9480] JIG Detached*****\n"); //wake_unlock(&JIGConnect_idle_wake); wake_unlock(&JIGConnect_suspend_wake); #ifdef CONFIG_KONA_PI_MGR pi_mgr_qos_request_update(&qos_node, PI_MGR_QOS_DEFAULT_VALUE); #endif #if defined(CONFIG_SPA) if(spa_external_event) { spa_external_event(SPA_CATEGORY_DEVICE, SPA_DEVICE_EVENT_JIG_DETACHED); } #elif defined(CONFIG_BATTERY_D2083) if(spa_external_event) { spa_external_event(D2083_CATEGORY_DEVICE, D2083_EVENT_JIG_DETACHED); } #endif if(muic_type==muicTypeTI6111) { /*SW RESET for TI USB:To fix no USB recog problem after jig attach&detach*/ //TI_SWreset(usbsw); } } } if( intr ){ usbsw->dev1 = val1; usbsw->dev2 = val2; chip->dev1 = val1; chip->dev2 = val2; } #if 0 // Not for TI fsa9480_read_reg(client, FSA9480_REG_CTRL, &ctrl); ctrl &= ~INT_MASK; fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); fsa9480_read_reg(client, FSA9480_REG_MANSW1, &temp); //khMa #endif }
static int __devinit fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { //struct regulator *regulator; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct fsa9480_platform_data *pdata = client->dev.platform_data; struct fsa9480_usbsw *usbsw; struct pm860x_vbus_info *vbus; #if 0 // TODO: struct pxa_vbus_info info; #endif unsigned int data; int ret = 0; u8 devID; u8 intr, intr2, intr_chg; u8 mansw1; unsigned int ctrl = CTRL_MASK; printk("[FSA9480] PROBE ......\n"); if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return -EIO; isProbe = 1; //add for AT Command //wake_lock_init(&JIGConnect_idle_wake, WAKE_LOCK_IDLE, "jig_connect_idle_wake"); wake_lock_init(&JIGConnect_suspend_wake, WAKE_LOCK_SUSPEND, "jig_connect_suspend_wake"); wake_lock_init(&mUSB_suspend_wake, WAKE_LOCK_SUSPEND, "mUSB_detect"); #ifdef CONFIG_KONA_PI_MGR ret=pi_mgr_qos_add_request(&qos_node, "fsa9480", PI_MGR_PI_ID_ARM_SUB_SYSTEM, PI_MGR_QOS_DEFAULT_VALUE); if (ret) { pr_err("%s: failed to add fsa9480 to qos\n",__func__); return -1; } #endif usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); if (!usbsw) { dev_err(&client->dev, "failed to allocate driver data\n"); return -ENOMEM; } usbsw->client = client; usbsw->pdata = client->dev.platform_data; chip = usbsw; i2c_set_clientdata(client, usbsw); #if defined (VBUS_DETECT) /* Init vbus for pxa(MARVELL) */ // chip->pdata = pm860x_pdata->vbus; vbus = kzalloc(sizeof(struct pm860x_vbus_info), GFP_KERNEL); if (!vbus) { ret = -ENOMEM; goto out_mem; } dev_set_drvdata(&client->dev, vbus); vbus->res = kzalloc(sizeof(struct resource), GFP_KERNEL); if (!vbus->res) { ret = -ENOMEM; goto out_mem2; } vbus->res->start = pdata->vbus->reg_base; vbus->res->end = pdata ->vbus->reg_end; memset(&info,0,sizeof(struct pxa_vbus_info)); info.dev = &client->dev; info.res = vbus->res; pxa_vbus_init(&info); data = VBUS_A_VALID | VBUS_A_SESSION_VALID | VBUS_B_SESSION_VALID | VBUS_B_SESSION_END | VBUS_ID; pxa_unmask_vbus(data); #endif #if defined(CONFIG_SPA) spa_external_event = spa_get_external_event_handler(); #elif defined(CONFIG_BATTERY_D2083) ret = d2083_register_enable_charge(TSU8111_Charger_Enable); if(ret < 0) { pr_err("%s. fail to register enable charge function\n", __func__); goto out_charger_enable; } ret = d2083_register_enable_back_charge(TSU8111_Charger_BackCHG_Enable); if(ret < 0) { pr_err("%s. fail to register enable charge function\n", __func__); goto out_charger_enable; } ret = d2083_register_disable_charge(TSU8111_Charger_Disable); if(ret < 0) { pr_err("%s. fail to register disable charge function\n", __func__); goto out_charger_disable; } spa_external_event = d2083_get_external_event_handler(); #endif /* clear interrupt */ fsa9480_read_reg(client, FSA9480_REG_INT1, &intr); fsa9480_read_reg(client, FSA9480_REG_DEVID, &devID); if(devID==0x0a || devID==0x5A) muic_type=muicTypeTI6111; else if(devID==0x00) muic_type=muicTypeFSA880; else muic_type=muicTypeFSA; if(muic_type==muicTypeFSA880) { intr &= 0xffff; /* set control register */ fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x04); } else if(muic_type==muicTypeTI6111) { intr &= 0xffff; /* clear interrupt */ fsa9480_read_reg(client, FSA9480_REG_INT2, &intr2); fsa9480_read_reg(client, FSA9480_REG_CHG_INT, &intr_chg); /* unmask interrupt (attach/detach only) */ ret = fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x00); if (ret < 0) return ret; #if 0/*FSA9480's Interrupt Mask init setting*/ //ret = fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x00); #endif /*TI USB : not to get Connect Interrupt : no more double interrupt*/ ret = fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0x40); if (ret < 0) return ret; ret = fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x20); if (ret < 0) return ret; ret = fsa9480_write_reg(client, FSA9480_REG_CHG_INT_MASK, 0xc0); if (ret < 0) return ret; fsa9480_read_reg(client, FSA9480_REG_MANSW1, &mansw1); usbsw->mansw = mansw1; ctrl &= ~INT_MASK; /* Unmask Interrupt */ if (usbsw->mansw) ctrl &= ~MANUAL_SWITCH; /* Manual Switching Mode */ fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); } else printk("[FSA9480] Error!!!! No Type. Check dev ID(0x01 addr) ......\n"); ret = fsa9480_irq_init(usbsw); if (ret) goto fsa9480_probe_fail; ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); if (ret) { dev_err(&client->dev, "[FSA9480] Creating fsa9480 attribute group failed"); goto fsa9480_probe_fail2; } /* device detection */ fsa9480_detect_dev(usbsw, 1); isProbe = 0; tsu8111_check_ovp(); /*reset UIC*/ if(muic_type==muicTypeFSA880) fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x04); else { fsa9480_write_reg(client, FSA9480_REG_CTRL, 0x1E); /*set timing1 to 100ms*/ // fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x1); } #ifdef CONFIG_KONA_PI_MGR //ret=pi_mgr_qos_request_update(&qos_node, 0); //if (ret) //{ // pr_err("%s: failed to request update qos_node\n",__func__); //} #endif printk("[FSA9480] PROBE Done.\n"); return 0; out_mem: return ret; #if defined(CONFIG_BATTERY_D2083) out_charger_enable: out_charger_disable: #endif /* CONFIG_BATTERY_D2083 */ out_mem2: kfree(vbus); fsa9480_probe_fail2: if (client->irq) free_irq(client->irq, NULL); fsa9480_probe_fail: i2c_set_clientdata(client, NULL); kfree(usbsw); return ret; }
static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw, int intr) { int val1, val2, ctrl; struct fsa9480_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; val1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1); val2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2); ctrl = fsa9480_read_reg(client, FSA9480_REG_CTRL); dev_info(&client->dev, "intr: 0x%x, dev1: 0x%x, dev2: 0x%x\n", intr, val1, val2); if (!intr) goto out; if (intr & INT_ATTACH) { /* Attached */ /* USB */ if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) { if (pdata->usb_cb) pdata->usb_cb(FSA9480_ATTACHED); if (usbsw->mansw) { fsa9480_write_reg(client, FSA9480_REG_MANSW1, usbsw->mansw); } } /* UART */ if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) { if (pdata->uart_cb) pdata->uart_cb(FSA9480_ATTACHED); if (!(ctrl & CON_MANUAL_SW)) { fsa9480_write_reg(client, FSA9480_REG_MANSW1, SW_UART); } } /* CHARGER */ if (val1 & DEV_T1_CHARGER_MASK) { if (pdata->charger_cb) pdata->charger_cb(FSA9480_ATTACHED); } /* JIG */ if (val2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9480_ATTACHED); } } else if (intr & INT_DETACH) { /* Detached */ /* USB */ if (usbsw->dev1 & DEV_T1_USB_MASK || usbsw->dev2 & DEV_T2_USB_MASK) { if (pdata->usb_cb) pdata->usb_cb(FSA9480_DETACHED); } /* UART */ if (usbsw->dev1 & DEV_T1_UART_MASK || usbsw->dev2 & DEV_T2_UART_MASK) { if (pdata->uart_cb) pdata->uart_cb(FSA9480_DETACHED); } /* CHARGER */ if (usbsw->dev1 & DEV_T1_CHARGER_MASK) { if (pdata->charger_cb) pdata->charger_cb(FSA9480_DETACHED); } /* JIG */ if (usbsw->dev2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9480_DETACHED); } } usbsw->dev1 = val1; usbsw->dev2 = val2; out: ctrl &= ~CON_INT_MASK; fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); }