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, &reg_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
	}
}