aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/flashlight/src
diff options
context:
space:
mode:
authorMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
committerMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
commitd2e1446d81725c351dc73a03b397ce043fb18452 (patch)
tree4dbc616b7f92aea39cd697a9084205ddb805e344 /drivers/misc/mediatek/flashlight/src
first commit
Diffstat (limited to 'drivers/misc/mediatek/flashlight/src')
-rw-r--r--drivers/misc/mediatek/flashlight/src/Makefile7
-rwxr-xr-xdrivers/misc/mediatek/flashlight/src/mt6735/Makefile34
-rwxr-xr-xdrivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/Makefile7
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/leds_strobe.c1225
-rwxr-xr-xdrivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/Makefile4
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/dummy_flashlight.c312
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/kd_flashlightlist.c980
-rwxr-xr-xdrivers/misc/mediatek/flashlight/src/mt6735/out.txt10
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid1_part2.c103
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part1.c396
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part2.c103
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_part_id.c43
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid1_part2.c102
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part1.c105
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part2.c103
-rw-r--r--drivers/misc/mediatek/flashlight/src/mt6735/sub_strobe.c103
16 files changed, 3637 insertions, 0 deletions
diff --git a/drivers/misc/mediatek/flashlight/src/Makefile b/drivers/misc/mediatek/flashlight/src/Makefile
new file mode 100644
index 000000000..05c2703fb
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/Makefile
@@ -0,0 +1,7 @@
+include $(srctree)/drivers/misc/mediatek/Makefile.custom
+
+
+obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/Makefile b/drivers/misc/mediatek/flashlight/src/mt6735/Makefile
new file mode 100755
index 000000000..ac2bf4d7c
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/Makefile
@@ -0,0 +1,34 @@
+#
+# Makefile for misc devices that really don't fit anywhere else.
+#
+include $(srctree)/drivers/misc/mediatek/Makefile.custom
+
+obj-y += kd_flashlightlist.o
+
+obj-y += strobe_main_sid2_part2.o
+obj-y += strobe_sub_sid2_part1.o
+obj-y += strobe_sub_sid2_part2.o
+obj-y += sub_strobe.o
+obj-y += strobe_main_sid1_part2.o
+obj-y += strobe_part_id.o
+obj-y += strobe_sub_sid1_part2.o
+
+ifeq ($(wildcard $(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/flashlight/strobe_main_sid2_part1.c),)
+obj-y += strobe_main_sid2_part1.o
+endif
+
+ifeq ($(wildcard $(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/flashlight),)
+#ifeq ($(wildcard $(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/flashlight),)
+
+
+
+custom_kernel_flashlight := $(addsuffix /, $(shell echo $(CONFIG_CUSTOM_KERNEL_FLASHLIGHT)))
+
+obj-y += $(custom_kernel_flashlight)
+
+
+
+
+endif
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/Makefile b/drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/Makefile
new file mode 100755
index 000000000..6069cfee0
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for misc devices that really don't fit anywhere else.
+#
+
+include $(srctree)/drivers/misc/mediatek/Makefile.custom
+
+obj-y += leds_strobe.o
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/leds_strobe.c b/drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/leds_strobe.c
new file mode 100644
index 000000000..d5305b4a9
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/constant_flashlight/leds_strobe.c
@@ -0,0 +1,1225 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include "kd_flashlight.h"
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <cust_i2c.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+#include <linux/mutex.h>
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#endif
+
+#include <linux/i2c.h>
+#include <linux/leds.h>
+
+
+
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+
+#define TAG_NAME "[leds_strobe.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) xlog_printk(ANDROID_LOG_DEBUG , TAG_NAME, KERN_INFO "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) xlog_printk(ANDROID_LOG_WARNING, TAG_NAME, KERN_WARNING "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) xlog_printk(ANDROID_LOG_DEBUG , TAG_NAME, KERN_NOTICE "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) xlog_printk(ANDROID_LOG_INFO , TAG_NAME, KERN_INFO "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) xlog_printk(ANDROID_LOG_DEBUG , TAG_NAME, "<%s>\n", __FUNCTION__);
+#define PK_TRC_VERBOSE(fmt, arg...) xlog_printk(ANDROID_LOG_VERBOSE, TAG_NAME, fmt, ##arg)
+#define PK_ERROR(fmt, arg...) xlog_printk(ANDROID_LOG_ERROR , TAG_NAME, KERN_ERR "%s: " fmt, __FUNCTION__ ,##arg)
+
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+#define MEIZU_M81
+
+#ifndef MEIZU_M81
+/******************************************************************************
+ * local variables
+******************************************************************************/
+
+static DEFINE_SPINLOCK(g_strobeSMPLock); /* cotta-- SMP proection */
+
+
+static u32 strobe_Res = 0;
+static u32 strobe_Timeus = 0;
+static BOOL g_strobe_On = 0;
+
+static int g_duty=-1;
+static int g_timeOutTimeMs=0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static DEFINE_MUTEX(g_strobeSem);
+#else
+static DECLARE_MUTEX(g_strobeSem);
+#endif
+
+
+#define STROBE_DEVICE_ID 0xC6
+
+
+static struct work_struct workTimeOut;
+
+//#define FLASH_GPIO_ENF GPIO12
+//#define FLASH_GPIO_ENT GPIO13
+
+static int g_bLtVersion=0;
+
+/*****************************************************************************
+Functions
+*****************************************************************************/
+extern int iWriteRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u16 i2cId);
+extern int iReadRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u8 * a_pRecvData, u16 a_sizeRecvData, u16 i2cId);
+static void work_timeOutFunc(struct work_struct *data);
+
+static struct i2c_client *LM3642_i2c_client = NULL;
+
+
+
+
+struct LM3642_platform_data {
+ u8 torch_pin_enable; // 1: TX1/TORCH pin isa hardware TORCH enable
+ u8 pam_sync_pin_enable; // 1: TX2 Mode The ENVM/TX2 is a PAM Sync. on input
+ u8 thermal_comp_mode_enable;// 1: LEDI/NTC pin in Thermal Comparator Mode
+ u8 strobe_pin_disable; // 1 : STROBE Input disabled
+ u8 vout_mode_enable; // 1 : Voltage Out Mode enable
+};
+
+struct LM3642_chip_data {
+ struct i2c_client *client;
+
+ //struct led_classdev cdev_flash;
+ //struct led_classdev cdev_torch;
+ //struct led_classdev cdev_indicator;
+
+ struct LM3642_platform_data *pdata;
+ struct mutex lock;
+
+ u8 last_flag;
+ u8 no_pdata;
+};
+
+/* i2c access*/
+/*
+static int LM3642_read_reg(struct i2c_client *client, u8 reg,u8 *val)
+{
+ int ret;
+ struct LM3642_chip_data *chip = i2c_get_clientdata(client);
+
+ mutex_lock(&chip->lock);
+ ret = i2c_smbus_read_byte_data(client, reg);
+ mutex_unlock(&chip->lock);
+
+ if (ret < 0) {
+ PK_ERR("failed reading at 0x%02x error %d\n",reg, ret);
+ return ret;
+ }
+ *val = ret&0xff;
+
+ return 0;
+}*/
+
+static int LM3642_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret=0;
+ struct LM3642_chip_data *chip = i2c_get_clientdata(client);
+
+ mutex_lock(&chip->lock);
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ mutex_unlock(&chip->lock);
+
+ if (ret < 0)
+ PK_ERR("failed writting at 0x%02x\n", reg);
+ return ret;
+}
+
+static int LM3642_read_reg(struct i2c_client *client, u8 reg)
+{
+ int val=0;
+ struct LM3642_chip_data *chip = i2c_get_clientdata(client);
+
+ mutex_lock(&chip->lock);
+ val = i2c_smbus_read_byte_data(client, reg);
+ mutex_unlock(&chip->lock);
+
+
+ return val;
+}
+
+
+
+
+static int LM3642_chip_init(struct LM3642_chip_data *chip)
+{
+
+
+ return 0;
+}
+
+static int LM3642_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct LM3642_chip_data *chip;
+ struct LM3642_platform_data *pdata = client->dev.platform_data;
+
+ int err = -1;
+
+ PK_DBG("LM3642_probe start--->.\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ err = -ENODEV;
+ printk(KERN_ERR "LM3642 i2c functionality check fail.\n");
+ return err;
+ }
+
+ chip = kzalloc(sizeof(struct LM3642_chip_data), GFP_KERNEL);
+ chip->client = client;
+
+ mutex_init(&chip->lock);
+ i2c_set_clientdata(client, chip);
+
+ if(pdata == NULL){ //values are set to Zero.
+ PK_ERR("LM3642 Platform data does not exist\n");
+ pdata = kzalloc(sizeof(struct LM3642_platform_data),GFP_KERNEL);
+ chip->pdata = pdata;
+ chip->no_pdata = 1;
+ }
+
+ chip->pdata = pdata;
+ if(LM3642_chip_init(chip)<0)
+ goto err_chip_init;
+
+ LM3642_i2c_client = client;
+ PK_DBG("LM3642 Initializing is done \n");
+
+ return 0;
+
+err_chip_init:
+ i2c_set_clientdata(client, NULL);
+ kfree(chip);
+ PK_ERR("LM3642 probe is failed \n");
+ return -ENODEV;
+}
+
+static int LM3642_remove(struct i2c_client *client)
+{
+ struct LM3642_chip_data *chip = i2c_get_clientdata(client);
+
+ if(chip->no_pdata)
+ kfree(chip->pdata);
+ kfree(chip);
+ return 0;
+}
+
+
+#define LM3642_NAME "leds-LM3642"
+static const struct i2c_device_id LM3642_id[] = {
+ {LM3642_NAME, 0},
+ {}
+};
+
+static struct i2c_driver LM3642_i2c_driver = {
+ .driver = {
+ .name = LM3642_NAME,
+ },
+ .probe = LM3642_probe,
+ .remove = LM3642_remove,
+ .id_table = LM3642_id,
+};
+
+struct LM3642_platform_data LM3642_pdata = {0, 0, 0, 0, 0};
+static struct i2c_board_info __initdata i2c_LM3642={ I2C_BOARD_INFO(LM3642_NAME, I2C_STROBE_MAIN_SLAVE_7_BIT_ADDR), \
+ .platform_data = &LM3642_pdata,};
+
+static int __init LM3642_init(void)
+{
+ printk("LM3642_init\n");
+ //i2c_register_board_info(2, &i2c_LM3642, 1);
+ i2c_register_board_info(I2C_STROBE_MAIN_CHANNEL, &i2c_LM3642, 1);
+
+
+ return i2c_add_driver(&LM3642_i2c_driver);
+}
+
+static void __exit LM3642_exit(void)
+{
+ i2c_del_driver(&LM3642_i2c_driver);
+}
+
+
+module_init(LM3642_init);
+module_exit(LM3642_exit);
+
+MODULE_DESCRIPTION("Flash driver for LM3642");
+MODULE_AUTHOR("pw <pengwei@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+
+int readReg(int reg)
+{
+
+ int val;
+ val = LM3642_read_reg(LM3642_i2c_client, reg);
+ return (int)val;
+}
+
+int FL_Enable(void)
+{
+ char buf[2];
+// char bufR[2];
+ if(g_duty<0)
+ g_duty=0;
+ else if(g_duty>16)
+ g_duty=16;
+ if(g_duty<=2)
+ {
+ int val;
+ if(g_bLtVersion==1)
+ {
+ if(g_duty==0)
+ val=3;
+ else if(g_duty==1)
+ val=5;
+ else //if(g_duty==2)
+ val=7;
+ }
+ else
+ {
+ if(g_duty==0)
+ val=1;
+ else if(g_duty==1)
+ val=2;
+ else //if(g_duty==2)
+ val=3;
+ }
+ buf[0]=9;
+ buf[1]=val<<4;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+
+ buf[0]=10;
+ buf[1]=0x02;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+ }
+ else
+ {
+ int val;
+ val = (g_duty-1);
+ buf[0]=9;
+ buf[1]=val;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+
+ buf[0]=10;
+ buf[1]=0x03;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+ }
+ PK_DBG(" FL_Enable line=%d\n",__LINE__);
+
+ readReg(0);
+ readReg(1);
+ readReg(6);
+ readReg(8);
+ readReg(9);
+ readReg(0xa);
+ readReg(0xb);
+
+ return 0;
+}
+
+
+
+int FL_Disable(void)
+{
+ char buf[2];
+
+///////////////////////
+ buf[0]=10;
+ buf[1]=0x00;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+ PK_DBG(" FL_Disable line=%d\n",__LINE__);
+ return 0;
+}
+
+int FL_dim_duty(kal_uint32 duty)
+{
+ PK_DBG(" FL_dim_duty line=%d\n",__LINE__);
+ g_duty = duty;
+ return 0;
+}
+
+
+
+
+int FL_Init(void)
+{
+ int regVal0;
+ char buf[2];
+
+ buf[0]=0xa;
+ buf[1]=0x0;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+
+ buf[0]=0x8;
+ buf[1]=0x47;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+
+ buf[0]=9;
+ buf[1]=0x35;
+ //iWriteRegI2C(buf , 2, STROBE_DEVICE_ID);
+ LM3642_write_reg(LM3642_i2c_client, buf[0], buf[1]);
+
+
+
+
+ //static int LM3642_read_reg(struct i2c_client *client, u8 reg)
+ //regVal0 = readReg(0);
+ regVal0 = LM3642_read_reg(LM3642_i2c_client, 0);
+
+ if(regVal0==1)
+ g_bLtVersion=1;
+ else
+ g_bLtVersion=0;
+
+
+ PK_DBG(" FL_Init regVal0=%d isLtVer=%d\n",regVal0, g_bLtVersion);
+
+
+/*
+ if(mt_set_gpio_mode(FLASH_GPIO_ENT,GPIO_MODE_00)){PK_DBG("[constant_flashlight] set gpio mode failed!! \n");}
+ if(mt_set_gpio_dir(FLASH_GPIO_ENT,GPIO_DIR_OUT)){PK_DBG("[constant_flashlight] set gpio dir failed!! \n");}
+ if(mt_set_gpio_out(FLASH_GPIO_ENT,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] set gpio failed!! \n");}
+
+ if(mt_set_gpio_mode(FLASH_GPIO_ENF,GPIO_MODE_00)){PK_DBG("[constant_flashlight] set gpio mode failed!! \n");}
+ if(mt_set_gpio_dir(FLASH_GPIO_ENF,GPIO_DIR_OUT)){PK_DBG("[constant_flashlight] set gpio dir failed!! \n");}
+ if(mt_set_gpio_out(FLASH_GPIO_ENF,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] set gpio failed!! \n");}
+ */
+
+
+
+
+ PK_DBG(" FL_Init line=%d\n",__LINE__);
+ return 0;
+}
+
+
+int FL_Uninit(void)
+{
+ FL_Disable();
+ return 0;
+}
+
+/*****************************************************************************
+User interface
+*****************************************************************************/
+
+static void work_timeOutFunc(struct work_struct *data)
+{
+ FL_Disable();
+ PK_DBG("ledTimeOut_callback\n");
+ //printk(KERN_ALERT "work handler function./n");
+}
+
+
+
+enum hrtimer_restart ledTimeOutCallback(struct hrtimer *timer)
+{
+ schedule_work(&workTimeOut);
+ return HRTIMER_NORESTART;
+}
+static struct hrtimer g_timeOutTimer;
+void timerInit(void)
+{
+ INIT_WORK(&workTimeOut, work_timeOutFunc);
+ g_timeOutTimeMs=1000; //1s
+ hrtimer_init( &g_timeOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ g_timeOutTimer.function=ledTimeOutCallback;
+
+}
+
+
+
+static int constant_flashlight_ioctl(unsigned int cmd, unsigned long arg)
+{
+ int i4RetValue = 0;
+ int ior_shift;
+ int iow_shift;
+ int iowr_shift;
+ ior_shift = cmd - (_IOR(FLASHLIGHT_MAGIC,0, int));
+ iow_shift = cmd - (_IOW(FLASHLIGHT_MAGIC,0, int));
+ iowr_shift = cmd - (_IOWR(FLASHLIGHT_MAGIC,0, int));
+ PK_DBG("LM3642 constant_flashlight_ioctl() line=%d ior_shift=%d, iow_shift=%d iowr_shift=%d arg=%d\n",__LINE__, ior_shift, iow_shift, iowr_shift,(int)arg);
+ switch(cmd)
+ {
+
+ case FLASH_IOC_SET_TIME_OUT_TIME_MS:
+ PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",(int)arg);
+ g_timeOutTimeMs=arg;
+ break;
+
+
+ case FLASH_IOC_SET_DUTY :
+ PK_DBG("FLASHLIGHT_DUTY: %d\n",(int)arg);
+ FL_dim_duty(arg);
+ break;
+
+
+ case FLASH_IOC_SET_STEP:
+ PK_DBG("FLASH_IOC_SET_STEP: %d\n",(int)arg);
+
+ break;
+
+ case FLASH_IOC_SET_ONOFF :
+ PK_DBG("FLASHLIGHT_ONOFF: %d\n",(int)arg);
+ if(arg==1)
+ {
+
+ int s;
+ int ms;
+ if(g_timeOutTimeMs>1000)
+ {
+ s = g_timeOutTimeMs/1000;
+ ms = g_timeOutTimeMs - s*1000;
+ }
+ else
+ {
+ s = 0;
+ ms = g_timeOutTimeMs;
+ }
+
+ if(g_timeOutTimeMs!=0)
+ {
+ ktime_t ktime;
+ ktime = ktime_set( s, ms*1000000 );
+ hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL );
+ }
+ FL_Enable();
+ }
+ else
+ {
+ FL_Disable();
+ hrtimer_cancel( &g_timeOutTimer );
+ }
+ break;
+ default :
+ PK_DBG(" No such command \n");
+ i4RetValue = -EPERM;
+ break;
+ }
+ return i4RetValue;
+}
+
+
+
+
+static int constant_flashlight_open(void *pArg)
+{
+ int i4RetValue = 0;
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+
+ if (0 == strobe_Res)
+ {
+ FL_Init();
+ timerInit();
+ }
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+ spin_lock_irq(&g_strobeSMPLock);
+
+
+ if(strobe_Res)
+ {
+ PK_ERR(" busy!\n");
+ i4RetValue = -EBUSY;
+ }
+ else
+ {
+ strobe_Res += 1;
+ }
+
+
+ spin_unlock_irq(&g_strobeSMPLock);
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+
+ return i4RetValue;
+
+}
+
+
+static int constant_flashlight_release(void *pArg)
+{
+ PK_DBG(" constant_flashlight_release\n");
+
+ if (strobe_Res)
+ {
+ spin_lock_irq(&g_strobeSMPLock);
+
+ strobe_Res = 0;
+ strobe_Timeus = 0;
+
+ /* LED On Status */
+ g_strobe_On = FALSE;
+
+ spin_unlock_irq(&g_strobeSMPLock);
+
+ FL_Uninit();
+ }
+
+ PK_DBG(" Done\n");
+
+ return 0;
+
+}
+
+
+FLASHLIGHT_FUNCTION_STRUCT constantFlashlightFunc=
+{
+ constant_flashlight_open,
+ constant_flashlight_release,
+ constant_flashlight_ioctl
+};
+
+
+MUINT32 constantFlashlightInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &constantFlashlightFunc;
+ }
+ return 0;
+}
+
+
+
+/* LED flash control for high current capture mode*/
+ssize_t strobe_VDIrq(void)
+{
+
+ return 0;
+}
+
+EXPORT_SYMBOL(strobe_VDIrq);
+
+#else //meizu m81 flashlight driver ,lcz@meizu.com 2014/9/21/
+
+
+#define REG_ENABLE 0x01
+#define REG_FLASH_LED1_BR 0x03
+#define REG_FLASH_LED2_BR 0x04
+#define REG_TORCH_LED1_BR 0x05
+#define REG_TORCH_LED2_BR 0x06
+#define REG_FLASH_TOUT 0x08
+#define REG_FLAG0 0x0a
+#define REG_FLAG1 0x0b
+
+#define I2C_STROBE_MAIN_SLAVE_7_BIT_ADDR 0x63
+#define I2C_STROBE_MAIN_CHANNEL 3
+
+#define DUTY_NUM 25
+
+/******************************************************************************
+ * local variables
+******************************************************************************/
+
+static DEFINE_SPINLOCK(g_strobeSMPLock); /* cotta-- SMP proection */
+
+
+static u32 strobe_Res = 0;
+static u32 strobe_Timeus = 0;
+static BOOL g_strobe_On = 0;
+
+static int gDuty=0;
+static int g_timeOutTimeMs=0;
+static bool torch_flag = false;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+static DEFINE_MUTEX(g_strobeSem);
+#else
+static DECLARE_MUTEX(g_strobeSem);
+#endif
+
+
+static struct work_struct workTimeOut;
+
+//static int gIsTorch[DUTY_NUM]={1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static int gLedDuty[DUTY_NUM]={0x11,0x22,0x33,0x43,0x54,0x66,0x0f,0x13,0x16,0x19,0x1c,0x20,0x24,0x28,0x2c,0x31,0x36,0x3b,0x41,0x46,0x4b,0x50,0x55,0x5a,0x61};
+static int gFlashDuty[DUTY_NUM]={0x01,0x3,0x05,0x07,0x09,0x0c,0x0f,0x13,0x16,0x19,0x1c,0x20,0x24,0x28,0x2c,0x31,0x36,0x3b,0x41,0x46,0x4b,0x50,0x55,0x5a,0x61};
+//current(mA) 25,50,75,100,125,150,190,230,270,310,350,400,450,500,550,600,650,710,770,830,890,950,1010,1075,1150
+
+
+/*****************************************************************************
+Functions
+*****************************************************************************/
+extern int iWriteRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u16 i2cId);
+extern int iReadRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u8 * a_pRecvData, u16 a_sizeRecvData, u16 i2cId);
+static void work_timeOutFunc(struct work_struct *data);
+
+static struct i2c_client *LM3644_i2c_client = NULL;
+
+
+
+
+struct LM3644_platform_data {
+ u8 torch_pin_enable; // 1: TX1/TORCH pin isa hardware TORCH enable
+ u8 pam_sync_pin_enable; // 1: TX2 Mode The ENVM/TX2 is a PAM Sync. on input
+ u8 thermal_comp_mode_enable;// 1: LEDI/NTC pin in Thermal Comparator Mode
+ u8 strobe_pin_disable; // 1 : STROBE Input disabled
+ u8 vout_mode_enable; // 1 : Voltage Out Mode enable
+};
+
+struct LM3644_chip_data {
+ struct i2c_client *client;
+
+ //struct led_classdev cdev_flash;
+ //struct led_classdev cdev_torch;
+ //struct led_classdev cdev_indicator;
+
+ struct LM3644_platform_data *pdata;
+ struct mutex lock;
+
+ u8 last_flag;
+ u8 no_pdata;
+};
+
+
+static int LM3644_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret=0;
+ struct LM3644_chip_data *chip = i2c_get_clientdata(client);
+
+ mutex_lock(&chip->lock);
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ mutex_unlock(&chip->lock);
+
+ if (ret < 0)
+ PK_ERR("failed writting at 0x%02x\n", reg);
+ return ret;
+}
+
+static int LM3644_read_reg(struct i2c_client *client, u8 reg)
+{
+ int val=0;
+ struct LM3644_chip_data *chip = i2c_get_clientdata(client);
+
+ mutex_lock(&chip->lock);
+ val = i2c_smbus_read_byte_data(client, reg);
+ mutex_unlock(&chip->lock);
+
+
+ return val;
+}
+
+static void Enable_GPIO(void){
+ //Enable hardware EN pin,LM3644 must Enable this to achieve i2c tranfer
+ printk("Enable Flash EN GPIO%d\n",__LINE__);
+ mt_set_gpio_mode(GPIO_CAMERA_FLASH_EN_PIN,GPIO_MODE_00);
+ mt_set_gpio_dir(GPIO_CAMERA_FLASH_EN_PIN,GPIO_DIR_OUT);
+ mt_set_gpio_out(GPIO_CAMERA_FLASH_EN_PIN,1);
+}
+
+static void Disable_GPIO(void){
+ //Disable hardware EN pin
+ printk("Disable Flash EN GPIO%d\n",__LINE__);
+ mt_set_gpio_mode(GPIO_CAMERA_FLASH_EN_PIN,GPIO_MODE_00);
+ mt_set_gpio_dir(GPIO_CAMERA_FLASH_EN_PIN,GPIO_DIR_OUT);
+ mt_set_gpio_out(GPIO_CAMERA_FLASH_EN_PIN,0);
+}
+
+
+
+//=========================
+
+static int LM3644_chip_init(struct LM3644_chip_data *chip)
+{
+ return 0;
+}
+
+static int LM3644_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct LM3644_chip_data *chip;
+ struct LM3644_platform_data *pdata = client->dev.platform_data;
+
+ int err = -1;
+
+ printk("LM3644_probe start--->.\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ err = -ENODEV;
+ printk(KERN_ERR "LM3644 i2c functionality check fail.\n");
+ return err;
+ }
+
+ chip = kzalloc(sizeof(struct LM3644_chip_data), GFP_KERNEL);
+ chip->client = client;
+
+ mutex_init(&chip->lock);
+ i2c_set_clientdata(client, chip);
+
+ if(pdata == NULL){ //values are set to Zero.
+ PK_ERR("LM3644 Platform data does not exist\n");
+ pdata = kzalloc(sizeof(struct LM3644_platform_data),GFP_KERNEL);
+ chip->pdata = pdata;
+ chip->no_pdata = 1;
+ }
+
+ chip->pdata = pdata;
+ if(LM3644_chip_init(chip)<0)
+ goto err_chip_init;
+
+ LM3644_i2c_client = client;
+ Enable_GPIO();
+ printk("LM3644 Initializing is done \n");
+ return 0;
+
+err_chip_init:
+ i2c_set_clientdata(client, NULL);
+ kfree(chip);
+ printk("LM3644 probe is failed \n");
+ return -ENODEV;
+}
+
+static int LM3644_remove(struct i2c_client *client)
+{
+ struct LM3644_chip_data *chip = i2c_get_clientdata(client);
+
+
+ if(chip->no_pdata)
+ kfree(chip->pdata);
+ kfree(chip);
+ return 0;
+}
+
+
+#define LM3644_NAME "leds-LM3644"
+static const struct i2c_device_id LM3644_id[] = {
+ {LM3644_NAME, 0},
+ {}
+};
+
+static struct i2c_driver LM3644_i2c_driver = {
+ .driver = {
+ .name = LM3644_NAME,
+ },
+ .probe = LM3644_probe,
+ .remove = LM3644_remove,
+ .id_table = LM3644_id,
+};
+
+struct LM3644_platform_data LM3644_pdata = {0, 0, 0, 0, 0};
+static struct i2c_board_info __initdata i2c_LM3644={ I2C_BOARD_INFO(LM3644_NAME, I2C_STROBE_MAIN_SLAVE_7_BIT_ADDR), \
+ .platform_data = &LM3644_pdata,};
+
+static int __init LM3644_init(void)
+{
+ printk("LM3644_init\n");
+ i2c_register_board_info(I2C_STROBE_MAIN_CHANNEL, &i2c_LM3644, 1);
+ return i2c_add_driver(&LM3644_i2c_driver);
+}
+
+static void __exit LM3644_exit(void)
+{
+ Disable_GPIO();
+ i2c_del_driver(&LM3644_i2c_driver);
+}
+
+
+module_init(LM3644_init);
+module_exit(LM3644_exit);
+
+MODULE_DESCRIPTION("Flash driver for LM3644");
+MODULE_AUTHOR("pw <pengwei@mediatek.com>");
+MODULE_LICENSE("GPL v2");
+
+int FL_dim_duty_led1(kal_uint32 duty)
+{
+ int buf[2];
+ if(duty>DUTY_NUM-1)
+ duty=DUTY_NUM-1;
+ if(duty<0)
+ duty=0;
+ gDuty=duty;
+ if(torch_flag){
+ buf[0]=REG_TORCH_LED1_BR;
+ buf[1]=gLedDuty[gDuty];
+ printk("[LM3644] set flashlight led1 duty=0x%X,torch mode\n",buf[1]);
+ }
+ else{
+ buf[0]=REG_FLASH_LED1_BR;
+ buf[1]=gFlashDuty[gDuty];
+ printk("[LM3644] set flashlight led1 duty=0x%X,flash mode\n",buf[1]);
+ }
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ PK_DBG("FL_dim_duty line=%d\n",__LINE__);
+ return 0;
+}
+int FL_dim_duty_led2(kal_uint32 duty)
+{
+ int buf[2];
+ if(duty>DUTY_NUM-1)
+ duty=DUTY_NUM-1;
+ if(duty<0)
+ duty=0;
+ gDuty=duty;
+ if(torch_flag){
+ buf[0]=REG_TORCH_LED1_BR; //must set REG_TORCH_LED1_BR bit7 as 0
+ buf[1]=LM3644_read_reg(LM3644_i2c_client,buf[0]);
+ buf[1]=buf[1]&0x7f;
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ buf[0]=REG_TORCH_LED2_BR;
+ buf[1]=gLedDuty[gDuty];
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+ printk("[LM3644] set flashlight led2 duty=0x%X,torch mode\n",buf[1]);
+ }
+ else{
+ buf[0]=REG_FLASH_LED1_BR; //must set REG_FLASH_LED1_BR bit7 as 0
+ buf[1]=LM3644_read_reg(LM3644_i2c_client,buf[0]);
+ buf[1]=buf[1]&0x7f;
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ buf[0]=REG_FLASH_LED2_BR;
+ buf[1]=gFlashDuty[gDuty];
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+ printk("[LM3644] set flashlight led2 duty=0x%X,flash mode\n",buf[1]);
+ }
+
+ PK_DBG("FL_dim_duty line=%d\n",__LINE__);
+ return 0;
+}
+
+int FL_Enable_led1(void)
+{
+
+ int buf[2];
+ buf[0]=REG_ENABLE;
+ buf[1]=LM3644_read_reg(LM3644_i2c_client,buf[0]);
+
+ if(torch_flag){
+ buf[1]=buf[1]|0x09;
+ printk("[LM3644] Enable the flashlight led1,torch mode\n");
+ }
+ else{
+ buf[1]=buf[1]|0x0d;
+ printk("[LM3644] Enable the flashlight led1,flash mode\n");
+ }
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ PK_DBG(" FL_Enable line=%d\n",__LINE__);
+ return 0;
+}
+
+int FL_Enable_led2(void)
+{
+
+ int buf[2];
+ buf[0]=REG_ENABLE;
+ buf[1]=LM3644_read_reg(LM3644_i2c_client,buf[0]);
+
+ if(torch_flag){
+ buf[1]=buf[1]|0xa;
+ printk("[LM3644] Enable the flashlight led2,torch mode\n");
+ }
+ else{
+ buf[1]=buf[1]|0xe;
+ printk("[LM3644] Enable the flashlight led2,flash mode\n");
+ }
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ PK_DBG(" FL_Enable line=%d\n",__LINE__);
+ return 0;
+}
+
+
+int FL_Disable_led1(void)
+{
+ int buf[2];
+ buf[0]=REG_ENABLE;
+ buf[1]=LM3644_read_reg(LM3644_i2c_client,buf[0]);
+
+ buf[1]=buf[1]&0xfe;
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ PK_DBG(" FL_Disable led1 line=%d\n",__LINE__);
+ return 0;
+}
+
+int FL_Disable_led2(void)
+{
+ int buf[2];
+ buf[0]=REG_ENABLE;
+ buf[1]=LM3644_read_reg(LM3644_i2c_client,buf[0]);
+
+ buf[1]=buf[1]&0xfd;
+ LM3644_write_reg(LM3644_i2c_client, buf[0], buf[1]);
+
+ PK_DBG(" FL_Disable led1 line=%d\n",__LINE__);
+ return 0;
+}
+
+
+int FL_Enable(void){
+ FL_Enable_led1();
+ return 0;
+}
+
+int FL_dim_duty(kal_uint32 duty){
+
+ FL_dim_duty_led1(duty);
+ return 0;
+}
+
+int FL_Disable(void){
+
+ FL_Disable_led1();
+ return 0;
+}
+
+int FL_Init(void)
+{
+ LM3644_write_reg(LM3644_i2c_client,REG_FLASH_TOUT, 0x0f);
+
+ printk("[LM3644] init done, FL_Init line=%d\n",__LINE__);
+ return 0;
+}
+
+
+int FL_Uninit(void)
+{
+ FL_Disable();
+
+ return 0;
+}
+
+/*****************************************************************************
+User interface
+*****************************************************************************/
+
+static void work_timeOutFunc(struct work_struct *data)
+{
+ FL_Disable();
+ PK_DBG("ledTimeOut_callback\n");
+ //printk(KERN_ALERT "work handler function./n");
+}
+
+
+
+enum hrtimer_restart ledTimeOutCallback(struct hrtimer *timer)
+{
+ schedule_work(&workTimeOut);
+ return HRTIMER_NORESTART;
+}
+static struct hrtimer g_timeOutTimer;
+void timerInit(void)
+{
+ INIT_WORK(&workTimeOut, work_timeOutFunc);
+ g_timeOutTimeMs=1000; //1s
+ hrtimer_init( &g_timeOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ g_timeOutTimer.function=ledTimeOutCallback;
+
+}
+
+
+
+static int constant_flashlight_ioctl(unsigned int cmd, unsigned long arg)
+{
+ int i4RetValue = 0;
+ int ior_shift;
+ int iow_shift;
+ int iowr_shift;
+ ior_shift = cmd - (_IOR(FLASHLIGHT_MAGIC,0, int));
+ iow_shift = cmd - (_IOW(FLASHLIGHT_MAGIC,0, int));
+ iowr_shift = cmd - (_IOWR(FLASHLIGHT_MAGIC,0, int));
+ PK_DBG("LM3644 constant_flashlight_ioctl() line=%d ior_shift=%d, iow_shift=%d iowr_shift=%d arg=%d\n",__LINE__, ior_shift, iow_shift, iowr_shift, arg);
+ switch(cmd)
+ {
+
+ case FLASH_IOC_SET_TIME_OUT_TIME_MS:
+ PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",(int)arg);
+ if(arg == 20000 || arg == 0){
+ torch_flag = true;
+ }
+ else{
+ torch_flag = false;
+ }
+ g_timeOutTimeMs=arg ;
+ break;
+
+
+ case FLASH_IOC_SET_DUTY :
+ PK_DBG("FLASHLIGHT_DUTY: %d\n",(int)arg);
+ FL_dim_duty(arg);
+ break;
+
+
+ case FLASH_IOC_SET_STEP:
+ PK_DBG("FLASH_IOC_SET_STEP: %d\n",(int)arg);
+
+ break;
+
+ case FLASH_IOC_SET_ONOFF :
+ PK_DBG("FLASHLIGHT_ONOFF: %d\n",(int)arg);
+ if(arg==1)
+ {
+ if(g_timeOutTimeMs!=0)
+ {
+ ktime_t ktime;
+ ktime = ktime_set( 0, g_timeOutTimeMs*1000000 );
+ hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL );
+ }
+ FL_Enable();
+ }
+ else
+ {
+ FL_Disable();
+ hrtimer_cancel( &g_timeOutTimer );
+ }
+ break;
+ default :
+ PK_DBG(" No such command \n");
+ i4RetValue = -EPERM;
+ break;
+ }
+ return i4RetValue;
+}
+
+
+
+static int constant_flashlight_open(void *pArg)
+{
+ int i4RetValue = 0;
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+
+ if (0 == strobe_Res)
+ {
+ FL_Init();
+ timerInit();
+ }
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+ spin_lock_irq(&g_strobeSMPLock);
+
+
+ if(strobe_Res)
+ {
+ PK_ERR(" busy!\n");
+ i4RetValue = -EBUSY;
+ }
+ else
+ {
+ strobe_Res += 1;
+ }
+
+
+ spin_unlock_irq(&g_strobeSMPLock);
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+
+ return i4RetValue;
+
+}
+
+
+static int constant_flashlight_release(void *pArg)
+{
+ PK_DBG(" constant_flashlight_release\n");
+
+ if (strobe_Res)
+ {
+ spin_lock_irq(&g_strobeSMPLock);
+
+ strobe_Res = 0;
+ strobe_Timeus = 0;
+
+ /* LED On Status */
+ g_strobe_On = FALSE;
+
+ spin_unlock_irq(&g_strobeSMPLock);
+
+ FL_Uninit();
+ }
+
+ PK_DBG(" Done\n");
+
+ return 0;
+
+}
+
+
+FLASHLIGHT_FUNCTION_STRUCT constantFlashlightFunc=
+{
+ constant_flashlight_open,
+ constant_flashlight_release,
+ constant_flashlight_ioctl
+};
+
+
+MUINT32 constantFlashlightInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &constantFlashlightFunc;
+ }
+ return 0;
+}
+
+
+
+/* LED flash control for high current capture mode*/
+ssize_t strobe_VDIrq(void)
+{
+
+ return 0;
+}
+
+EXPORT_SYMBOL(strobe_VDIrq);
+
+
+#endif
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/Makefile b/drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/Makefile
new file mode 100755
index 000000000..0b8a088b3
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/Makefile
@@ -0,0 +1,4 @@
+include $(srctree)/drivers/misc/mediatek/Makefile.custom
+
+obj-y += dummy_flashlight.o
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/dummy_flashlight.c b/drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/dummy_flashlight.c
new file mode 100644
index 000000000..60d92badf
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/dummy_flashlight/dummy_flashlight.c
@@ -0,0 +1,312 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include "kd_flashlight.h"
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/xlog.h>
+//#include <mach/mt6516_typedefs.h>
+//#include <mach/mt6516_gpt_sw.h>
+
+/******************************************************************************
+ * Definition
+******************************************************************************/
+/* device name and major number */
+#define STROBE_DEVNAME "leds_strobe"
+
+#define DELAY_MS(ms) {mdelay(ms);}//unit: ms(10^-3)
+#define DELAY_US(us) {mdelay(us);}//unit: us(10^-6)
+#define DELAY_NS(ns) {mdelay(ns);}//unit: ns(10^-9)
+
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+#define TAG_NAME "[dummy_flashlight.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(ANDROID_LOG_DEBUG , TAG_NAME, KERN_INFO "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_debug(ANDROID_LOG_WARNING, TAG_NAME, KERN_WARNING "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_debug(ANDROID_LOG_DEBUG , TAG_NAME, KERN_NOTICE "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_debug(ANDROID_LOG_INFO , TAG_NAME, KERN_INFO "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(ANDROID_LOG_DEBUG , TAG_NAME, "<%s>\n", __FUNCTION__);
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(ANDROID_LOG_VERBOSE, TAG_NAME, fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_debug(ANDROID_LOG_ERROR , TAG_NAME, KERN_ERR "%s: " fmt, __FUNCTION__ ,##arg)
+
+
+//#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+#if 0
+/*******************************************************************************
+* structure & enumeration
+*******************************************************************************/
+struct strobe_data{
+ spinlock_t lock;
+ wait_queue_head_t read_wait;
+ struct semaphore sem;
+};
+
+/******************************************************************************
+ * local variables
+******************************************************************************/
+static struct class *strobe_class = NULL;
+static struct device *strobe_device = NULL;
+static struct strobe_data strobe_private;
+static dev_t strobe_devno;
+static struct cdev strobe_cdev;
+//static BOOL g_strobe_On = FALSE;
+#endif
+/*****************************************************************************
+User interface
+*****************************************************************************/
+static int dummy_flashlight_ioctl(unsigned int cmd, unsigned long arg)
+{
+ int i4RetValue = 0;
+ int iFlashType = (int)FLASHLIGHT_NONE;
+
+ switch(cmd)
+ {
+ case FLASHLIGHTIOC_G_FLASHTYPE:
+ iFlashType = FLASHLIGHT_NONE;
+ if (0 != arg) {
+ if(copy_to_user((void __user *) arg , (void*)&iFlashType , _IOC_SIZE(cmd)))
+ {
+ PK_DBG("[strobe_ioctl] ioctl copy to user failed\n");
+ i4RetValue = -EFAULT;
+ }
+ }
+ else {
+ i4RetValue = -EPERM;
+ }
+ break;
+
+ default :
+ PK_DBG("ERROR Cmd ID \n");
+ //i4RetValue = -EPERM;
+ break;
+ }
+ return i4RetValue;
+}
+
+static int dummy_flashlight_open(void *pArg)
+{
+ return 0;
+}
+
+static int dummy_flashlight_release(void *pArg)
+{
+ return 0;
+}
+
+FLASHLIGHT_FUNCTION_STRUCT dummyFlashlightFunc=
+{
+ dummy_flashlight_open,
+ dummy_flashlight_release,
+ dummy_flashlight_ioctl
+};
+
+MUINT32 dummyFlashlightInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc) {
+ if (pfFunc!=NULL) {
+ *pfFunc=&dummyFlashlightFunc;
+ }
+ return 0;
+}
+
+
+/* LED flash control for high current capture mode*/
+ssize_t strobe_VDIrq(void)
+{
+ return 0;
+}
+
+EXPORT_SYMBOL(strobe_VDIrq);
+
+#if 0
+static int strobe_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int strobe_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/* Kernel interface */
+static struct file_operations strobe_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = strobe_ioctl,
+ .open = strobe_open,
+ .release = strobe_release,
+};
+
+/*****************************************************************************
+Driver interface
+*****************************************************************************/
+#define ALLOC_DEVNO
+static int strobe_probe(struct platform_device *dev)
+{
+ int ret = 0, err = 0;
+
+#ifdef ALLOC_DEVNO
+ ret = alloc_chrdev_region(&strobe_devno, 0, 1, STROBE_DEVNAME);
+ if (ret) {
+ PK_ERR("alloc_chrdev_region fail: %d\n", ret);
+ goto strobe_probe_error;
+ } else {
+ PK_DBG("major: %d, minor: %d\n", MAJOR(strobe_devno), MINOR(strobe_devno));
+ }
+ cdev_init(&strobe_cdev, &strobe_fops);
+ strobe_cdev.owner = THIS_MODULE;
+ err = cdev_add(&strobe_cdev, strobe_devno, 1);
+ if (err) {
+ PK_ERR("cdev_add fail: %d\n", err);
+ goto strobe_probe_error;
+ }
+#else
+ #define STROBE_MAJOR 242
+ ret = register_chrdev(STROBE_MAJOR, STROBE_DEVNAME, &strobe_fops);
+ if (ret != 0) {
+ PK_ERR("Unable to register chardev on major=%d (%d)\n", STROBE_MAJOR, ret);
+ return ret;
+ }
+ strobe_devno = MKDEV(STROBE_MAJOR, 0);
+#endif
+
+
+ strobe_class = class_create(THIS_MODULE, "strobedrv");
+ if (IS_ERR(strobe_class)) {
+ PK_ERR("Unable to create class, err = %d\n", (int)PTR_ERR(strobe_class));
+ goto strobe_probe_error;
+ }
+
+ strobe_device = device_create(strobe_class, NULL, strobe_devno, NULL, STROBE_DEVNAME);
+ if(NULL == strobe_device){
+ PK_ERR("device_create fail\n");
+ goto strobe_probe_error;
+ }
+
+ /*initialize members*/
+ spin_lock_init(&strobe_private.lock);
+ init_waitqueue_head(&strobe_private.read_wait);
+ init_MUTEX(&strobe_private.sem);
+
+ //LED On Status
+// g_strobe_On = FALSE;
+
+ return 0;
+
+strobe_probe_error:
+#ifdef ALLOC_DEVNO
+ if (err == 0)
+ cdev_del(&strobe_cdev);
+ if (ret == 0)
+ unregister_chrdev_region(strobe_devno, 1);
+#else
+ if (ret == 0)
+ unregister_chrdev(MAJOR(strobe_devno), STROBE_DEVNAME);
+#endif
+ return -1;
+}
+
+static int strobe_remove(struct platform_device *dev)
+{
+#ifdef ALLOC_DEVNO
+ cdev_del(&strobe_cdev);
+ unregister_chrdev_region(strobe_devno, 1);
+#else
+ unregister_chrdev(MAJOR(strobe_devno), STROBE_DEVNAME);
+#endif
+ device_destroy(strobe_class, strobe_devno);
+ class_destroy(strobe_class);
+
+ //LED On Status
+ // g_strobe_On = FALSE;
+ return 0;
+}
+
+
+static struct platform_driver strobe_platform_driver =
+{
+ .probe = strobe_probe,
+ .remove = strobe_remove,
+ .driver = {
+ .name = STROBE_DEVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_device strobe_platform_device = {
+ .name = STROBE_DEVNAME,
+ .id = 0,
+ .dev = {
+ }
+};
+
+static int __init strobe_init(void)
+{
+ int ret = 0;
+
+ ret = platform_device_register (&strobe_platform_device);
+ if (ret) {
+ PK_ERR("platform_device_register fail\n");
+ return ret;
+ }
+
+ ret = platform_driver_register(&strobe_platform_driver);
+ if(ret){
+ PK_ERR("platform_driver_register fail\n");
+ return ret;
+ }
+ return ret;
+}
+
+static void __exit strobe_exit(void)
+{
+ platform_driver_unregister(&strobe_platform_driver);
+}
+
+/*****************************************************************************/
+module_init(strobe_init);
+module_exit(strobe_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jackie Su <jackie.su@mediatek.com>");
+MODULE_DESCRIPTION("LED strobe control Driver");
+
+/* LED flash control for capture mode*/
+ssize_t strobe_StillExpCfgStart(void)
+{
+ return 0;
+}
+
+ssize_t strobe_StillExpEndIrqCbf(void)
+{
+ return 0;
+}
+
+EXPORT_SYMBOL(strobe_StillExpCfgStart);
+EXPORT_SYMBOL(strobe_StillExpEndIrqCbf);
+#endif
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/kd_flashlightlist.c b/drivers/misc/mediatek/flashlight/src/mt6735/kd_flashlightlist.c
new file mode 100644
index 000000000..595511314
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/kd_flashlightlist.c
@@ -0,0 +1,980 @@
+#ifdef WIN32
+#include "win_test.h"
+#include "stdio.h"
+#include "kd_flashlight.h"
+#else
+#ifdef CONFIG_COMPAT
+
+#include <linux/fs.h>
+#include <linux/compat.h>
+
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <mach/upmu_sw.h>
+#endif
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+
+
+#define MEIZU_M81
+
+int strobe_getPartId(int sensorDev, int strobeId);
+
+MUINT32 strobeInit_dummy(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 constantFlashlightInit(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+//MUINT32 strobeInit_main(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 strobeInit_main_sid1_part2(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 strobeInit_main_sid2_part1(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 strobeInit_main_sid2_part2(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 subStrobeInit(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 strobeInit_sub_sid1_part2(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 strobeInit_sub_sid2_part1(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+MUINT32 strobeInit_sub_sid2_part2(FLASHLIGHT_FUNCTION_STRUCT **pfFunc);
+/******************************************************************************
+ * Definition
+******************************************************************************/
+
+/* device name and major number */
+#define FLASHLIGHT_DEVNAME "kd_camera_flashlight"
+
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+#ifdef WIN32
+#define logI(fmt, ...) {printf(fmt, __VA_ARGS__); printf("\n");}
+#define logE(fmt, ...) {printf("merror: %d ", __LINE__); printf(fmt, __VA_ARGS__); printf("\n");}
+#else
+ #define PFX "[KD_CAMERA_FLASHLIGHT]"
+ #define PK_DBG_NONE(fmt, arg...) do {} while (0)
+ #define PK_DBG_FUNC(fmt, arg...) printk(KERN_INFO PFX "%s: " fmt, __FUNCTION__ ,##arg)
+
+ #define PK_WARN(fmt, arg...) printk(KERN_WARNING PFX "%s: " fmt, __FUNCTION__ ,##arg)
+ #define PK_NOTICE(fmt, arg...) printk(KERN_NOTICE PFX "%s: " fmt, __FUNCTION__ ,##arg)
+ #define PK_INFO(fmt, arg...) printk(KERN_INFO PFX "%s: " fmt, __FUNCTION__ ,##arg)
+ #define PK_TRC_FUNC(f) printk(PFX "<%s>\n", __FUNCTION__);
+ #define PK_TRC_VERBOSE(fmt, arg...) printk(PFX fmt, ##arg)
+
+ #define DEBUG_KD_STROBE
+ #ifdef DEBUG_KD_STROBE
+ #define logI PK_DBG_FUNC
+ #define logE(fmt, arg...) printk(KERN_ERR PFX "%s: " fmt, __FUNCTION__ ,##arg)
+ #else
+ #define logI(a,...)
+ #define logE(a,...)
+ #endif
+#endif
+//==============================
+// variables
+//==============================
+static FLASHLIGHT_FUNCTION_STRUCT *g_pFlashInitFunc[e_Max_Sensor_Dev_Num][e_Max_Strobe_Num_Per_Dev][e_Max_Part_Num_Per_Dev];
+static int gLowBatDuty[e_Max_Sensor_Dev_Num][e_Max_Strobe_Num_Per_Dev];
+static int g_strobePartId[e_Max_Sensor_Dev_Num][e_Max_Strobe_Num_Per_Dev];
+
+//==============================
+// functions
+//==============================
+int globalInit(void)
+{
+ int i;
+ int j;
+ int k;
+ logI("globalInit");
+ for(i=0;i<e_Max_Sensor_Dev_Num;i++)
+ for(j=0;j<e_Max_Strobe_Num_Per_Dev;j++)
+ {
+ gLowBatDuty[i][j]=-1;
+ g_strobePartId[i][j]=1;
+ for(k=0;k<e_Max_Part_Num_Per_Dev;k++)
+ {
+ g_pFlashInitFunc[i][j][k]=0;
+ }
+
+ }
+ return 0;
+}
+
+int checkAndRelease(void)
+{
+ int i;
+ int j;
+ int k;
+ for(i=0;i<e_Max_Sensor_Dev_Num;i++)
+ for(j=0;j<e_Max_Strobe_Num_Per_Dev;j++)
+ for(k=0;k<e_Max_Part_Num_Per_Dev;k++)
+ {
+ if(g_pFlashInitFunc[i][j][k]!=0)
+ {
+ logI("checkAndRelease %d %d %d", i, j, k);
+ g_pFlashInitFunc[i][j][k]->flashlight_release(0);
+ g_pFlashInitFunc[i][j][k]=0;
+ }
+ }
+ return 0;
+}
+int getSensorDevIndex(int sensorDev)
+{
+ if(sensorDev==e_CAMERA_MAIN_SENSOR)
+ return 0;
+ else if(sensorDev==e_CAMERA_SUB_SENSOR)
+ return 1;
+ else if(sensorDev==e_CAMERA_MAIN_2_SENSOR)
+ return 2;
+ else
+ {
+ logE("sensorDev=%d is wrong",sensorDev);
+ return -1;
+ }
+}
+int getStrobeIndex(int strobeId)
+{
+ if(strobeId<1 || strobeId>2)
+ {
+ logE("strobeId=%d is wrong",strobeId);
+ return -1;
+ }
+ return strobeId-1;
+}
+int getPartIndex(int partId)
+{
+ if(partId<1 || partId>2)
+ {
+ logE("partId=%d is wrong",partId);
+ return -1;
+ }
+ return partId-1;
+}
+
+MINT32 default_flashlight_open(void *pArg) {
+ logI("[default_flashlight_open] E ~");
+ return 0;
+}
+MINT32 default_flashlight_release(void *pArg) {
+ logI("[default_flashlight_release] E ~");
+ return 0;
+}
+MINT32 default_flashlight_ioctl(unsigned int cmd, unsigned long arg) {
+ int i4RetValue = 0;
+ int iFlashType = (int)FLASHLIGHT_NONE;
+ kdStrobeDrvArg kdArg;
+ unsigned long copyRet;
+ copyRet = copy_from_user(&kdArg , (void *)arg , sizeof(kdStrobeDrvArg));
+
+
+ switch(cmd)
+ {
+ case FLASHLIGHTIOC_G_FLASHTYPE:
+ iFlashType = FLASHLIGHT_NONE;
+ kdArg.arg = iFlashType;
+ if(copy_to_user((void __user *) arg , (void*)&kdArg , sizeof(kdStrobeDrvArg)))
+ {
+ logE("[FLASHLIGHTIOC_G_FLASHTYPE] ioctl copy to user failed ~");
+ return -EFAULT;
+ }
+ break;
+ default :
+ logI("[default_flashlight_ioctl] ~");
+ break;
+ }
+ return i4RetValue;
+}
+
+FLASHLIGHT_FUNCTION_STRUCT defaultFlashlightFunc=
+{
+ default_flashlight_open,
+ default_flashlight_release,
+ default_flashlight_ioctl,
+};
+
+UINT32 strobeInit_dummy(FLASHLIGHT_FUNCTION_STRUCT **pfFunc) {
+ if (pfFunc!=NULL) {
+ *pfFunc=&defaultFlashlightFunc;
+ }
+ return 0;
+}
+//========================================================================
+static int setFlashDrv(int sensorDev, int strobeId)
+{
+ int partId;
+ int sensorDevIndex;
+ int strobeIndex;
+ int partIndex;
+ FLASHLIGHT_FUNCTION_STRUCT** ppF=0;
+ sensorDevIndex = getSensorDevIndex(sensorDev);
+ strobeIndex = getStrobeIndex(strobeId);
+ if(sensorDevIndex<0 || strobeIndex<0 )
+ return -1;
+ partId = g_strobePartId[sensorDevIndex][strobeIndex];
+ partIndex = getPartIndex(partId);
+ if(partIndex<0)
+ return -1;
+
+ logI("setFlashDrv sensorDev=%d, strobeId=%d, partId=%d ~",sensorDev, strobeId, partId);
+
+ ppF = &g_pFlashInitFunc[sensorDevIndex][strobeIndex][partIndex];
+ if(sensorDev==e_CAMERA_MAIN_SENSOR)
+ {
+ #if defined(DUMMY_FLASHLIGHT)
+ strobeInit_dummy(ppF);
+ #else
+ if(strobeId==1)
+ {
+ if(partId==1)
+ constantFlashlightInit(ppF);
+ else if(partId==2)
+ strobeInit_main_sid1_part2(ppF);
+ }
+ else if(strobeId==2)
+ {
+ if(partId==1)
+ strobeInit_main_sid2_part1(ppF);
+
+ else if(partId==2)
+ strobeInit_main_sid2_part2(ppF);
+ }
+ #endif
+ }
+ else if(sensorDev==e_CAMERA_SUB_SENSOR)
+ {
+ if(strobeId==1)
+ {
+ if(partId==1)
+ subStrobeInit(ppF);
+ else if(partId==2)
+ strobeInit_sub_sid1_part2(ppF);
+ }
+ else if(strobeId==2)
+ {
+ if(partId==1)
+ strobeInit_sub_sid2_part1(ppF);
+ else if(partId==2)
+ strobeInit_sub_sid2_part2(ppF);
+ }
+ }
+
+
+ if((*ppF)!=0)
+ {
+ (*ppF)->flashlight_open(0);
+ logI("setFlashDrv ok %d",__LINE__);
+ }
+ else
+ {
+ logE("set function pointer not found!!");
+ return -1;
+ }
+ return 0;
+}
+
+
+static int decFlash(void)
+{
+ int i;
+ int j;
+ int k;
+ int duty;
+ for(i=0;i<e_Max_Sensor_Dev_Num;i++)
+ for(j=0;j<e_Max_Strobe_Num_Per_Dev;j++)
+ for(k=0;k<e_Max_Part_Num_Per_Dev;k++)
+ {
+ if(g_pFlashInitFunc[i][j][k]!=0)
+ {
+ if(gLowBatDuty[i][j]!=-1)
+ {
+ duty = gLowBatDuty[i][j];
+ logI("decFlash i,j,k,duty %d %d %d %d", i, j, k, duty);
+ g_pFlashInitFunc[i][j][k]->flashlight_ioctl(FLASH_IOC_SET_DUTY, duty);
+ }
+ }
+ }
+ return 0;
+}
+
+static int closeFlash(void)
+{
+ int i;
+ int j;
+ int k;
+ logI("closeFlash ln=%d",__LINE__);
+ for(i=0;i<e_Max_Sensor_Dev_Num;i++)
+ {
+ //logI("closeFlash ln=%d %d",__LINE__,i);
+ for(j=0;j<e_Max_Strobe_Num_Per_Dev;j++)
+ {
+ //logI("closeFlash ln=%d %d",__LINE__,j);
+ for(k=0;k<e_Max_Part_Num_Per_Dev;k++)
+ {
+ //logI("closeFlash ln=%d %d %d",__LINE__,k, (int)g_pFlashInitFunc[i][j][k]);
+ if(g_pFlashInitFunc[i][j][k]!=0)
+ {
+ logI("closeFlash i,j,k %d %d %d", i, j, k);
+ g_pFlashInitFunc[i][j][k]->flashlight_ioctl(FLASH_IOC_SET_ONOFF, 0);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+//@@{
+
+/*
+#define LOW_BATTERY_LEVEL_0 0
+#define LOW_BATTERY_LEVEL_1 1
+#define LOW_BATTERY_LEVEL_2 2
+#define BATTERY_PERCENT_LEVEL_0 0
+#define BATTERY_PERCENT_LEVEL_1 1
+*/
+
+///}@@
+static int gLowPowerVbat=LOW_BATTERY_LEVEL_0;
+
+static void Lbat_protection_powerlimit_flash(LOW_BATTERY_LEVEL level)
+{
+ logI("Lbat_protection_powerlimit_flash %d (%d %d %d %d)\n", level, LOW_BATTERY_LEVEL_0, LOW_BATTERY_LEVEL_1, LOW_BATTERY_LEVEL_2,__LINE__);
+ logI("Lbat_protection_powerlimit_flash %d (%d %d %d %d)\n", level, LOW_BATTERY_LEVEL_0, LOW_BATTERY_LEVEL_1, LOW_BATTERY_LEVEL_2,__LINE__);
+ if (level == LOW_BATTERY_LEVEL_0)
+ {
+ gLowPowerVbat=LOW_BATTERY_LEVEL_0;
+ }
+ else if (level == LOW_BATTERY_LEVEL_1)
+ {
+ closeFlash();
+ gLowPowerVbat=LOW_BATTERY_LEVEL_1;
+
+ }
+ else if(level == LOW_BATTERY_LEVEL_2)
+ {
+ closeFlash();
+ gLowPowerVbat=LOW_BATTERY_LEVEL_2;
+ }
+ else
+ {
+ //unlimit cpu and gpu
+ }
+}
+
+
+
+static int gLowPowerPer=BATTERY_PERCENT_LEVEL_0;
+
+static void bat_per_protection_powerlimit_flashlight(BATTERY_PERCENT_LEVEL level)
+{
+ logI("bat_per_protection_powerlimit_flashlight %d (%d %d %d)\n", level, BATTERY_PERCENT_LEVEL_0, BATTERY_PERCENT_LEVEL_1,__LINE__);
+ logI("bat_per_protection_powerlimit_flashlight %d (%d %d %d)\n", level, BATTERY_PERCENT_LEVEL_0, BATTERY_PERCENT_LEVEL_1,__LINE__);
+ if (level == BATTERY_PERCENT_LEVEL_0)
+ {
+ gLowPowerPer=BATTERY_PERCENT_LEVEL_0;
+ }
+ else if(level == BATTERY_PERCENT_LEVEL_1)
+ {
+ closeFlash();
+ gLowPowerPer=BATTERY_PERCENT_LEVEL_1;
+ }
+ else
+ {
+ //unlimit cpu and gpu
+ }
+}
+
+
+/*
+static int gLowPowerOc=BATTERY_OC_LEVEL_0;
+
+void bat_oc_protection_powerlimit(BATTERY_OC_LEVEL level)
+{
+ logI("bat_oc_protection_powerlimit %d (%d %d %d)\n", level, BATTERY_OC_LEVEL_0, BATTERY_OC_LEVEL_1,__LINE__);
+ logI("bat_oc_protection_powerlimit %d (%d %d %d)\n", level, BATTERY_OC_LEVEL_0, BATTERY_OC_LEVEL_1,__LINE__);
+ if (level == BATTERY_OC_LEVEL_1){
+ // battery OC trigger CPU Limit to under 4 X 0.8G
+ closeFlash();
+ gLowPowerOc=BATTERY_OC_LEVEL_1;
+ }
+ else{
+ //unlimit cpu and gpu
+ gLowPowerOc=BATTERY_OC_LEVEL_0;
+ }
+}
+*/
+
+
+
+//========================================================================
+extern void kicker_pbm_by_flash(bool status);
+
+static long flashlight_ioctl_core(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int partId;
+ int sensorDevIndex;
+ int strobeIndex;
+ int partIndex;
+ int i4RetValue = 0;
+ kdStrobeDrvArg kdArg;
+ unsigned long copyRet;
+ copyRet = copy_from_user(&kdArg , (void *)arg , sizeof(kdStrobeDrvArg));
+ logI("flashlight_ioctl cmd=0x%x(nr=%d), senorDev=0x%x ledId=0x%x arg=0x%lx",cmd, _IOC_NR(cmd), kdArg.sensorDev, kdArg.strobeId ,(unsigned long)kdArg.arg);
+ sensorDevIndex = getSensorDevIndex(kdArg.sensorDev);
+ strobeIndex = getStrobeIndex(kdArg.strobeId);
+ if(sensorDevIndex<0 || strobeIndex<0 )
+ return -1;
+ partId = g_strobePartId[sensorDevIndex][strobeIndex];
+ partIndex = getPartIndex(partId);
+ if(partIndex<0)
+ return -1;
+
+
+
+ switch(cmd)
+ {
+ case FLASH_IOC_GET_PROTOCOL_VERSION:
+ i4RetValue=1;
+ break;
+ case FLASH_IOC_IS_LOW_POWER:
+ logI("FLASH_IOC_IS_LOW_POWER");
+ {
+ int isLow=0;
+ if(gLowPowerPer!=BATTERY_PERCENT_LEVEL_0 || gLowPowerVbat!=LOW_BATTERY_LEVEL_0 )
+ isLow=1;
+ logI("FLASH_IOC_IS_LOW_POWER %d %d %d",gLowPowerPer,gLowPowerVbat,isLow);
+ kdArg.arg = isLow;
+ if(copy_to_user((void __user *) arg , (void*)&kdArg , sizeof(kdStrobeDrvArg)))
+ {
+ logE("[FLASH_IOC_IS_LOW_POWER] ioctl copy to user failed ~");
+ return -EFAULT;
+ }
+ }
+ break;
+
+ case FLASH_IOC_LOW_POWER_DETECT_START:
+ logI("FLASH_IOC_LOW_POWER_DETECT_START");
+ gLowBatDuty[sensorDevIndex][strobeIndex]=kdArg.arg;
+ break;
+
+ case FLASH_IOC_LOW_POWER_DETECT_END:
+ logI("FLASH_IOC_LOW_POWER_DETECT_END");
+ gLowBatDuty[sensorDevIndex][strobeIndex]=-1;
+ break;
+ case FLASHLIGHTIOC_X_SET_DRIVER:
+ i4RetValue = setFlashDrv(kdArg.sensorDev, kdArg.strobeId);
+ break;
+ case FLASH_IOC_GET_PART_ID:
+ case FLASH_IOC_GET_MAIN_PART_ID:
+ case FLASH_IOC_GET_SUB_PART_ID:
+ case FLASH_IOC_GET_MAIN2_PART_ID:
+ {
+ int partId;
+ partId = strobe_getPartId(kdArg.sensorDev, kdArg.strobeId);
+ g_strobePartId[sensorDevIndex][strobeIndex]=partId;
+ kdArg.arg = partId;
+ if(copy_to_user((void __user *) arg , (void*)&kdArg , sizeof(kdStrobeDrvArg)))
+ {
+ logE("[FLASH_IOC_GET_PART_ID] ioctl copy to user failed ~");
+ return -EFAULT;
+ }
+ logI("FLASH_IOC_GET_PART_ID line=%d partId=%d",__LINE__,partId);
+ }
+ break;
+ case FLASH_IOC_SET_ONOFF:
+ {
+ FLASHLIGHT_FUNCTION_STRUCT *pF;
+ pF = g_pFlashInitFunc[sensorDevIndex][strobeIndex][partIndex];
+ if(pF!=0)
+ {
+ kicker_pbm_by_flash(kdArg.arg);
+ i4RetValue = pF->flashlight_ioctl(cmd,kdArg.arg);
+
+ }
+ else
+ {
+ logE("[FLASH_IOC_SET_ONOFF] function pointer is wrong -");
+ }
+ }
+ break;
+ case FLASH_IOC_UNINIT:
+ {
+ FLASHLIGHT_FUNCTION_STRUCT *pF;
+ pF = g_pFlashInitFunc[sensorDevIndex][strobeIndex][partIndex];
+ if(pF!=0)
+ {
+ i4RetValue = pF->flashlight_release((void*)0);
+ pF=0;
+
+ }
+ else
+ {
+ logE("[FLASH_IOC_UNINIT] function pointer is wrong ~");
+ }
+ }
+ default :
+ {
+ FLASHLIGHT_FUNCTION_STRUCT *pF;
+ pF = g_pFlashInitFunc[sensorDevIndex][strobeIndex][partIndex];
+ if(pF!=0)
+ {
+ i4RetValue = pF->flashlight_ioctl(cmd,kdArg.arg);
+ }
+ else
+ {
+ logE("[default] function pointer is wrong ~");
+ }
+ }
+ break;
+ }
+ return i4RetValue;
+}
+
+
+static long flashlight_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err;
+// int dir;
+ err = flashlight_ioctl_core(file, cmd, arg);
+ //dir = _IOC_DIR(cmd);
+ //if(dir &_IOC_READ)
+ {
+ // copy_to_user
+ }
+ return err;
+}
+
+#ifdef CONFIG_COMPAT
+
+/*
+static int compat_arg_struct_user32_to_kernel(
+ struct StrobeDrvArg __user *data32,
+ struct compat_StrobeDrvArg __user *data)
+{
+ compat_int_t i;
+ int err=0;
+
+ err |= get_user(i, &data32->sensorDev);
+ err |= put_user(i, &data->sensorDev);
+
+ err |= get_user(i, &data32->arg);
+ err |= put_user(i, &data->arg);
+
+ return err;
+}
+
+static int compat_arg_struct_kernel_to_user32(
+ struct StrobeDrvArg __user *data32,
+ struct compat_StrobeDrvArg __user *data)
+
+{
+ compat_int_t i;
+ int err=0;
+
+ err |= get_user(i, &data->sensorDev);
+ err |= put_user(i, &data32->sensorDev);
+ err |= get_user(i, &data->arg);
+ err |= put_user(i, &data32->arg);
+
+ return err;
+}*/
+
+
+
+static long my_ioctl_compat(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ logI("flash my_ioctl_compat2 line=%d cmd=%d arg=%ld \n",__LINE__,cmd,arg);
+ int err;
+ //int copyRet;
+ kdStrobeDrvArg* pUObj;
+ pUObj = compat_ptr(arg);
+
+ /*
+ kdStrobeDrvArg* pUObj;
+ pUObj = compat_ptr(arg);
+ kdStrobeDrvArg obj;
+ copyRet = copy_from_user(&obj , (void *)pUObj , sizeof(kdStrobeDrvArg));
+ logI("strobe arg %d %d %d\n", obj.sensorDev, obj.strobeId, obj.arg);
+ obj.arg = 23411;
+ copy_to_user((void __user *) arg , (void*)&obj , sizeof(kdStrobeDrvArg));
+ */
+
+
+
+
+ //data = compat_alloc_user_space(sizeof(*data));
+ //if (sys_data == NULL)
+ // return -EFAULT;
+ //err = compat_arg_struct_user32_to_kernel(data32, data);
+ //arg2 = (unsigned long)data32;
+ err = flashlight_ioctl_core(filep, cmd, pUObj);
+
+ return err;
+
+}
+#endif
+
+
+static int flashlight_open(struct inode *inode, struct file *file)
+{
+ int i4RetValue = 0;
+ static int bInited=0;
+ if(bInited==0)
+ {
+ globalInit();
+ bInited=1;
+ }
+ logI("[flashlight_open] E ~");
+ return i4RetValue;
+}
+
+static int flashlight_release(struct inode *inode, struct file *file)
+{
+ logI("[flashlight_release] E ~");
+
+ checkAndRelease();
+
+ return 0;
+}
+
+#ifdef MEIZU_M81
+static ssize_t flash1_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ //sprintf(buf, "%d\n", duty);
+ return 1;
+}
+
+static ssize_t flash1_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ FLASHLIGHT_FUNCTION_STRUCT* pF = NULL;
+ static int strobe1_init = 0;
+ int duty;
+ int ret = 0;
+
+ sscanf(buf, "%d\n", &duty);
+
+ constantFlashlightInit(&pF);
+
+ /* the max torch mode duty is 5 */
+
+ if (duty > 5)
+ duty = 5;
+
+ /* when duty < 0, flash will be closed. */
+ if (duty >= 0) {
+ if (strobe1_init == 0) {
+ ret = pF->flashlight_open(0);
+ if (ret) {
+ logE("[flash1_store] flash1 busy!");
+ return ret;
+ }
+
+ strobe1_init++;
+ }
+
+ ret = pF->flashlight_ioctl(FLASH_IOC_SET_TIME_OUT_TIME_MS, 0);
+ ret += pF->flashlight_ioctl(FLASH_IOC_SET_DUTY, duty);
+// ret += pF->flashlight_ioctl(FLASH_IOC_PRE_ON, 1);
+ ret += pF->flashlight_ioctl(FLASH_IOC_SET_ONOFF, 1);
+ if (ret) {
+ logE("[flash1_store] flash1 ioctl failed!");
+ return ret;
+ }
+ } else {
+ pF->flashlight_ioctl(FLASH_IOC_SET_ONOFF, 0);
+ pF->flashlight_release(0);
+ strobe1_init = 0;
+ }
+
+ return count;
+}
+
+static ssize_t flash2_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ //sprintf(buf, "%d\n", duty);
+ return 1;
+}
+
+static ssize_t flash2_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ FLASHLIGHT_FUNCTION_STRUCT* pF = NULL;
+ static int strobe2_init = 0;
+ int duty;
+ int ret = 0;
+
+ sscanf(buf, "%d\n", &duty);
+
+ strobeInit_main_sid2_part1(&pF);
+
+ /* the max torch mode duty is 5 */
+ if (duty > 5)
+ duty = 5;
+
+ /* when duty < 0, flash will be closed. */
+ if (duty >= 0) {
+ if (strobe2_init == 0) {
+ ret = pF->flashlight_open(0);
+ if (ret) {
+ logE("[flash2_store] flash2 busy!");
+ return ret;
+ }
+
+ strobe2_init++;
+ }
+
+ ret = pF->flashlight_ioctl(FLASH_IOC_SET_TIME_OUT_TIME_MS, 0);
+ ret += pF->flashlight_ioctl(FLASH_IOC_SET_DUTY, duty);
+// ret += pF->flashlight_ioctl(FLASH_IOC_PRE_ON, 1);
+ ret += pF->flashlight_ioctl(FLASH_IOC_SET_ONOFF, 1);
+ if (ret) {
+ logE("[flash2_store] flash2 ioctl failed!");
+ return ret;
+ }
+ } else {
+ pF->flashlight_ioctl(FLASH_IOC_SET_ONOFF, 0);
+ pF->flashlight_release(0);
+ strobe2_init = 0;
+ }
+
+ return count;
+}
+#endif
+
+#ifdef WIN32
+int fl_open(struct inode *inode, struct file *file)
+{
+ return flashlight_open(inode, file);
+}
+int fl_release(struct inode *inode, struct file *file)
+{
+ return flashlight_release(inode, file);
+}
+long fl_ioctrl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return flashlight_ioctl(file, cmd, arg);
+}
+
+#else
+//========================================================================
+//========================================================================
+//========================================================================
+/* Kernel interface */
+static struct file_operations flashlight_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = flashlight_ioctl,
+ .open = flashlight_open,
+ .release = flashlight_release,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = my_ioctl_compat,
+#endif
+};
+
+#ifdef MEIZU_M81
+static struct device_attribute dev_attr_flash1 = {
+ .attr = {.name = "flash1", .mode = 0644},
+ .show = flash1_show,
+ .store = flash1_store,
+};
+
+static struct device_attribute dev_attr_flash2 = {
+ .attr = {.name = "flash2", .mode = 0644},
+ .show = flash2_show,
+ .store = flash2_store,
+};
+#endif
+
+//========================================================================
+// Driver interface
+//========================================================================
+struct flashlight_data{
+ spinlock_t lock;
+ wait_queue_head_t read_wait;
+ struct semaphore sem;
+};
+static struct class *flashlight_class = NULL;
+static struct device *flashlight_device = NULL;
+static struct flashlight_data flashlight_private;
+static dev_t flashlight_devno;
+static struct cdev flashlight_cdev;
+//========================================================================
+#define ALLOC_DEVNO
+static int flashlight_probe(struct platform_device *dev)
+{
+ int ret = 0, err = 0;
+
+ logI("[flashlight_probe] start ~");
+
+#ifdef ALLOC_DEVNO
+ ret = alloc_chrdev_region(&flashlight_devno, 0, 1, FLASHLIGHT_DEVNAME);
+ if (ret) {
+ logE("[flashlight_probe] alloc_chrdev_region fail: %d ~", ret);
+ goto flashlight_probe_error;
+ } else {
+ logI("[flashlight_probe] major: %d, minor: %d ~", MAJOR(flashlight_devno), MINOR(flashlight_devno));
+ }
+ cdev_init(&flashlight_cdev, &flashlight_fops);
+ flashlight_cdev.owner = THIS_MODULE;
+ err = cdev_add(&flashlight_cdev, flashlight_devno, 1);
+ if (err) {
+ logE("[flashlight_probe] cdev_add fail: %d ~", err);
+ goto flashlight_probe_error;
+ }
+#else
+ #define FLASHLIGHT_MAJOR 242
+ ret = register_chrdev(FLASHLIGHT_MAJOR, FLASHLIGHT_DEVNAME, &flashlight_fops);
+ if (ret != 0) {
+ logE("[flashlight_probe] Unable to register chardev on major=%d (%d) ~", FLASHLIGHT_MAJOR, ret);
+ return ret;
+ }
+ flashlight_devno = MKDEV(FLASHLIGHT_MAJOR, 0);
+#endif
+
+
+ flashlight_class = class_create(THIS_MODULE, "flashlightdrv");
+ if (IS_ERR(flashlight_class)) {
+ logE("[flashlight_probe] Unable to create class, err = %d ~", (int)PTR_ERR(flashlight_class));
+ goto flashlight_probe_error;
+ }
+
+ flashlight_device = device_create(flashlight_class, NULL, flashlight_devno, NULL, FLASHLIGHT_DEVNAME);
+ if(NULL == flashlight_device){
+ logE("[flashlight_probe] device_create fail ~");
+ goto flashlight_probe_error;
+ }
+
+#ifdef MEIZU_M81
+ device_create_file(flashlight_device, &dev_attr_flash1);
+ device_create_file(flashlight_device, &dev_attr_flash2);
+#endif
+
+ //initialize members
+ spin_lock_init(&flashlight_private.lock);
+ init_waitqueue_head(&flashlight_private.read_wait);
+ //init_MUTEX(&flashlight_private.sem);
+ sema_init(&flashlight_private.sem, 1);
+
+ logI("[flashlight_probe] Done ~");
+ return 0;
+
+flashlight_probe_error:
+#ifdef ALLOC_DEVNO
+ if (err == 0)
+ cdev_del(&flashlight_cdev);
+ if (ret == 0)
+ unregister_chrdev_region(flashlight_devno, 1);
+#else
+ if (ret == 0)
+ unregister_chrdev(MAJOR(flashlight_devno), FLASHLIGHT_DEVNAME);
+#endif
+ return -1;
+}
+
+static int flashlight_remove(struct platform_device *dev)
+{
+
+ logI("[flashlight_probe] start\n");
+
+#ifdef ALLOC_DEVNO
+ cdev_del(&flashlight_cdev);
+ unregister_chrdev_region(flashlight_devno, 1);
+#else
+ unregister_chrdev(MAJOR(flashlight_devno), FLASHLIGHT_DEVNAME);
+#endif
+ device_destroy(flashlight_class, flashlight_devno);
+ class_destroy(flashlight_class);
+
+ logI("[flashlight_probe] Done ~");
+ return 0;
+}
+
+static void flashlight_shutdown(struct platform_device *dev)
+{
+
+ logI("[flashlight_shutdown] start\n");
+ checkAndRelease();
+ logI("[flashlight_shutdown] Done ~");
+}
+
+static struct platform_driver flashlight_platform_driver =
+{
+ .probe = flashlight_probe,
+ .remove = flashlight_remove,
+ .shutdown = flashlight_shutdown,
+ .driver = {
+ .name = FLASHLIGHT_DEVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_device flashlight_platform_device = {
+ .name = FLASHLIGHT_DEVNAME,
+ .id = 0,
+ .dev = {
+ }
+};
+
+static int __init flashlight_init(void)
+{
+ int ret = 0;
+ logI("[flashlight_probe] start ~");
+
+ ret = platform_device_register (&flashlight_platform_device);
+ if (ret) {
+ logE("[flashlight_probe] platform_device_register fail ~");
+ return ret;
+ }
+
+ ret = platform_driver_register(&flashlight_platform_driver);
+ if(ret){
+ logE("[flashlight_probe] platform_driver_register fail ~");
+ return ret;
+ }
+
+ register_low_battery_notify(&Lbat_protection_powerlimit_flash, LOW_BATTERY_PRIO_FLASHLIGHT);
+ register_battery_percent_notify(&bat_per_protection_powerlimit_flashlight, BATTERY_PERCENT_PRIO_FLASHLIGHT);
+//@@ register_battery_oc_notify(&bat_oc_protection_powerlimit, BATTERY_OC_PRIO_FLASHLIGHT);
+
+ logI("[flashlight_probe] done! ~");
+ return ret;
+}
+
+static void __exit flashlight_exit(void)
+{
+ logI("[flashlight_probe] start ~");
+ platform_driver_unregister(&flashlight_platform_driver);
+ //to flush work queue
+ //flush_scheduled_work();
+ logI("[flashlight_probe] done! ~");
+}
+
+//========================================================
+module_init(flashlight_init);
+module_exit(flashlight_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jackie Su <jackie.su@mediatek.com>");
+MODULE_DESCRIPTION("Flashlight control Driver");
+
+#endif
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/out.txt b/drivers/misc/mediatek/flashlight/src/mt6735/out.txt
new file mode 100755
index 000000000..6b23324f3
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/out.txt
@@ -0,0 +1,10 @@
+LOCAL_SRC_FILES += \
+ kd_flashlightlist.c \
+ strobe_main_sid2_part1.c \
+ strobe_main_sid2_part2.c \
+ strobe_sub_sid2_part1.c \
+ strobe_sub_sid2_part2.c \
+ sub_strobe.c \
+ strobe_main_sid1_part2.c \
+ strobe_part_id.c \
+ strobe_sub_sid1_part2.c \
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid1_part2.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid1_part2.c
new file mode 100644
index 000000000..32de1f934
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid1_part2.c
@@ -0,0 +1,103 @@
+
+#ifdef CONFIG_COMPAT
+
+#include <linux/fs.h>
+#include <linux/compat.h>
+
+#endif
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[strobe_main_sid1_part2.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+
+static int strobe_ioctl(unsigned int cmd, unsigned long arg)
+{
+ PK_DBG("sub dummy ioctl");
+ return 0;
+}
+
+static int strobe_open(void *pArg)
+{
+ PK_DBG("sub dummy open");
+ return 0;
+}
+
+static int strobe_release(void *pArg)
+{
+ PK_DBG("sub dummy release");
+ return 0;
+}
+
+static FLASHLIGHT_FUNCTION_STRUCT strobeFunc=
+{
+ strobe_open,
+ strobe_release,
+ strobe_ioctl
+};
+
+MUINT32 strobeInit_main_sid1_part2(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &strobeFunc;
+ }
+ return 0;
+}
+
+
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part1.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part1.c
new file mode 100644
index 000000000..4f20c09c8
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part1.c
@@ -0,0 +1,396 @@
+#ifdef CONFIG_COMPAT
+
+#include <linux/fs.h>
+#include <linux/compat.h>
+
+#endif
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+#include <mach/upmu_common.h>
+//#include <mach/mt6333.h>
+
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[strobe_main_sid2_part1.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+/******************************************************************************
+ * local variables
+******************************************************************************/
+static DEFINE_SPINLOCK(g_strobeSMPLock); /* cotta-- SMP proection */
+static struct work_struct workTimeOut;
+static int g_timeOutTimeMs=0;
+static u32 strobe_Res = 0;
+/*****************************************************************************
+Functions
+*****************************************************************************/
+static void work_timeOutFunc(struct work_struct *data);
+
+//extern int flashEnable_sky81296_2(void);
+//extern int flashDisable_sky81296_2(void);
+//extern int setDuty_sky81296_2(int duty);
+//int init_sky81296();
+
+#define MEIZU_M81
+
+#ifdef MEIZU_M81
+extern int FL_Enable_led2(void);
+extern int FL_dim_duty_led2(kal_uint32 duty);
+extern int FL_Disable_led2(void);
+#endif
+
+static int FL_Enable(void)
+{
+// flashEnable_sky81296_1();
+#ifdef MEIZU_M81
+ FL_Enable_led2();
+#endif
+ PK_DBG("FL_Enable-");
+
+ return 0;
+}
+
+static int FL_Disable(void)
+{
+ // flashDisable_sky81296_1();
+#ifdef MEIZU_M81
+ FL_Disable_led2();
+#endif
+ return 0;
+}
+
+static int FL_dim_duty(kal_uint32 duty)
+{
+ //setDuty_sky81296_1(duty);
+#ifdef MEIZU_M81
+ FL_dim_duty_led2(duty);
+#endif
+ return 0;
+}
+
+/*
+static int g_lowPowerLevel=LOW_BATTERY_LEVEL_0;
+static void lowPowerCB(LOW_BATTERY_LEVEL lev)
+{
+ g_lowPowerLevel=lev;
+}*/
+
+static int FL_Init(void)
+{
+ PK_DBG(" FL_Init line=%d\n",__LINE__);
+ INIT_WORK(&workTimeOut, work_timeOutFunc);
+ // register_low_battery_callback(&lowPowerCB, LOW_BATTERY_PRIO_FLASHLIGHT);
+ // register_low_battery_notify(&lowPowerCB, LOW_BATTERY_PRIO_FLASHLIGHT);
+
+
+
+ return 0;
+}
+static int FL_Uninit(void)
+{
+ FL_Disable();
+ return 0;
+}
+
+static int FL_hasLowPowerDetect(void)
+{
+
+ return 1;
+}
+
+static int detLowPowerStart(void)
+{
+
+// g_lowPowerLevel=LOW_BATTERY_LEVEL_0;
+ return 0;
+}
+
+
+static int detLowPowerEnd(void)
+{
+
+ return 0;
+}
+
+/*****************************************************************************
+User interface
+*****************************************************************************/
+static struct hrtimer g_timeOutTimer;
+
+static int g_b1stInit=1;
+
+static void work_timeOutFunc(struct work_struct *data)
+{
+ FL_Disable();
+ PK_DBG("ledTimeOut_callback\n");
+}
+
+
+
+static enum hrtimer_restart ledTimeOutCallback(struct hrtimer *timer)
+{
+ schedule_work(&workTimeOut);
+ return HRTIMER_NORESTART;
+}
+
+static void timerInit(void)
+{
+ //ktime_t ktime;
+
+
+ //mt6333_set_rg_chrwdt_en(0);
+
+ //mt6333_set_rg_chrwdt_td(0); //4 sec
+ //mt6333_set_rg_chrwdt_en(1);
+
+ //mt6333_set_rg_chrwdt_en(0);
+
+ if(g_b1stInit==1)
+ {
+ g_b1stInit=0;
+
+
+ INIT_WORK(&workTimeOut, work_timeOutFunc);
+ g_timeOutTimeMs=1000; //1s
+ hrtimer_init( &g_timeOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
+ g_timeOutTimer.function=ledTimeOutCallback;
+ }
+
+
+
+}
+
+
+static int constant_flashlight_ioctl(unsigned int cmd, unsigned long arg)
+{
+ int temp;
+ int i4RetValue = 0;
+ int ior_shift;
+ int iow_shift;
+ int iowr_shift;
+ //kal_uint8 valTemp;
+ ior_shift = cmd - (_IOR(FLASHLIGHT_MAGIC,0, int));
+ iow_shift = cmd - (_IOW(FLASHLIGHT_MAGIC,0, int));
+ iowr_shift = cmd - (_IOWR(FLASHLIGHT_MAGIC,0, int));
+ PK_DBG("constant_flashlight_ioctl() line=%d ior_shift=%d, iow_shift=%d iowr_shift=%d arg=%d\n",__LINE__, ior_shift, iow_shift, iowr_shift, (int)arg);
+ switch(cmd)
+ {
+
+ case FLASH_IOC_SET_TIME_OUT_TIME_MS:
+ PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",(int)arg);
+ g_timeOutTimeMs=arg;
+ break;
+
+
+ case FLASH_IOC_SET_DUTY :
+ PK_DBG("FLASHLIGHT_DUTY: %d\n",(int)arg);
+ FL_dim_duty(arg);
+ break;
+
+
+ case FLASH_IOC_SET_STEP:
+ PK_DBG("FLASH_IOC_SET_STEP: %d\n",(int)arg);
+
+ break;
+
+ case FLASH_IOC_SET_ONOFF :
+ PK_DBG("FLASHLIGHT_ONOFF: %d\n",(int)arg);
+ if(arg==1)
+ {
+ if(g_timeOutTimeMs!=0)
+ {
+ ktime_t ktime;
+ ktime = ktime_set( 0, g_timeOutTimeMs*1000000 );
+ hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL );
+ }
+ FL_Enable();
+ }
+ else
+ {
+ FL_Disable();
+ hrtimer_cancel( &g_timeOutTimer );
+ }
+ break;
+/*
+ case FLASH_IOC_PRE_ON:
+ PK_DBG("FLASH_IOC_PRE_ON\n");
+ FL_preOn();
+ break;
+ case FLASH_IOC_GET_PRE_ON_TIME_MS:
+ PK_DBG("FLASH_IOC_GET_PRE_ON_TIME_MS: %d\n",(int)arg);
+ temp=13;
+ if(copy_to_user((void __user *) arg , (void*)&temp , 4))
+ {
+ PK_DBG(" ioctl copy to user failed\n");
+ return -1;
+ }
+ break;
+*/
+ case FLASH_IOC_SET_REG_ADR:
+ PK_DBG("FLASH_IOC_SET_REG_ADR: %d\n",(int)arg);
+ //g_reg = arg;
+ break;
+ case FLASH_IOC_SET_REG_VAL:
+ PK_DBG("FLASH_IOC_SET_REG_VAL: %d\n",(int)arg);
+ //g_val = arg;
+ break;
+ case FLASH_IOC_SET_REG:
+ // PK_DBG("FLASH_IOC_SET_REG: %d %d\n",g_reg, g_val);
+
+ break;
+
+ case FLASH_IOC_GET_REG:
+ PK_DBG("FLASH_IOC_GET_REG: %d\n",(int)arg);
+
+ //i4RetValue = valTemp;
+ //PK_DBG("FLASH_IOC_GET_REG: v=%d\n",valTemp);
+ break;
+
+ case FLASH_IOC_HAS_LOW_POWER_DETECT:
+ PK_DBG("FLASH_IOC_HAS_LOW_POWER_DETECT");
+ temp=FL_hasLowPowerDetect();
+ if(copy_to_user((void __user *) arg , (void*)&temp , 4))
+ {
+ PK_DBG(" ioctl copy to user failed\n");
+ return -1;
+ }
+ break;
+ case FLASH_IOC_LOW_POWER_DETECT_START:
+ detLowPowerStart();
+ break;
+ case FLASH_IOC_LOW_POWER_DETECT_END:
+ i4RetValue = detLowPowerEnd();
+ break;
+
+ default :
+ PK_DBG(" No such command \n");
+ i4RetValue = -EPERM;
+ break;
+ }
+ return i4RetValue;
+}
+
+
+
+
+static int constant_flashlight_open(void *pArg)
+{
+ int i4RetValue = 0;
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+
+ if (0 == strobe_Res)
+ {
+ FL_Init();
+ timerInit();
+ }
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+ spin_lock_irq(&g_strobeSMPLock);
+
+
+ if(strobe_Res)
+ {
+ PK_ERR(" busy!\n");
+ i4RetValue = -EBUSY;
+ }
+ else
+ {
+ strobe_Res += 1;
+ }
+
+
+ spin_unlock_irq(&g_strobeSMPLock);
+ PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
+
+ return i4RetValue;
+
+}
+
+
+static int constant_flashlight_release(void *pArg)
+{
+ PK_DBG(" constant_flashlight_release\n");
+
+ if (strobe_Res)
+ {
+ spin_lock_irq(&g_strobeSMPLock);
+
+ strobe_Res = 0;
+
+
+ spin_unlock_irq(&g_strobeSMPLock);
+ FL_Uninit();
+ }
+ PK_DBG(" Done\n");
+ return 0;
+}
+
+
+static FLASHLIGHT_FUNCTION_STRUCT constantFlashlightFunc=
+{
+ constant_flashlight_open,
+ constant_flashlight_release,
+ constant_flashlight_ioctl
+};
+
+
+
+MUINT32 strobeInit_main_sid2_part1(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &constantFlashlightFunc;
+ }
+ return 0;
+}
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part2.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part2.c
new file mode 100644
index 000000000..4738c1dfd
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_main_sid2_part2.c
@@ -0,0 +1,103 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[strobe_main_sid2_part2.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+
+static int sub_strobe_ioctl(unsigned int cmd, unsigned long arg)
+{
+ PK_DBG("sub dummy ioctl");
+ return 0;
+}
+
+static int sub_strobe_open(void *pArg)
+{
+ PK_DBG("sub dummy open");
+ return 0;
+
+}
+
+static int sub_strobe_release(void *pArg)
+{
+ PK_DBG("sub dummy release");
+ return 0;
+
+}
+
+static FLASHLIGHT_FUNCTION_STRUCT subStrobeFunc=
+{
+ sub_strobe_open,
+ sub_strobe_release,
+ sub_strobe_ioctl
+};
+
+
+MUINT32 strobeInit_main_sid2_part2(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &subStrobeFunc;
+ }
+ return 0;
+}
+
+
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_part_id.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_part_id.c
new file mode 100644
index 000000000..4cd059ccb
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_part_id.c
@@ -0,0 +1,43 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+
+int strobe_getPartId(int sensorDev)
+{
+ // return 1 or 2 (backup flash part). Other numbers are invalid.
+ if(sensorDev == e_CAMERA_MAIN_SENSOR)
+ {
+ return 1;
+ }
+ else if(sensorDev == e_CAMERA_SUB_SENSOR)
+ {
+ return 1;
+ }
+ else //e_CAMERA_MAIN_2_SENSOR
+ {
+ return 200;
+ }
+ return 100;
+} \ No newline at end of file
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid1_part2.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid1_part2.c
new file mode 100644
index 000000000..ba8f540bf
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid1_part2.c
@@ -0,0 +1,102 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[strobe_sub_sid1_part2.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+
+static int strobe_ioctl(unsigned int cmd, unsigned long arg)
+{
+ PK_DBG("sub dummy ioctl");
+ return 0;
+}
+
+
+static int strobe_open(void *pArg)
+{
+ PK_DBG("sub dummy open");
+ return 0;
+}
+
+static int strobe_release(void *pArg)
+{
+ PK_DBG("sub dummy release");
+ return 0;
+}
+
+static FLASHLIGHT_FUNCTION_STRUCT strobeFunc=
+{
+ strobe_open,
+ strobe_release,
+ strobe_ioctl
+};
+
+MUINT32 strobeInit_sub_sid1_part2(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &strobeFunc;
+ }
+ return 0;
+}
+
+
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part1.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part1.c
new file mode 100644
index 000000000..4cb706687
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part1.c
@@ -0,0 +1,105 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[strobe_sub_sid2_part1.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+
+static int sub_strobe_ioctl(unsigned int cmd, unsigned long arg)
+{
+ PK_DBG("sub dummy ioctl");
+ return 0;
+}
+
+static int sub_strobe_open(void *pArg)
+{
+ PK_DBG("sub dummy open");
+ return 0;
+
+}
+
+static int sub_strobe_release(void *pArg)
+{
+ PK_DBG("sub dummy release");
+ return 0;
+
+}
+
+static FLASHLIGHT_FUNCTION_STRUCT subStrobeFunc=
+{
+ sub_strobe_open,
+ sub_strobe_release,
+ sub_strobe_ioctl
+};
+
+
+MUINT32 strobeInit_sub_sid2_part1(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &subStrobeFunc;
+ }
+ return 0;
+}
+
+
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part2.c b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part2.c
new file mode 100644
index 000000000..a5a7d9000
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/strobe_sub_sid2_part2.c
@@ -0,0 +1,103 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[strobe_sub_sid2_part2.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+
+static int sub_strobe_ioctl(unsigned int cmd, unsigned long arg)
+{
+ PK_DBG("sub dummy ioctl");
+ return 0;
+}
+
+static int sub_strobe_open(void *pArg)
+{
+ PK_DBG("sub dummy open");
+ return 0;
+
+}
+
+static int sub_strobe_release(void *pArg)
+{
+ PK_DBG("sub dummy release");
+ return 0;
+
+}
+
+static FLASHLIGHT_FUNCTION_STRUCT subStrobeFunc=
+{
+ sub_strobe_open,
+ sub_strobe_release,
+ sub_strobe_ioctl
+};
+
+
+MUINT32 strobeInit_sub_sid2_part2(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &subStrobeFunc;
+ }
+ return 0;
+}
+
+
+
+
+
diff --git a/drivers/misc/mediatek/flashlight/src/mt6735/sub_strobe.c b/drivers/misc/mediatek/flashlight/src/mt6735/sub_strobe.c
new file mode 100644
index 000000000..efe8011dc
--- /dev/null
+++ b/drivers/misc/mediatek/flashlight/src/mt6735/sub_strobe.c
@@ -0,0 +1,103 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "kd_camera_hw.h"
+#include <cust_gpio_usage.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
+#include <linux/xlog.h>
+#include <linux/version.h>
+#ifdef CONFIG_COMPAT
+#include <linux/fs.h>
+#include <linux/compat.h>
+#endif
+#include "kd_flashlight.h"
+/******************************************************************************
+ * Debug configuration
+******************************************************************************/
+// availible parameter
+// ANDROID_LOG_ASSERT
+// ANDROID_LOG_ERROR
+// ANDROID_LOG_WARNING
+// ANDROID_LOG_INFO
+// ANDROID_LOG_DEBUG
+// ANDROID_LOG_VERBOSE
+#define TAG_NAME "[sub_strobe.c]"
+#define PK_DBG_NONE(fmt, arg...) do {} while (0)
+#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
+#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
+#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
+
+#define DEBUG_LEDS_STROBE
+#ifdef DEBUG_LEDS_STROBE
+ #define PK_DBG PK_DBG_FUNC
+ #define PK_VER PK_TRC_VERBOSE
+ #define PK_ERR PK_ERROR
+#else
+ #define PK_DBG(a,...)
+ #define PK_VER(a,...)
+ #define PK_ERR(a,...)
+#endif
+
+
+static int sub_strobe_ioctl(unsigned int cmd, unsigned long arg)
+{
+ PK_DBG("sub dummy ioctl");
+ return 0;
+}
+
+static int sub_strobe_open(void *pArg)
+{
+ PK_DBG("sub dummy open");
+ return 0;
+
+}
+
+static int sub_strobe_release(void *pArg)
+{
+ PK_DBG("sub dummy release");
+ return 0;
+
+}
+
+FLASHLIGHT_FUNCTION_STRUCT subStrobeFunc=
+{
+ sub_strobe_open,
+ sub_strobe_release,
+ sub_strobe_ioctl
+};
+
+
+MUINT32 subStrobeInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
+{
+ if (pfFunc != NULL)
+ {
+ *pfFunc = &subStrobeFunc;
+ }
+ return 0;
+}
+
+
+
+
+