int msm_camera_flash_external(
	struct msm_camera_sensor_flash_external *external,
	unsigned led_state)
{
	int rc = 0;

	switch (led_state) {
//B 2012/07/22
#ifdef CONFIG_LEDS_LM3561
    case MSM_CAMERA_LED_INIT:
        lm3561 = lm3561_init();
        break;
    case MSM_CAMERA_LED_RELEASE:
        //B 2012/08/20
        lm3561_release(lm3561);
        lm3561 = NULL;
        //E 2012/08/20
        break;
    case MSM_CAMERA_LED_OFF:
        //B 2012/11/06
        if (flash_auto && board_type_with_hw_id() > DVT2_BOARD_HW_ID) {
            flash_auto = 0;
        } else {
            lm3561_flash_set(lm3561, 0);
        }
        //E 2012/11/06
        break;
    case MSM_CAMERA_LED_LOW:
        lm3561_torch_set(lm3561, 1);
        break;
    case MSM_CAMERA_LED_HIGH:
        //B 2012/11/06
        if (board_type_with_hw_id() <= DVT2_BOARD_HW_ID) {
            lm3561_flash_set(lm3561, 1);
        } else {
            msm_sensor_set_flash(1);
            flash_auto = 1;
        }
        //E 2012/11/06
        break;
    default:
        rc = -EFAULT;
        break;
#else
	case MSM_CAMERA_LED_INIT:
		if (external->flash_id == MAM_CAMERA_EXT_LED_FLASH_SC628A) {
			if (!sc628a_client) {
				rc = i2c_add_driver(&sc628a_i2c_driver);
				if (rc < 0 || sc628a_client == NULL) {
					pr_err("sc628a_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else if (external->flash_id ==
			MAM_CAMERA_EXT_LED_FLASH_TPS61310) {
			if (!tps61310_client) {
				rc = i2c_add_driver(&tps61310_i2c_driver);
				if (rc < 0 || tps61310_client == NULL) {
					pr_err("tps61310_i2c_driver add failed\n");
					rc = -ENOTSUPP;
					return rc;
				}
			}
		} else {
			pr_err("Flash id not supported\n");
			rc = -ENOTSUPP;
			return rc;
		}

#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && !sx150x_client) {
			struct i2c_adapter *adapter =
			i2c_get_adapter(external->expander_info->bus_id);
			if (adapter)
				sx150x_client = i2c_new_device(adapter,
					external->expander_info->board_info);
			if (!sx150x_client || !adapter) {
				pr_err("sx150x_client is not available\n");
				rc = -ENOTSUPP;
				if (sc628a_client) {
					i2c_del_driver(&sc628a_i2c_driver);
					sc628a_client = NULL;
				}
				if (tps61310_client) {
					i2c_del_driver(&tps61310_i2c_driver);
					tps61310_client = NULL;
				}
				return rc;
			}
			i2c_put_adapter(adapter);
		}
#endif
		if (sc628a_client)
			rc = gpio_request(external->led_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_en, 0);
		} else {
			goto error;
		}

		if (sc628a_client)
			rc = gpio_request(external->led_flash_en, "sc628a");
		if (tps61310_client)
			rc = gpio_request(external->led_flash_en, "tps61310");

		if (!rc) {
			gpio_direction_output(external->led_flash_en, 0);
			break;
		}

		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
		}
error:
		pr_err("%s gpio request failed\n", __func__);
		if (sc628a_client) {
			i2c_del_driver(&sc628a_i2c_driver);
			sc628a_client = NULL;
		}
		if (tps61310_client) {
			i2c_del_driver(&tps61310_i2c_driver);
			tps61310_client = NULL;
		}
		break;

	case MSM_CAMERA_LED_RELEASE:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_free(external->led_en);
			gpio_set_value_cansleep(external->led_flash_en, 0);
			gpio_free(external->led_flash_en);
			if (sc628a_client) {
				i2c_del_driver(&sc628a_i2c_driver);
				sc628a_client = NULL;
			}
			if (tps61310_client) {
				if (timer_state) {
					del_timer(&flash_timer);
					kfree((void *)work);
					timer_state = 0;
				}
				i2c_del_driver(&tps61310_i2c_driver);
				tps61310_client = NULL;
			}
		}
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
		if (external->expander_info && sx150x_client) {
			i2c_unregister_device(sx150x_client);
			sx150x_client = NULL;
		}
#endif
		break;

	case MSM_CAMERA_LED_OFF:
		if (sc628a_client || tps61310_client) {
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x00, MSM_CAMERA_I2C_BYTE_DATA);
				if (timer_state) {
					del_timer(&flash_timer);
					kfree((void *)work);
					timer_state = 0;
				}
			}
			gpio_set_value_cansleep(external->led_en, 0);
			gpio_set_value_cansleep(external->led_flash_en, 0);
		}
		break;

	case MSM_CAMERA_LED_LOW:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x06, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x46, MSM_CAMERA_I2C_BYTE_DATA);
				flash_wq = alloc_workqueue("my_queue",WQ_MEM_RECLAIM,1);
				work = (struct flash_work *)kmalloc(sizeof(struct flash_work), GFP_KERNEL);
				INIT_WORK( (struct work_struct *)work, flash_wq_function );
				setup_timer(&flash_timer, flash_timer_callback, 0);
				mod_timer(&flash_timer, jiffies + msecs_to_jiffies(10000));
				timer_state = 1;
			}
		}
		break;

	case MSM_CAMERA_LED_HIGH:
		if (sc628a_client || tps61310_client) {
			gpio_set_value_cansleep(external->led_en, 1);
			gpio_set_value_cansleep(external->led_flash_en, 1);
			usleep_range(2000, 3000);
			if (sc628a_client) {
				i2c_client.client = sc628a_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x02,
					0x49, MSM_CAMERA_I2C_BYTE_DATA);
			}
			if (tps61310_client) {
				i2c_client.client = tps61310_client;
				i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;
				rc = msm_camera_i2c_write(&i2c_client, 0x01,
					0x8B, MSM_CAMERA_I2C_BYTE_DATA);
			}
		}
		break;

	default:
		rc = -EFAULT;
		break;
