s32 muic_max14526_detect_accessory(s32 upon_irq) { s32 ret = 0; u8 int_stat_value; /* Upon an MUIC IRQ (MUIC_INT_N falls), * wait 70ms before reading INT_STAT and STATUS. * After the reads, MUIC_INT_N returns to high * (but the INT_STAT and STATUS contents will be held). * * Do this only if muic_max14526_detect_accessory() was called upon IRQ. */ muic_mdelay(250); /* Reads INT_STAT */ ret = muic_i2c_read_byte(INT_STAT, &int_stat_value); printk(KERN_WARNING "[MUIC] muic_max14526_detect_accessory, int_stat_value = 0x%02x \n", int_stat_value); if (ret < 0) { printk(KERN_INFO "[MUIC] INT_STAT reading failed\n"); muic_mode = MUIC_UNKNOWN; charging_mode = CHARGING_UNKNOWN; return ret; } /* Branches according to the previous muic_mode */ switch (muic_mode) { /* MUIC_UNKNOWN is reached in two cases both do not have nothing to do with IRQ. * First, at the initialization time where the muic_mode is not available yet. * Second, whenever the current muic_mode detection is failed. */ case MUIC_UNKNOWN : /* If the previous muic_mode was MUIC_NONE, * the only possible condition for a MUIC IRQ is plugging in an accessory. */ case MUIC_NONE : set_max14526_muic_mode(int_stat_value); break; /* If the previous muic_mode was MUIC_NA_TA, MUIC_LG_TA, MUIC_TA_1A, MUIC_INVALID_CHG, * MUIC_AP_UART, MUIC_CP_UART, MUIC_AP_USB, MUIC_OTG, or MUIC_CP_USB, * the only possible condition for a MUIC IRQ is plugging out the accessory. * * In this case, initialize MUIC and wait an IRQ. * We don't need to wait 250msec because this is not an erronous case * (we need to reset the facility to set STATUS for an erronous case and * have to wait 250msec) and, if this is not an erronous case, the facility * was already initialized at the system booting. */ case MUIC_NA_TA: case MUIC_TA_1A: case MUIC_INVALID_CHG : case MUIC_LG_TA : case MUIC_AP_UART : case MUIC_CP_UART : case MUIC_AP_USB : case MUIC_CP_USB : if ((int_stat_value & V_VBUS) != 0) { // V_VBUS == 1 set_max14526_muic_mode(int_stat_value); } else if ((int_stat_value & IDNO) == IDNO_1011) { // V_VBUS == 0 charging_mode = CHARGING_NONE; muic_mode = MUIC_NONE; } else set_max14526_muic_mode(int_stat_value); break; #if defined(CONFIG_MHL_TX_SII9244) case MUIC_MHL : printk(KERN_WARNING "[MUIC] Detect step3 MHL \n"); if ((int_stat_value & V_VBUS) == 0) { MHL_On(0); muic_mode = MUIC_NONE; charging_mode = CHARGING_NONE; } if( ((int_stat_value & V_VBUS) != 0) && (!gpio_get_value(GPIO_MHL_SEL)) && ((int_stat_value & IDNO) == IDNO_0000) ) { MHL_On(1); //re-enable MHL muic_mode = MUIC_MHL; charging_mode = CHARGING_USB; } break; #endif default: printk(KERN_WARNING "[MUIC] Failed to detect an accessory. Try again!"); muic_mode = MUIC_UNKNOWN; charging_mode = CHARGING_UNKNOWN; ret = -1; break; } printk(KERN_WARNING "[MUIC] muic_max14526_detect_accessory, muic_mode = %s (%d) \n", muic_mode_str[muic_mode], muic_mode ); if (muic_mode == MUIC_UNKNOWN || muic_mode == MUIC_NONE) { muic_init_max14526(RESET); gpio_set_value(IFX_USB_VBUS_EN_GPIO, 0); printk(KERN_INFO "[MUIC] charging_ic_deactive()\n"); } return ret; }
static int __devinit max14526_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; TYPE_MUIC_MODE muic_mode; struct ts5usb_device *dev = NULL; struct muic_platform_data *pdata = client->dev.platform_data; dev_info(&client->dev, "muic: %s()\n", __func__); if (!pdata) { dev_err(&client->dev, "muic: %s: no platform data\n", __func__); return -EINVAL; } dev = kzalloc(sizeof(struct ts5usb_device), GFP_KERNEL); if (!dev) { dev_err(&client->dev, "muic: %s: no memory\n", __func__); return -ENOMEM; } dev->client = client; dev->gpio_int = pdata->gpio_int; #if defined(CONFIG_MHL) dev->gpio_mhl = pdata->gpio_mhl; dev->gpio_ifx_vbus = pdata->gpio_ifx_vbus; #endif dev->irq = client->irq; max14526 = client; /* Initializes gpio_165 (USIF1_SW). */ ret = gpio_request(USIF_IN_1_GPIO, "USIF switch control GPIO"); if (ret < 0) { printk(KERN_INFO "[MUIC] GPIO 165 USIF1_SW is already occupied by other driver!\n"); /* * We know board_cosmo.c:ifx_n721_configure_gpio() performs a gpio_request on this pin first. * Because the prior gpio_request is also for the analog switch control, this is not a confliction. */ return -ENOSYS; } ret = gpio_direction_output(USIF_IN_1_GPIO, 0); if (ret < 0) { printk(KERN_INFO "[MUIC] gpio_16 USIF_IN_1_GPIO direction initialization failed!\n"); return -ENOSYS; } /* Initializes gpio_11 (OMAP_UART_SW) and gpio_12 (IFX_UART_SW) */ ret = gpio_request(DP3T_IN_1_GPIO, "DP3T switch control 1 GPIO"); if (ret < 0) { printk(KERN_INFO "[MUIC] GPIO 11 DP3T_IN_1_GPIO is already occupied by other driver!\n"); return -ENOSYS; } ret = gpio_direction_output(DP3T_IN_1_GPIO, 0); if (ret < 0) { printk(KERN_INFO "[MUIC] gpio_11 DP3T_IN_1_GPIO direction initialization failed!\n"); return -ENOSYS; } ret = gpio_request(DP3T_IN_2_GPIO, "DP3T switch control 2 GPIO"); if (ret < 0) { printk(KERN_INFO "[MUIC] gpio_12 DP3T_IN_2_GPIO is already occupied by other driver!\n"); return -ENOSYS; } ret = gpio_direction_output(DP3T_IN_2_GPIO, 0); if (ret < 0) { printk(KERN_INFO "[MUIC] gpio_12 DP3T_IN_2_GPIO direction initialization failed!\n"); return -ENOSYS; } ret = gpio_request(IFX_USB_VBUS_EN_GPIO, "DP3T switch control 2 GPIO"); if (ret < 0) { printk(KERN_INFO "[MUIC] gpio_55 IFX_USB_VBUS_EN_GPIO is already occupied by other driver!\n"); return -ENOSYS; } ret = gpio_direction_output(IFX_USB_VBUS_EN_GPIO, 0); if (ret < 0) { printk(KERN_INFO "[MUIC] gpio_55 IFX_USB_VBUS_EN_GPIO direction initialization failed!\n"); return -ENOSYS; } /* * Initializes gpio_wk8 (MUIC_INT_N). * Checks if other driver already occupied it. */ ret = gpio_request(dev->gpio_int, "MUIC IRQ GPIO"); if (ret < 0) { dev_err(&client->dev, "muic: GPIO %d is already used\n", dev->gpio_int); ret = -ENOSYS; goto err_gpio_request; } /* Initializes GPIO direction before use or IRQ setting */ gpio_direction_input(dev->gpio_int); /* Registers MUIC work queue function */ INIT_WORK(&dev->muic_wq, max14526_wq_func); /* * Set up an IRQ line and enable the involved interrupt handler. * From this point, a MUIC_INT_N can invoke muic_interrupt_handler(). * muic_interrupt_handler merely calls schedule_work() with muic_wq_func(). * muic_wq_func() actually performs the accessory detection. */ ret = request_irq(dev->irq, max14526_interrupt_handler,IRQF_TRIGGER_FALLING, "muic_irq", dev); if (ret < 0) { dev_err(&client->dev, "muic: %s: request_irq failed!\n",__func__); goto err_request_irq; } //disable_irq_wake(gpio_to_irq(MUIC_INT)); /* Prepares a human accessible method to control MUIC */ //create_cosmo_muic_proc_file(); /* Selects one of the possible muic chips */ //muic_detect_device(); wake_lock_init(&dev->muic_wake_lock, WAKE_LOCK_SUSPEND,"muic_wake_lock"); ret = muic_device_register(&muic_dev, NULL); if (ret < 0) { dev_err(&client->dev, "muic: %s: muic_device_register failed\n",__func__); goto err_muic_device_register; } i2c_set_clientdata(client, dev); // hunsoo.lee printk("%s, registering ops\n", __func__); muic_client_dev_register(dev->client->name, dev, &max14526_ops); /* Initializes MUIC - Finally MUIC INT becomes enabled */ if (BOOT_RECOVERY == muic_retain_mode) { /* Recovery mode */ muic_mode = MUIC_CP_UART; muic_init_max14526(client, BOOTUP); dev_info(&client->dev, "muic: %s: first boot\n", __func__); } else { muic_init_max14526(client, RESET); muic_max14526_detect_accessory(client, NOT_UPON_IRQ); muic_mode = muic_get_mode(); } muic_set_mode(muic_mode); /* Makes the interrupt on MUIC INT wake up OMAP which is in suspend mode */ ret = enable_irq_wake(dev->irq); if (ret < 0) { dev_err(&client->dev, "muic: GPIO %d wake up source setting failed!\n", dev->gpio_int); disable_irq_wake(dev->irq); goto err_irq_wake; } dev_info(&client->dev, "muic: muic_probe()\n"); return ret; err_irq_wake: muic_device_unregister(&muic_dev); err_muic_device_register: wake_lock_destroy(&dev->muic_wake_lock); free_irq(dev->irq, dev); err_request_irq: gpio_free(dev->gpio_int); err_gpio_request: kfree(dev); return ret; }
s32 muic_max14526_detect_accessory(s32 upon_irq) { s32 ret = 0; u8 int_stat_value; /* For detecting time */ muic_mdelay(250); /* Reads INT_STAT */ ret = muic_i2c_read_byte(muic_client,INT_STAT, &int_stat_value); printk(KERN_WARNING "[MUIC] muic_max14526_detect_accessory, int_stat_value = 0x%02x \n", int_stat_value); if (ret < 0) { printk(KERN_INFO "[MUIC] INT_STAT reading failed\n"); muic_path = MUIC_UNKNOWN; charging_mode = CHARGING_UNKNOWN; //LGE_CHANGE_S [[email protected]] let charger know muic detected charger type.. //set_muic_charger_detected(); return ret; } /* Branches according to the previous muic_path */ switch (muic_path) { /* MUIC_UNKNOWN is reached in two cases both do not have nothing to do with IRQ. * First, at the initialization time where the muic_path is not available yet. * Second, whenever the current muic_path detection is failed. */ case MUIC_UNKNOWN : /* If the previous muic_path was MUIC_NONE, * the only possible condition for a MUIC IRQ is plugging in an accessory. */ case MUIC_NONE : set_max14526_muic_path(int_stat_value); break; /* If the previous muic_path was MUIC_NA_TA, MUIC_LG_TA, MUIC_TA_1A, MUIC_INVALID_CHG, * MUIC_AP_UART, MUIC_CP_UART, MUIC_AP_USB, MUIC_OTG, or MUIC_CP_USB, * the only possible condition for a MUIC IRQ is plugging out the accessory. * * In this case, initialize MUIC and wait an IRQ. * We don't need to wait 250msec because this is not an erronous case * (we need to reset the facility to set STATUS for an erronous case and * have to wait 250msec) and, if this is not an erronous case, the facility * was already initialized at the system booting. */ case MUIC_NA_TA: case MUIC_TA_1A: case MUIC_INVALID_CHG : case MUIC_LG_TA : case MUIC_AP_UART : case MUIC_CP_UART : case MUIC_AP_USB : case MUIC_CP_USB : if ((int_stat_value & VBUS) != 0) { set_max14526_muic_path(int_stat_value); } else if ((int_stat_value & IDNO) == IDNO_1011) { charging_mode = CHARGING_NONE; muic_path = MUIC_NONE; } else set_max14526_muic_path(int_stat_value); break; default : printk(KERN_WARNING "[MUIC] Failed to detect an accessory. Try again!"); muic_path = MUIC_UNKNOWN; charging_mode = CHARGING_UNKNOWN; ret = -1; } printk(KERN_WARNING "[MUIC] muic_max14526_detect_accessory, muic_path = %s, charing = %s\n", muic_path_str[muic_path], charging_mode_str[charging_mode]); if (muic_path == MUIC_UNKNOWN || muic_path == MUIC_NONE) { muic_init_max14526(RESET); gpio_set_value(IFX_USB_VBUS_EN_GPIO, 0); printk(KERN_INFO "[MUIC] charging_ic_deactive()\n"); } //LGE_CHANGE_S [[email protected]] let charger know muic detected charger type.. //set_muic_charger_detected(); return ret; }
s32 muic_max14526_detect_accessory(struct i2c_client *client, s32 upon_irq) { s32 ret = 0; s32 loop = 0; u8 int_stat_value=0; TYPE_MUIC_MODE muic_mode = muic_get_mode(); struct ts5usb_device *dev = i2c_get_clientdata(client); /* * Upon an MUIC IRQ (MUIC_INT_N falls), * wait 70ms before reading INT_STATUS1 and STATUS. * After the reads, MUIC_INT_N returns to high * (but the INT_STATUS1 and STATUS contents will be held). * * Do this only if muic_max14526_detect_accessory() was called upon IRQ. */ if (upon_irq) { mdelay(70); } /* Read INT_STATUS1 */ ret = muic_i2c_read_byte(client, INT_STAT, &int_stat_value); dev_info(&client->dev, "muic: %s: int_stat_value:0x%x :%d\n", __func__, int_stat_value, muic_mode); if (ret < 0) { dev_info(&client->dev, "muic: INT_STATUS1 reading failed\n"); muic_set_mode(MUIC_UNKNOWN); return ret; } switch (muic_mode) {/* Branch according to the previous muic_mode */ case MUIC_UNKNOWN : case MUIC_NONE : muic_set_device_none_detect(client, int_stat_value); break; case MUIC_AP_UART : case MUIC_CP_UART : dev_info(&client->dev, "muic: MUIC_AP_UART || MUIC_CP_UART\n"); if(!(int_stat_value & VBUS)&&(IDNO_0010 == (int_stat_value & 0x0f))) { muic_set_mode(MUIC_CP_USB); } else if (!(int_stat_value & VBUS)) { muic_i2c_write_byte(client, SW_CONTROL, DP_UART | DM_UART); muic_set_mode(MUIC_NONE); } else { dev_info(&client->dev, "UART is not removed\n"); } break; case MUIC_NA_TA : case MUIC_LG_TA : case MUIC_TA_1A : case MUIC_INVALID_CHG : dev_info(&client->dev, "muic: Detect step2\n"); if (((int_stat_value & VBUS) == 0) ||((int_stat_value & CHGDET) == 0)) { muic_set_mode(MUIC_NONE); } else { dev_info(&client->dev, "TA is not removed\n"); } break; case MUIC_AP_USB : /* USB Host Removed */ if((int_stat_value & VBUS) == 0) { android_USB_disconnect();// for usb disconnect event muic_set_mode(MUIC_NONE); } else { dev_info(&client->dev, "AP USB is not removed\n"); } break; case MUIC_CP_USB : if((int_stat_value & VBUS) == 0) { muic_set_mode(MUIC_NONE); } else { dev_info(&client->dev, "CP USB is not removed\n"); } break; #if defined(CONFIG_MHL_TX_SII9244) || defined(CONFIG_MHL_TX_SII9244_LEGACY) case MUIC_MHL : dev_info(&client->dev, "muic: Detect step3 mhl \n"); if ((int_stat_value & VBUS) == 0) { //MHL_On(0); muic_set_mode(MUIC_NONE); } break; #endif default: dev_info(&client->dev, "muic: Failed to detect an accessory. Try again!"); muic_set_mode(MUIC_UNKNOWN); ret = -1; break; } muic_mode = muic_get_mode(); dev_info(&client->dev, "muic: muic_detection_mode=%d \n", muic_mode); if (muic_mode == MUIC_UNKNOWN || muic_mode == MUIC_NONE) { #if defined(CONFIG_MHL) && defined(CONFIG_MHL_TX_MUIC_BUG_FIX) /* SJIT 2012-01-27 [[email protected]] P940 GB * max14526 300ms delay side effect bug fixed test code */ if (Int_Status == Second_Int) { if (!gpio_get_value(dev->gpio_mhl)) { dev_info(&client->dev, "muic: wait for mhl switch completed\n"); muic_init_max14526(client, DEFAULT); gpio_set_value(dev->gpio_ifx_vbus, 0); } else { dev_info(&client->dev, "muic: mhl switch not completed\n"); while (!gpio_get_value(dev->gpio_mhl)) { udelay(500); muic_set_mode(MUIC_MHL); // MHL_On(0); } dev_info(&client->dev, "muic: mhl switch completed\n"); muic_init_max14526(client, DEFAULT); gpio_set_value(dev->gpio_ifx_vbus, 0); } } else { muic_init_max14526(client, DEFAULT); gpio_set_value(dev->gpio_ifx_vbus, 0); } #else muic_init_max14526(client, RESET); gpio_set_value(IFX_USB_VBUS_EN_GPIO, 0); //charging_ic_deactive(); dev_info(&client->dev, "muic: charging_ic_deactive()\n"); #endif } // LGE_CHANGES_S [[email protected]] 2012-03-19 #if defined(CONFIG_MAX8971_CHARGER) if(muic_mode == MUIC_NA_TA || muic_mode == MUIC_LG_TA || muic_mode == MUIC_TA_1A) { printk("[MUIC] max8971_start_charging TA\n"); max8971_start_charging(900); } else if(muic_mode == MUIC_AP_USB) { printk("[MUIC]max8971_start_charging USB\n"); max8971_start_charging(500); } /* else if( muic_mode == MUIC_CP_USB || muic_mode == MUIC_CP_UART) { printk("[MUIC] max8971_start_charging Factory\n"); max8971_start_charging(1550); } */ else if( muic_mode == MUIC_CP_USB ) { //printk("[MUIC] max8971_stop due to MUIC_CP_USB mode \n"); printk("[MUIC] max8971_start_charging Factory MUIC_CP_USB \n"); // max8971_start_charging(1550); // max8971_stop_charging(); max8971_start_Factory_charging(); } else if( muic_mode == MUIC_CP_UART) { printk("[MUIC] max8971_start_charging Factory MUIC_CP_UART \n"); //printk("[MUIC] max8971_stop due to MUIC_CP_UART mode \n"); // max8971_stop_charging(); // max8971_start_charging(1550); max8971_start_Factory_charging(); } else if( muic_mode == MUIC_MHL) { printk("[MUIC] max8971_start_charging MHL\n"); max8971_start_charging(400); } else if( muic_mode == MUIC_NONE) { printk("[MUIC] max8971_stop_charging\n"); max8971_stop_charging(); } else printk("[MUIC] can not open muic mode\n"); // LGE_CHANGES_E [[email protected]] 2012-03-19 #endif return ret; }
void set_max14526_muic_mode(unsigned char int_stat_value) { unsigned char reg_value; printk(KERN_WARNING "[chahee.kim] set_max14526_muic_mode, " "int_stat_value = %x \n", int_stat_value); if (int_stat_value & CHGDET) { set_max14526_charger_mode(int_stat_value); #ifndef CHARGER_TEST lge_charger_ta_mode_enable(); #endif } else if (int_stat_value & VBUS) { if ((int_stat_value & IDNO) == IDNO_0101) { set_max14526_ap_usb_mode(); #ifndef CHARGER_TEST lge_charger_usb_mode_enable(); #endif } else { /* Standard USB Host Detected (0x03=0x23) */ muic_i2c_write_byte(SW_CONTROL, COMP2_TO_HZ | COMN1_TO_C1COMP); muic_udelay(1000); /* Read Status Reigster(0x05) */ muic_i2c_read_byte(STATUS, ®_value); if (reg_value & C1COMP) { /* Charger Detected COMP2/COMN1 to H-Z (0x03=0x24) */ muic_i2c_write_byte(SW_CONTROL, COMP2_TO_HZ | COMN1_TO_HZ); /* Dedicated Charger(TA) Detected */ muic_mode = MUIC_NA_TA; } else { /* Turn on USB switches */ set_max14526_ap_usb_mode(); #ifndef CHARGER_TEST lge_charger_usb_mode_enable(); #endif } } } else if ((int_stat_value & IDNO) == IDNO_0010) { //set_max14526_cp_usb_mode(); set_max14526_ap_uart_mode(); #ifndef CHARGER_TEST lge_charger_disable(); #endif } else if ((int_stat_value & IDNO) == IDNO_0101) { set_max14526_ap_uart_mode(); #ifndef CHARGER_TEST lge_charger_disable(); #endif } else { /* Accessory Not Supported */ muic_mode = MUIC_NONE; muic_init_max14526(DEFAULT); #ifndef CHARGER_TEST lge_charger_disable(); #endif } }