/*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 irqreturn_t fsa9485_irq_thread(int irq, void *data) { struct fsa9485_usbsw *usbsw = data; struct i2c_client *client = usbsw->client; int intr, intr2, detect; DisableFSA9480Interrupts(); /* FSA9485 : Read interrupt -> Read Device FSA9485 : Read Device -> Read interrupt */ mutex_lock(&usbsw->mutex); if (is_ti_muic()) msleep(50); pr_info("fsa9485_irq_thread is called\n"); /* read and clear interrupt status bits */ intr = i2c_smbus_read_byte_data(client, FSA9485_REG_INT1); dev_info(&client->dev, "%s: intr : 0x%x", __func__, intr & 0xff); intr2 = i2c_smbus_read_byte_data(client, FSA9485_REG_INT2); dev_info(&client->dev, "%s: intr2 : 0x%x\n", __func__, intr2 & 0xff); local_usbsw->last_state.int1 = intr; local_usbsw->last_state.int2 = intr2; if (intr & INT_OVP_EN) usbsw->pdata->oxp_callback(ENABLE); else if (intr & INT_OXP_DISABLE) usbsw->pdata->oxp_callback(DISABLE); if (intr == (INT_ATTACH + INT_DETACH)) { fsa9485_detach_dev(usbsw); EnableFSA9480Interrupts(); return IRQ_HANDLED; } /* device detection */ detect = fsa9485_detect_dev(usbsw); mutex_unlock(&usbsw->mutex); pr_info("%s: detect dev_adc: %x\n", __func__, detect); EnableFSA9480Interrupts(); return IRQ_HANDLED; }
void FSA9480_MhlSwitchSel(bool sw) { struct i2c_client *client = local_usbsw->client; //struct power_supply *mhl_power_supply = power_supply_get_by_name("battery"); // union power_supply_propval value; printk("[FSA] mutex_lock\n"); //mutex_lock(&FSA9480_MhlSwitchSel_lock);//avoid race condtion between mhl and hpd if(sw) { sii9234_cfg_power(1); if (gv_intr2&0x1) //cts: fix for 3355 { mhl_vbus = true; mhl_power_supply=1; local_pdata->charger_cb(FSA9480_ATTACHED); gv_intr2=0; printk("vbus_power is detected\n"); } SiI9234_init(); } else { if (tegra_dc_hdmi_hpd()) { printk("[FSA] Turn off hdmi\n"); mhl_hpd_handler(false); } if(mhl_power_supply==1) { mhl_power_supply=0; local_pdata->charger_cb(FSA9480_DETACHED); } mhl_vbus = false; sii9234_cfg_power(0); //Turn Off power to SiI9234 } /********************FSA-MHL-FSA Switching start***************************/ DisableFSA9480Interrupts(); { //gpio_set_value_cansleep(GPIO_MHL_SEL, sw); sii9234_switch_onoff(sw); i2c_smbus_read_byte_data(client, FSA9480_REG_INT1); } EnableFSA9480Interrupts(); /******************FSA-MHL-FSA Switching End*******************************/ //mutex_unlock(&FSA9480_MhlSwitchSel_lock); printk("[FSA] mutex_unlock\n"); }
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); }
void FSA9480_MhlTvOff(void) { struct i2c_client *client = local_usbsw->client; int intr1; DisableFSA9480Interrupts(); //printk(KERN_ERR "%s: started######\n", __func__); intr1 = i2c_smbus_read_word_data(client, FSA9480_REG_INT1); gpio_set_value(GPIO_MHL_SEL, 0); do { msleep(5); intr1 = i2c_smbus_read_byte_data(client, FSA9480_REG_INT1); }while(!intr1); mhl_cable_status =0x08;//MHL_TV_OFF_CABLE_CONNECT; EnableFSA9480Interrupts(); //printk(KERN_ERR "%s: End######\n",__func__); printk("%s: interrupt1= %d\n", __func__, intr1); }
static int fsa9485_detect_dev(struct fsa9485_usbsw *usbsw) { int device_type, ret; unsigned int val1, val2, adc; struct fsa9485_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) u8 mhl_ret = 0; #endif device_type = i2c_smbus_read_word_data(client, FSA9485_REG_DEV_T1); if (device_type < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, device_type); return device_type; } val1 = device_type & 0xff; val2 = device_type >> 8; adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC); if (usbsw->dock_attached) pdata->dock_cb(FSA9485_DETACHED_DOCK); if (adc == 0x10) val2 = DEV_SMARTDOCK; else if (adc == 0x12) val2 = DEV_AUDIO_DOCK; dev_info(&client->dev, "dev1: 0x%x, dev2: 0x%x adc : 0x%x\n", val1, val2, adc); /* Attached */ if (val1 || val2) { /* USB */ if (val1 & DEV_USB || val2 & DEV_T2_USB_MASK) { dev_info(&client->dev, "usb connect\n"); if (pdata->usb_cb) { if (force_fast_charge != 0) { dev_info(&client->dev, "[imoseyon] fastcharge\n"); pdata->charger_cb(FSA9485_ATTACHED); } else pdata->usb_cb(FSA9485_ATTACHED); } if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* USB_CDP */ } else if (val1 & DEV_USB_CHG) { dev_info(&client->dev, "usb_cdp connect\n"); if (pdata->usb_cdp_cb) pdata->usb_cdp_cb(FSA9485_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* UART */ } else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) { uart_connecting = 1; dev_info(&client->dev, "uart connect\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); if (pdata->uart_cb) pdata->uart_cb(FSA9485_ATTACHED); if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_UART); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* CHARGER */ } else if (val1 & DEV_T1_CHARGER_MASK) { dev_info(&client->dev, "charger connect\n"); if (pdata->charger_cb) pdata->charger_cb(FSA9485_ATTACHED); /* for SAMSUNG OTG */ } else if (val1 & DEV_USB_OTG) { dev_info(&client->dev, "otg connect\n"); if (pdata->otg_cb) pdata->otg_cb(FSA9485_ATTACHED); i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, 0x27); i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW2, 0x02); msleep(50); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1a); /* JIG */ } else if (val2 & DEV_T2_JIG_MASK) { dev_info(&client->dev, "jig connect\n"); if (pdata->jig_cb) pdata->jig_cb(FSA9485_ATTACHED); /* Desk Dock */ } else if (val2 & DEV_AV) { if ((adc & 0x1F) == ADC_DESKDOCK) { pr_info("FSA Deskdock Attach\n"); FSA9485_CheckAndHookAudioDock(1); usbsw->deskdock = 1; #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) isDeskdockconnected = 1; #endif i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x08); } else { pr_info("FSA MHL Attach\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x08); #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) DisableFSA9480Interrupts(); if (!isDeskdockconnected) mhl_ret = mhl_onoff_ex(1); if (mhl_ret != MHL_DEVICE && (adc & 0x1F) == 0x1A) { FSA9485_CheckAndHookAudioDock(1); isDeskdockconnected = 1; } EnableFSA9480Interrupts(); #else pr_info("FSA mhl attach, but not support MHL feature!\n"); #endif } /* Car Dock */ } else if (val2 & DEV_JIG_UART_ON) { if (pdata->dock_cb) pdata->dock_cb(FSA9485_ATTACHED_CAR_DOCK); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_AUDIO); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->dock_attached = FSA9485_ATTACHED; /* SmartDock */ } else if (val2 & DEV_SMARTDOCK) { usbsw->adc = adc; dev_info(&client->dev, "smart dock connect\n"); usbsw->mansw = SW_DHOST; ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->smartdock_cb) pdata->smartdock_cb(FSA9485_ATTACHED); #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) mhl_onoff_ex(1); #endif } else if (val2 & DEV_AUDIO_DOCK) { usbsw->adc = adc; dev_info(&client->dev, "audio dock connect\n"); usbsw->mansw = SW_DHOST; ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->smartdock_cb) pdata->audio_dock_cb(FSA9485_ATTACHED); } /* Detached */ } else { /* USB */ if (usbsw->dev1 & DEV_USB || usbsw->dev2 & DEV_T2_USB_MASK) { if (pdata->usb_cb) pdata->usb_cb(FSA9485_DETACHED); } else if (usbsw->dev1 & DEV_USB_CHG) { if (pdata->usb_cdp_cb) pdata->usb_cdp_cb(FSA9485_DETACHED); /* UART */ } else if (usbsw->dev1 & DEV_T1_UART_MASK || usbsw->dev2 & DEV_T2_UART_MASK) { if (pdata->uart_cb) pdata->uart_cb(FSA9485_DETACHED); uart_connecting = 0; dev_info(&client->dev, "[FSA9485] uart disconnect\n"); /* CHARGER */ } else if (usbsw->dev1 & DEV_T1_CHARGER_MASK) { if (pdata->charger_cb) pdata->charger_cb(FSA9485_DETACHED); /* for SAMSUNG OTG */ } else if (usbsw->dev1 & DEV_USB_OTG) { i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); /* JIG */ } else if (usbsw->dev2 & DEV_T2_JIG_MASK) { if (pdata->jig_cb) pdata->jig_cb(FSA9485_DETACHED); /* Desk Dock */ } else if (usbsw->dev2 & DEV_AV) { pr_info("FSA MHL Detach\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x04); #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) if (isDeskdockconnected) FSA9485_CheckAndHookAudioDock(0); #if defined CONFIG_MHL_D3_SUPPORT mhl_onoff_ex(false); detached_status = 1; #endif isDeskdockconnected = 0; #else if (usbsw->deskdock) { FSA9485_CheckAndHookAudioDock(0); usbsw->deskdock = 0; } else { pr_info("FSA detach mhl cable, but not support MHL feature\n"); } #endif /* Car Dock */ } else if (usbsw->dev2 & DEV_JIG_UART_ON) { if (pdata->dock_cb) pdata->dock_cb(FSA9485_DETACHED_DOCK); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->dock_attached = FSA9485_DETACHED; } else if (usbsw->adc == 0x10) { dev_info(&client->dev, "smart dock disconnect\n"); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->smartdock_cb) pdata->smartdock_cb(FSA9485_DETACHED); usbsw->adc = 0; #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2) mhl_onoff_ex(false); #endif } else if (usbsw->adc == 0x12) { dev_info(&client->dev, "audio dock disconnect\n"); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); if (pdata->smartdock_cb) pdata->audio_dock_cb(FSA9485_DETACHED); usbsw->adc = 0; } } usbsw->dev1 = val1; usbsw->dev2 = val2; return adc; }
void mhl_onff_handler(struct work_struct *work) //Rajucm { // struct i2c_client *client = local_usbsw->client; printk("praveen: mhl on off handler\n"); //Rajucm: phone Power on with MHL Cable,avoid crash while((!SII9234_i2c_status)) { //4Control enters into while loop only when fsa9480 detects MHL-cable @ phone bootup //printk(KERN_ERR"[FSA9480]## mhl cable detected during boot ## \n"); //i2c_smbus_write_byte_data(client, 0x02, (0x01|i2c_smbus_read_byte_data(client, 0x02))); //DisableFSA9480Interrupts if(!sec_get_lpm_mode()) { printk(KERN_ERR "[FSA9480]## %s ## \n", SII9234_i2c_status? "Ready to start MHL":"Let's Sleep untill MHL condition comes true"); wait_event_interruptible_timeout(fsa9480_MhlWaitEvent, SII9234_i2c_status, msecs_to_jiffies(5*1000)); //5sec: } //skip controlling the sii9234 on lpm mode if(sec_get_lpm_mode()) { //ignore turn on mhl because of only charging mode in power off state! printk(KERN_DEBUG "lpm_mode booting, so there is no to turn on mhl:mhl_onoff[%d]\n",mhl_onoff); //only desk_dock without mhl cable! DisableFSA9480Interrupts(); FSA9480_CheckAndHookAudioDock(USE_DESK_DOCK,mhl_onoff); return; } } if(mhl_onoff) { sii9234_cfg_power(1); //Turn On power to SiI9234 printk("Praveen:The value of mhl_cable_status is %d\n", mhl_cable_status); if(mhl_cable_status == 0x08 || mhl_cable_status == 0x00 || mhl_cable_status == 0x03) { SiI9234_init(); local_usbsw->check_watchdog=0; schedule_delayed_work(&local_usbsw->fsa_watchdog, msecs_to_jiffies(3000)); DisableFSA9480Interrupts(); gpio_set_value_cansleep(GPIO_MHL_SEL, mhl_onoff); } } else { sii9234_cfg_power(0); //Turn Off power to SiI9234 DisableFSA9480Interrupts(); gpio_set_value_cansleep(GPIO_MHL_SEL, mhl_onoff); mhl_cable_status = 0x08; //Once mhl powered off cable status cannot be 0x07; } // this code only for deskdock [ if (!mhl_onoff) { if (usedeskdock) { FSA9480_CheckAndHookAudioDock(USE_DESK_DOCK, 0); } else { FSA9480_CheckAndHookAudioDock(USB_HDMI_CABLE,0); EnableFSA9480Interrupts(); } } // ] }
void FSA9480_CheckAndHookAudioDock(int value, int onoff) { struct i2c_client *client = local_usbsw->client; struct fsa9480_platform_data *pdata = local_usbsw->pdata; int ret = 0; // unsigned int ctrl = CON_MASK; if (onoff) local_usbsw->check_watchdog=1; if (value == USE_DESK_DOCK) { if (onoff) { //skip controlling the sii9234 on lpm mode if(!sec_get_lpm_mode()) { #if defined(CONFIG_VIDEO_MHL_V1) sii9234_cfg_power(0); //Turn Off power to SiI9234 #elif defined(CONFIG_VIDEO_MHL_V2) mhl_onoff_ex(0); //will call hw_onoff(0) #endif gpio_set_value_cansleep(GPIO_MHL_SEL, 0); } ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); dev_info(&client->dev, "FSA9480_CheckAndHookAudioDock On ctrl reg: 0x%x\n", ret); if (pdata->deskdock_cb) pdata->deskdock_cb(FSA9480_ATTACHED); //#if !defined(CONFIG_USA_MODEL_SGH_I717) && !defined (CONFIG_USA_MODEL_SGH_T769) if (!get_sec_det_jack_state()) { if (HWversion ==VERSION_FSA9480) { ret = i2c_smbus_write_byte_data(client,FSA9480_REG_MANSW1,SW_AUDIO); } else { ret = i2c_smbus_write_byte_data(client,FSA9480_REG_MANSW1,AUDIO_9485); } if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); } else printk("%s: Earjack exist..\n", __func__); //#endif ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client,FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW & ~CON_RAW_DATA); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client,FSA9480_REG_INT2_MASK); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_INT2_MASK, ret & ~INT_MASK_ADC_CHANGE); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); usedeskdock= true; isDeskdockconnected=1; Dockconnected = 1; } else { dev_info(&client->dev, "FSA9480_CheckAndHookAudioDock Off ctrl reg: 0x%x\n", ret); if (pdata->deskdock_cb) pdata->deskdock_cb(FSA9480_DETACHED); ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client,FSA9480_REG_CTRL, ret | CON_MANUAL_SW | CON_RAW_DATA); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client,FSA9480_REG_INT2_MASK); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_INT2_MASK, ret | INT_MASK_ADC_CHANGE); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); usedeskdock= false; isDeskdockconnected=0; Dockconnected = 0; } EnableFSA9480Interrupts(); } else if (value == USB_HDMI_CABLE) { if (onoff) { if (pdata->mhl_cb) pdata->mhl_cb(FSA9480_ATTACHED); } else { if (pdata->mhl_cb) pdata->mhl_cb(FSA9480_DETACHED); if (local_usbsw!=NULL) fsa9480_reg_init(local_usbsw); } usedeskdock= false; isDeskdockconnected=0; Dockconnected = 0; } else if (value == USE_VEHICLE_DOCK) { if (onoff) { ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); dev_info(&client->dev, "FSA9480_CheckAndHookAudioDock On ctrl reg: 0x%x\n", ret); //#if !defined(CONFIG_USA_MODEL_SGH_I717) && !defined (CONFIG_USA_MODEL_SGH_T769) if (!get_sec_det_jack_state()) { if (HWversion ==VERSION_FSA9480) { ret = i2c_smbus_write_byte_data(client,FSA9480_REG_MANSW1,SW_AUDIO); } else { ret = i2c_smbus_write_byte_data(client,FSA9480_REG_MANSW1,AUDIO_9485); } if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); } else printk("%s: Earjack exist..\n", __func__); //#endif ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client,FSA9480_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); Dockconnected = 1; } else { dev_info(&client->dev, "FSA9480_CheckAndHookAudioDock Off ctrl reg: 0x%x\n", ret); ret = i2c_smbus_read_byte_data(client,FSA9480_REG_CTRL); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client,FSA9480_REG_CTRL, ret | CON_MANUAL_SW | CON_RAW_DATA); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client,FSA9480_REG_INT2_MASK); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9480_REG_INT2_MASK, ret | INT_MASK_ADC_CHANGE); if (ret < 0) dev_err(&client->dev,"%s: err %d\n", __func__, ret); Dockconnected = 0; } } }
static int fsa9485_detect_dev(struct fsa9485_usbsw *usbsw) { int ret, adc; unsigned int val1, val2, val3; struct fsa9485_platform_data *pdata = usbsw->pdata; struct i2c_client *client = usbsw->client; #if defined(CONFIG_VIDEO_MHL_V2) u8 mhl_ret = 0; #endif val1 = i2c_smbus_read_byte_data(client, FSA9485_REG_DEV_T1); if (val1 < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, val1); return val1; } val2 = i2c_smbus_read_byte_data(client, FSA9485_REG_DEV_T2); if (val2 < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, val2); return val2; } jig_state = (val2 & DEV_T2_JIG_ALL_MASK) ? 1 : 0; if (is_ti_muic()) { val3 = i2c_smbus_read_byte_data(client, FSA9485_REG_DEV_T3); if (val3 < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, val3); return val3; } } else { val3 = i2c_smbus_read_byte_data(client, FSA9485_REG_RESERVED_1D); if (val3 < 0) { dev_err(&client->dev, "%s: err %d\n", __func__, val3); return val3; } val3 = val3 & 0x02; } adc = i2c_smbus_read_byte_data(client, FSA9485_REG_ADC); if (adc == 0x10) val2 = DEV_SMARTDOCK; else if (adc == 0x11 || adc == 0x12) { val2 = DEV_AUDIO_DOCK; dev_err(&client->dev, "adc is audio"); val1 = 0; } dev_err(&client->dev, "dev1: 0x%x, dev2: 0x%x, dev3: 0x%x, ADC: 0x%x Jig:%s\n", val1, val2, val3, adc, (check_jig_state() ? "ON" : "OFF")); if ((val1+val2+val3 != 0)) { pr_info("%s Save state\n", __func__); local_usbsw->last_state.dev1 = val1; local_usbsw->last_state.dev2 = val2; local_usbsw->last_state.dev3 = val3; } /* Attached */ if (val1 || val2 || (val3 & ~DEV_VBUS_DEBOUNCE) || ((val3 & DEV_VBUS_DEBOUNCE) && (adc != ADC_OPEN))) { /* USB */ if (val1 & DEV_USB || val2 & DEV_T2_USB_MASK) { dev_info(&client->dev, "usb connect\n"); pdata->callback(CABLE_TYPE_USB, FSA9485_ATTACHED); local_usbsw->last_state.attach = USB_CALL; if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* USB_CDP */ } else if (val1 & DEV_USB_CHG) { dev_info(&client->dev, "usb_cdp connect\n"); #ifdef CONFIG_TSU6721_CDP_FIX pdata->callback(CABLE_TYPE_CDP, is_ti_muic() ? TSU6721_ATTACHED : FSA9485_ATTACHED); #else pdata->callback(CABLE_TYPE_CDP, FSA9485_ATTACHED); #endif local_usbsw->last_state.attach = CDP_CALL; if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, usbsw->mansw); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* UART */ } else if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) { uart_connecting = 1; dev_info(&client->dev, "uart connect\n"); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); pdata->callback(CABLE_TYPE_UARTOFF, FSA9485_ATTACHED); local_usbsw->last_state.attach = UART_CALL; if (usbsw->mansw) { ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_UART); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); } /* CHARGER */ } else if ((val1 & DEV_T1_CHARGER_MASK) || (val3 & DEV_T3_CHARGER_MASK)) { dev_info(&client->dev, "charger connect\n"); pdata->callback(CABLE_TYPE_AC, FSA9485_ATTACHED); local_usbsw->last_state.attach = CHARGER_CALL; /* for SAMSUNG OTG */ #if defined(CONFIG_USB_HOST_NOTIFY) } else if (val1 & DEV_USB_OTG) { dev_info(&client->dev, "otg connect\n"); pdata->callback(CABLE_TYPE_OTG, FSA9485_ATTACHED); local_usbsw->last_state.attach = OTG_CALL; i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, is_ti_muic() ? 0x25 : 0x27); i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW2, 0x02); msleep(50); i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1a); #endif /* JIG */ } else if (val2 & DEV_T2_JIG_MASK) { dev_info(&client->dev, "jig connect\n"); pdata->callback(CABLE_TYPE_JIG, FSA9485_ATTACHED); local_usbsw->last_state.attach = JIG_CALL; /* Desk Dock */ } else if ((val2 & DEV_AV) || (val3 & DEV_MHL) || (val3 & DEV_AV_VBUS)) { if ((!is_ti_muic()) && ((adc & 0x1F) == 0x1A)) { pr_info("FSA Deskdock Attach\n"); FSA9485_CheckAndHookAudioDock(1); #if defined(CONFIG_VIDEO_MHL_V2) isDeskdockconnected = 1; #endif i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x08); } else if ((is_ti_muic()) && !(val3 & DEV_MHL)) { pr_info("TI Deskdock Attach\n"); FSA9485_CheckAndHookAudioDock(1); #if defined(CONFIG_VIDEO_MHL_V2) isDeskdockconnected = 1; #endif } else { pr_info("MHL Attach\n"); if (!is_ti_muic()) i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x08); #if defined(CONFIG_VIDEO_MHL_V2) DisableFSA9480Interrupts(); if (!isDeskdockconnected) { if (!poweroff_charging) mhl_ret = mhl_onoff_ex(1); else pr_info("LPM mode, skip MHL sequence\n"); } local_usbsw->last_state.device = MHL_CALL; if (mhl_ret != MHL_DEVICE && (adc & 0x1F) == 0x1A) { FSA9485_CheckAndHookAudioDock(1); isDeskdockconnected = 1; } EnableFSA9480Interrupts(); #else FSA9485_CheckAndHookAudioDock(1); #endif } /* Car Dock */ } else if (val2 & DEV_JIG_UART_ON) { pdata->callback(CABLE_TYPE_CARDOCK, FSA9485_ATTACHED); local_usbsw->last_state.attach = CARDOCK_CALL; ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_AUDIO); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->dock_attached = FSA9485_ATTACHED; /* SmartDock */ } else if (val2 & DEV_SMARTDOCK) { usbsw->adc = adc; dev_info(&client->dev, "smart dock connect\n"); usbsw->mansw = SW_DHOST; ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); pdata->callback(CABLE_TYPE_SMART_DOCK, FSA9485_ATTACHED); local_usbsw->last_state.attach = SMARTDOCK_CALL; #if defined(CONFIG_VIDEO_MHL_V2) mhl_onoff_ex(1); #endif #if defined(CONFIG_USB_HOST_NOTIFY) /* Audio Dock */ } else if (val2 & DEV_AUDIO_DOCK) { usbsw->adc = adc; dev_info(&client->dev, "audio dock connect\n"); usbsw->mansw = SW_DHOST; if (is_ti_muic()) ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST_TSU); else ret = i2c_smbus_write_byte_data(client, FSA9485_REG_MANSW1, SW_DHOST); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret & ~CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); pdata->callback(CABLE_TYPE_AUDIO_DOCK, FSA9485_ATTACHED); local_usbsw->last_state.attach = AUDIODOCK_CALL; #endif /* Incompatible */ } else if (val3 & DEV_VBUS_DEBOUNCE) { dev_info(&client->dev, "Incompatible Charger connect\n"); pdata->callback(CABLE_TYPE_INCOMPATIBLE, FSA9485_ATTACHED); local_usbsw->last_state.attach = INCOMPATIBLE_CALL; } /* Detached */ } else { /* USB */ if (usbsw->dev1 & DEV_USB || usbsw->dev2 & DEV_T2_USB_MASK) { pdata->callback(CABLE_TYPE_USB, FSA9485_DETACHED); local_usbsw->last_state.detach = USB_CALL; } else if (usbsw->dev1 & DEV_USB_CHG) { pdata->callback(CABLE_TYPE_CDP, FSA9485_DETACHED); local_usbsw->last_state.detach = CDP_CALL; /* UART */ } else if (usbsw->dev1 & DEV_T1_UART_MASK || usbsw->dev2 & DEV_T2_UART_MASK) { pdata->callback(CABLE_TYPE_UARTOFF, FSA9485_DETACHED); local_usbsw->last_state.detach = UART_CALL; uart_connecting = 0; dev_info(&client->dev, "[FSA9485] uart disconnect\n"); /* CHARGER */ } else if ((usbsw->dev1 & DEV_T1_CHARGER_MASK) || (usbsw->dev3 & DEV_T3_CHARGER_MASK)) { pdata->callback(CABLE_TYPE_AC, FSA9485_DETACHED); local_usbsw->last_state.detach = CHARGER_CALL; /* for SAMSUNG OTG */ } else if (usbsw->dev1 & DEV_USB_OTG) { i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, 0x1E); /* JIG */ } else if (usbsw->dev2 & DEV_T2_JIG_MASK) { pdata->callback(CABLE_TYPE_JIG, FSA9485_DETACHED); local_usbsw->last_state.detach = JIG_CALL; /* Desk Dock */ } else if ((usbsw->dev2 & DEV_AV) || (usbsw->dev3 & DEV_MHL) || (usbsw->dev3 & DEV_AV_VBUS)) { pr_info("Deskdock/MHL Detach\n"); if (!is_ti_muic()) i2c_smbus_write_byte_data(client, FSA9485_REG_RESERVED_20, 0x04); #if defined(CONFIG_VIDEO_MHL_V2) if (isDeskdockconnected) FSA9485_CheckAndHookAudioDock(0); #if defined CONFIG_MHL_D3_SUPPORT mhl_onoff_ex(false); detached_status = 1; #endif isDeskdockconnected = 0; #else FSA9485_CheckAndHookAudioDock(0); #endif /* Car Dock */ } else if (usbsw->dev2 & DEV_JIG_UART_ON) { pdata->callback(CABLE_TYPE_CARDOCK, FSA9485_DETACHED_DOCK); local_usbsw->last_state.detach = CARDOCK_CALL; ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); usbsw->dock_attached = FSA9485_DETACHED; } else if (usbsw->adc == 0x10) { dev_info(&client->dev, "smart dock disconnect\n"); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); pdata->callback(CABLE_TYPE_SMART_DOCK, FSA9485_DETACHED); local_usbsw->last_state.detach = SMARTDOCK_CALL; usbsw->adc = 0; #if defined(CONFIG_VIDEO_MHL_V2) mhl_onoff_ex(false); #endif } else if (usbsw->dev2 == DEV_AUDIO_DOCK) { dev_info(&client->dev, "audio dock disconnect\n"); ret = i2c_smbus_read_byte_data(client, FSA9485_REG_CTRL); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); ret = i2c_smbus_write_byte_data(client, FSA9485_REG_CTRL, ret | CON_MANUAL_SW); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); pdata->callback(CABLE_TYPE_AUDIO_DOCK, FSA9485_DETACHED); local_usbsw->last_state.detach = AUDIODOCK_CALL; usbsw->adc = 0; } else if (usbsw->dev3 & DEV_VBUS_DEBOUNCE) { dev_info(&client->dev, "Incompatible Charger disconnect\n"); pdata->callback(CABLE_TYPE_INCOMPATIBLE, FSA9485_DETACHED); local_usbsw->last_state.detach = INCOMPATIBLE_CALL; } } usbsw->dev1 = val1; usbsw->dev2 = val2; usbsw->dev3 = val3; return adc; }