#endif
//E 2012/07/22
	}
	return rc;
}
static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
	const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
	struct gpio_keys_drvdata *ddata;
	struct device *dev = &pdev->dev;
	struct gpio_keys_platform_data alt_pdata;
	struct input_dev *input;
	int i, error;
	int wakeup = 0;

	if (!pdata) {
		error = gpio_keys_get_devtree_pdata(dev, &alt_pdata);
		if (error)
			return error;
		pdata = &alt_pdata;
	}

	ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
			pdata->nbuttons * sizeof(struct gpio_button_data),
			GFP_KERNEL);
	input = input_allocate_device();
	if (!ddata || !input) {
		dev_err(dev, "failed to allocate state\n");
		error = -ENOMEM;
		goto fail1;
	}

	ddata->input = input;
	ddata->n_buttons = pdata->nbuttons;
	ddata->enable = pdata->enable;
	ddata->disable = pdata->disable;
	mutex_init(&ddata->disable_lock);

	platform_set_drvdata(pdev, ddata);
	input_set_drvdata(input, ddata);

	input->name = pdata->name ? : pdev->name;
	input->phys = "gpio-keys/input0";
	input->dev.parent = &pdev->dev;
	input->open = gpio_keys_open;
	input->close = gpio_keys_close;

	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0100;

	/* Enable auto repeat feature of Linux input subsystem */
	if (pdata->rep)
		__set_bit(EV_REP, input->evbit);
 
#if 0
	error = gpio_request(GPIO_CAMERA_CTRL, NULL);
		if (error < 0) {
		printk("[%s]Failed to request GPIO %d, error %d\n",
			__func__,GPIO_CAMERA_CTRL, error);
		//return error;
		}
#endif
	Printlog("[%s]hw_id = %d \n",__func__,board_type_with_hw_id());
	 camera_ctrl= (board_type_with_hw_id() > DVT2_BOARD_HW_ID);
	Printlog("[%s] camera_ctrl :%d \n",__func__,camera_ctrl);
//	camera_ctrl = gpio_get_value(GPIO_CAMERA_CTRL);	
	if(camera_ctrl){//for after DVT3 to cahnge camera gpio define	
		for (i = 4; i <8; i++) {
			const struct gpio_keys_button *button = &pdata->buttons[i];
			struct gpio_button_data *bdata = &ddata->data[i];

			error = gpio_keys_setup_key(pdev, input, bdata, button);
			if (error)
				goto fail2;

			if (button->wakeup)
				wakeup = 1;
		}
	}else{ //for before DVT3.
	for (i = 0; i < pdata->nbuttons-4; i++) {
		const struct gpio_keys_button *button = &pdata->buttons[i];
		struct gpio_button_data *bdata = &ddata->data[i];

		error = gpio_keys_setup_key(pdev, input, bdata, button);
		if (error)
			goto fail2;

		if (button->wakeup)
			wakeup = 1;
	}
			}
	//PrintAA("[%s] GPIO_CAMERA_CTRL  value:%d",__func__,camera_ctrl);
 

	error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group);
	if (error) {
		dev_err(dev, "Unable to export keys/switches, error: %d\n",
			error);
		goto fail2;
	}

	error = input_register_device(input);
	if (error) {
		dev_err(dev, "Unable to register input device, error: %d\n",
			error);
		goto fail3;
	}
	if(camera_ctrl){//for after DVT3 to cahnge camera gpio define
		/* get current state of buttons that are connected to GPIOs */
		for (i = 4; i < 8; i++) {
			struct gpio_button_data *bdata = &ddata->data[i];
			if (gpio_is_valid(bdata->button->gpio))
				gpio_keys_gpio_report_event(bdata);
		}
	}else{//for before DVT3
	/* get current state of buttons that are connected to GPIOs */
	for (i = 0; i < pdata->nbuttons-4; i++) {
		struct gpio_button_data *bdata = &ddata->data[i];
		if (gpio_is_valid(bdata->button->gpio))
			gpio_keys_gpio_report_event(bdata);
		}
	}
	input_sync(input);

	device_init_wakeup(&pdev->dev, wakeup);

	return 0;

 fail3:
	sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
 fail2:
 if(camera_ctrl)
 	while (--i >= 4)  
		gpio_remove_key(&ddata->data[i]);
else{ 	
	while (--i >= 0) //for before DVT3.
		gpio_remove_key(&ddata->data[i]);
}
	platform_set_drvdata(pdev, NULL);
 fail1:
	input_free_device(input);
	kfree(ddata);
	/* If we have no platform_data, we allocated buttons dynamically. */
	if (!pdev->dev.platform_data)
		kfree(pdata->buttons);

	return error;
}