enum error_type ext_watch_set_position(struct spi_device *spi, struct ext_watch_cfg *cfg)
{
	u8 *ptr = (u8 *)(&cfg->position);	

	TOUCH_I("%s \n", __func__);

	DO_SAFE(sic_spi_write(spi, EXT_WATCH_POSITION, ptr, sizeof(u32) * 5), error);
	#if 0
	TOUCH_I("Set Hour Position [%d][%d] \n",
		cfg->position.h10x_pos, cfg->position.h1x_pos);
	TOUCH_I("Set Min Position [%d][%d] \n",
		cfg->position.m10x_pos, cfg->position.m1x_pos);
	TOUCH_I("Set Colon Position [%d] \n", cfg->position.clx_pos);
	TOUCH_I("Set Zero Display [%d] \n", cfg->position.zero_disp);
	TOUCH_I("Set 24H Mode [%d] \n", cfg->position.h24_en);
	TOUCH_I("Set Display Mode [%d] \n", cfg->position.clock_disp_mode);
	TOUCH_I("Set Clock Mode [%d] \n", cfg->position.clock_disp_mode);
	TOUCH_I("Set Blink period [%d] \n", cfg->position.bhprd);
	#endif

	return NO_ERROR;
error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;
}
int ext_watch_check_font_download(struct device *dev)
{
	struct touch_core_data *ts = to_touch_core(dev);
	struct lg4945_data *d = to_lg4945_data(dev);
	int ret = 0;

	TOUCH_I("%s:start\n", __func__);
	if (atomic_read(&d->watch.state.is_font) != DOWN_LOADED) {
		TOUCH_I("%s : font data is not\n", __func__);
		return -ENOMEM;
	}

	if (touch_mfts_mode_check(dev))
		return -EBUSY;

	if (atomic_read(&d->watch.state.font_mem) == DOWN_LOADING) {
		TOUCH_I("%s : doing download..\n", __func__);
		return -EBUSY;
	}
	if (atomic_read(&d->watch.state.font_mem) == DOWN_LOADED) {
		TOUCH_I("%s : not need download..\n", __func__);
		return -EBUSY;
	}

	if (d->watch.ext_wdata.font_data == NULL) {
		TOUCH_E("%s : font data is not ready\n",
			__func__);
		return -ENOMEM;
	}

	queue_delayed_work(ts->wq, &d->font_download_work, 0);

	return ret;
}
/* ext_watch_set_onoff
 *
 * 'power state' can has only 'ON' or 'OFF'. (not 'SLEEP' or 'WAKE') 
 */
enum error_type ext_watch_onoff(struct spi_device *spi, u32 onoff)
{
	TOUCH_I("%s %d\n", __func__, onoff);

	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_CTRL,
			(u8 *)&onoff, sizeof(u32)), error);

	return NO_ERROR;
error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;
}
enum error_type ext_watch_set_cfg(struct spi_device *spi,struct ext_watch_cfg *cfg)
{
	TOUCH_I("%s \n", __func__);

	cfg->mode.watch_ctrl.alpha = 1; // bypass foreground
	DO_IF(ext_watch_set_mode(spi, cfg) != 0, error);
	DO_IF(ext_watch_set_position(spi, cfg) != 0, error);

	return NO_ERROR;
error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;
}
enum error_type ext_watch_get_cfg(struct spi_device *spi, struct ext_watch_cfg *cfg)
{
	TOUCH_I("%s \n", __func__);

	DO_IF(ext_watch_get_mode(spi, cfg) != 0, error);
	DO_IF(ext_watch_get_position(spi, cfg) != 0, error);
	DO_IF(ext_watch_get_current_time(spi,cfg)!= 0, error);

	return NO_ERROR;
error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;
}
enum error_type ext_watch_get_current_time(struct spi_device *spi, struct ext_watch_cfg *cfg)
{
	DO_SAFE(sic_spi_read(spi, EXT_WATCH_RTC_CTST,
		(u8 *)&cfg->time.rtc_ctst, sizeof(u32)), error);

	TOUCH_I("%s : %02d:%02d:%02d\n", __func__,
		cfg->time.rtc_ctst.hour, cfg->time.rtc_ctst.min, cfg->time.rtc_ctst.sec);

	return NO_ERROR;

error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;
}
void touch_gpio_direction_input(int pin)
{
	TOUCH_I("%s - pin:%d\n", __func__, pin);

	if (gpio_is_valid(pin))
		gpio_direction_input(pin);
}
static ssize_t store_extwatch_fontposition_config(struct device *dev,
		const char *buf, size_t count)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	struct ExtWatchFontPostionConfig cfg;

	if (atomic_read(&d->block_watch_cfg) == SUPPORT)
		return count;

	memcpy((char *)&cfg, buf, sizeof(struct ExtWatchFontPostionConfig));

	d->watch.ext_wdata.mode.watch_area.watstartx = cfg.watstartx;
	d->watch.ext_wdata.mode.watch_area.watendx = cfg.watendx;
	d->watch.ext_wdata.position.h10x_pos = cfg.h10x_pos;
	d->watch.ext_wdata.position.h1x_pos = cfg.h1x_pos;
	d->watch.ext_wdata.position.m10x_pos = cfg.m10x_pos;
	d->watch.ext_wdata.position.m1x_pos = cfg.m1x_pos;
	d->watch.ext_wdata.position.clx_pos = cfg.clx_pos;

	if ( cfg.watstartx < 0x190 || cfg.watendx > 0x5A0 )
		TOUCH_E("check the position. (invalid range)\n");

	TOUCH_I("%s : Watch area [%d , %d] position [%d %d %d %d %d]\n",
		__func__, cfg.watstartx, cfg.watendx, cfg.h10x_pos,
		cfg.h1x_pos, cfg.clx_pos, cfg.m10x_pos, cfg.m1x_pos);

	return count;
}
static ssize_t store_extwatch_fontproperty_config
	(struct device *dev, const char *buf, size_t count)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	struct ExtWatchFontPropertyConfig cfg;
	int idx = 0;
	char log[256] = {0};
	int len = 0;

	if (atomic_read(&d->block_watch_cfg) == SUPPORT)
		return count;

	memcpy((char *)&cfg, buf, sizeof(struct ExtWatchFontPropertyConfig));

	len += snprintf(log + len, 256 - len, "%s : LUT[%d] ",
		__func__, (int)cfg.max_num);

	for (idx = 0; idx < (int)cfg.max_num; idx++) {
		d->watch.ext_wdata.mode.lut[idx].b = cfg.LUT[idx].RGB_blue;
		d->watch.ext_wdata.mode.lut[idx].g = cfg.LUT[idx].RGB_green;
		d->watch.ext_wdata.mode.lut[idx].r = cfg.LUT[idx].RGB_red;

		len += snprintf(log + len, 256 - len, "%d:%02X%02X%02X ", idx,
			cfg.LUT[idx].RGB_blue, cfg.LUT[idx].RGB_green,
			cfg.LUT[idx].RGB_red);
	}

	TOUCH_I("%s\n", log);

	return count;
}
static int watch_fontdata_attr_init(struct lg4945_data *d)
{
	d->watch.font_written_size = 0;
	d->watch.font_width = 0;
	d->watch.font_written_comp_size = COMP_FONTM_MAX_SIZE;
	d->watch.fontdata_size = MAX_WATCH_DATA_SIZE;
	d->watch.fontdata_comp_size = COMP_FONTM_MAX_SIZE;
	d->watch.ext_wdata.font_data =
			kzalloc(d->watch.fontdata_size, GFP_KERNEL);
	d->watch.ext_wdata.comp_buf =
			kzalloc(d->watch.fontdata_comp_size, GFP_KERNEL);
	if (d->watch.ext_wdata.font_data && d->watch.ext_wdata.comp_buf) {
		TOUCH_I("%s font_buffer(%d KB) malloc\n", __func__,
			d->watch.fontdata_size/1024);
	} else {
		TOUCH_E("%s font_buffer(%d KB) malloc failed\n", __func__,
			d->watch.fontdata_size/1024);
		return 1;
	}

	sysfs_bin_attr_init(&d->watch.fontdata_attr);
	d->watch.fontdata_attr.attr.name = "config_fontdata";
	d->watch.fontdata_attr.attr.mode = S_IWUSR | S_IRUSR;
	d->watch.fontdata_attr.read = watch_access_read;
	d->watch.fontdata_attr.write = watch_access_write;
	d->watch.fontdata_attr.size = d->watch.fontdata_size;

	if (sysfs_create_bin_file(&d->kobj, &d->watch.fontdata_attr) < 0)
		TOUCH_E("Failed to create %s\n",
			d->watch.fontdata_attr.attr.name);
	return 0;
}
static ssize_t store_extwatch_fontonoff
	(struct device *dev, const char *buf, size_t count)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	u8 value;
	u8 zero = '0';
	int ret = 0;

	if (atomic_read(&d->block_watch_cfg) == SUPPORT)
		return count;

	memcpy((char *)&value, buf, sizeof(u8));

	if (value == POWER_OFF || value == zero)
		value = 0x00;
	else
		value = 0x01;

	TOUCH_I("%s : %s\n", __func__,
			value ? "On" : "Off");

	ret = ext_watch_set_cfg(dev);
	if (ret)
		TOUCH_E("Fail %d\n", ret);

	d->watch.ext_wdata.time.disp_waton = value;
	ret = ext_watch_onoff(dev);
	if (ret)
		TOUCH_E("Fail %d\n", ret);

	return count;
}
static ssize_t store_extwatch_timesync_config(struct device *dev,
		const char *buf, size_t count)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	struct ExtWatchTimeSyncConfig cfg;
	int ret = 0;

	if (atomic_read(&d->block_watch_cfg) == SUPPORT)
		return count;

	memcpy((char *)&cfg, buf, sizeof(struct ExtWatchTimeSyncConfig));

	d->watch.ext_wdata.time.rtc_sct.hour = cfg.rtc_cwhour;
	d->watch.ext_wdata.time.rtc_sct.min = cfg.rtc_cwmin;
	d->watch.ext_wdata.time.rtc_sct.sec = cfg.rtc_cwsec;
	d->watch.ext_wdata.time.rtc_sctcnt = cfg.rtc_cwmilli;

	TOUCH_I("%s : %02d:%02d:%02d.%03d\n", __func__,
		cfg.rtc_cwhour, cfg.rtc_cwmin, cfg.rtc_cwsec, cfg.rtc_cwmilli);

	ret = ext_watch_set_current_time(dev);
	if (ret)
		TOUCH_E("%s fail\n", __func__);

	return count;
}
void touch_gpio_direction_output(int pin, int value)
{
	TOUCH_I("%s - pin:%d, value:%d\n", __func__, pin, value);

	if (gpio_is_valid(pin))
		gpio_direction_output(pin, value);
}
static int ext_watch_font_dump(struct device *dev, char *font_dump)
{
	u32 font_sel = 0;
	u32 font_data_offset = 0;
	u32 wdata = 0;
	u32 size = 0;
	int ret = 0;

	TOUCH_TRACE();

	/* Font memory access enable */
	wdata = 1;
	ret = lg4945_reg_write(dev, EXT_WATCH_FONT_ACC_EN,
		(u8 *)&wdata, sizeof(u32));
	if (ret)
		goto error;

	size = sizeof(u32) * EXT_WATCH_FONT_NUM_SIZE;

	for (font_sel = 0; font_sel < 10; font_sel++) {
		/* Font select : '0' ~ '9' */
		font_data_offset = font_sel * size;
		ret = lg4945_reg_write(dev, EXT_WATCH_FONT_SEL,
					(u8 *)&font_sel, sizeof(u32));
		if (ret)
			goto error;

		ret = lg4945_reg_read(dev, EXT_WATCH_FONT_OFFSET_ADDR,
			(u8 *)&font_dump[font_data_offset], size);
		if (ret)
			goto error;
	}

	/* Font select : ':' */
	font_data_offset = font_sel * size;
	size = sizeof(u32) * EXT_WATCH_FONT_CHAR_SIZE;
	ret = lg4945_reg_write(dev, EXT_WATCH_FONT_SEL,
		(u8 *)&font_sel, sizeof(u32));
	if (ret)
		goto error;
	ret = lg4945_reg_read(dev, EXT_WATCH_FONT_OFFSET_ADDR,
			(u8 *)&font_dump[font_data_offset], size);
	if (ret)
		goto error;

	/* Font memory access disable */
	wdata = 0;
	ret = lg4945_reg_write(dev, EXT_WATCH_FONT_ACC_EN,
		(u8 *)&wdata, sizeof(u32));
	if (ret)
		goto error;

	TOUCH_I("%s done\n", __func__);
	return ret;

error:
	TOUCH_E("fail %d\n", ret);
	return -EIO;
}
/* ext_watch_shutdown
 *
 * 'power state' can has only  'SLEEP' or 'WAKE' (not 'ON' or 'OFF')
 */
enum error_type ext_watch_shutdown(struct spi_device *spi, u8 onoff)
{
	u32 rtc_ctrl = EXT_WATCH_RTC_STOP;
	TOUCH_I("%s start \n", __func__ );

	if ( onoff == EXT_WATCH_RTC_START )
		rtc_ctrl = EXT_WATCH_RTC_START;

	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_RUN,
		(u8 *)&rtc_ctrl, sizeof(u32)), error);

	return NO_ERROR;
error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;

}
/* -- gpio -- */
int touch_gpio_init(int pin, const char *name)
{
	int ret = 0;
	TOUCH_I("%s - pin:%d, name:%s\n", __func__, pin, name);

	if (gpio_is_valid(pin))
		ret = gpio_request(pin, name);

	return ret;
}
void ext_watch_font_download_func(
	struct work_struct *font_download_work)
{
	struct lg4945_data *d =
		container_of(to_delayed_work(font_download_work),
				struct lg4945_data, font_download_work);
	struct touch_core_data *ts = to_touch_core(d->dev);

	u32 wdata = 0;
	int ret = 0;

	if (d->lcd_mode != LCD_MODE_U3) {
		TOUCH_E("skip font download, lcd mode[U%d]\n", d->lcd_mode);
		ret = -EBUSY;
		goto error;
	}

	TOUCH_I("%s start\n", __func__);
	/* Font memory access enable */
	wdata = 1;
	ret = lg4945_reg_write(ts->dev, EXT_WATCH_FONT_ACC_EN,
		(u8 *)&wdata, sizeof(u32));
	if (ret)
		goto error;

	ret = lg4945_reg_write(ts->dev, EXT_WATCH_FONT_COMP_ADDR,
		(u8 *)d->watch.ext_wdata.comp_buf,
		COMP_FONTM_MAX_SIZE);

	if (ret)
		goto error;
	wdata = 0;
	ret = lg4945_reg_write(ts->dev, EXT_WATCH_FONT_ACC_EN,
		(u8 *)&wdata, sizeof(u32));
	if (ret)
		goto error;
	atomic_set(&d->watch.state.font_mem, DOWN_LOADED);
	TOUCH_I("%s done\n", __func__);
	return;
error:
	TOUCH_E("Fail [%d]\n", ret);
}
enum error_type ext_watch_font_dump(struct spi_device *spi, char *font_dump)
{
	u32 font_sel = 0;
	u32 font_data_offset = 0;
	u32 wdata = 0;
	u32 size = 0;

	TOUCH_I("%s start\n", __func__);
	// Font memory access enable
	wdata = 1;
	DO_SAFE(sic_spi_write(spi, EXT_WATCH_FONT_ACC_EN,
		(u8 *)&wdata, sizeof(u32)), error);

	size = sizeof(u32) * EXT_WATCH_FONT_NUM_SIZE;

	for (font_sel = 0; font_sel < 10; font_sel++) {
		// Font select : '0' ~ '9'
		font_data_offset = font_sel * size;
		DO_SAFE(sic_spi_font_read(spi, (u8 *)&font_sel,
			font_dump+font_data_offset, size), error);
	}

	// Font select : ':'
	font_data_offset = font_sel * size;
	size = sizeof(u32) * EXT_WATCH_FONT_CHAR_SIZE;
	DO_SAFE(sic_spi_font_read(spi, (u8 *)&font_sel,
		font_dump+font_data_offset, size), error);

	// Font memory access disable
	wdata = 0;
	DO_SAFE(sic_spi_write(spi, EXT_WATCH_FONT_ACC_EN,
		(u8 *)&wdata, sizeof(u32)), error);

	TOUCH_I("%s done\n", __func__);
	return NO_ERROR;

error:
	TOUCH_I("%s Fail\n", __func__);
	return ERROR;
}
static ssize_t show_extwatch_fonttime_query
	(struct device *dev, char *buf)
{
	struct ExtWatchFontTimeQuery query;

	query.h24_supported = SUPPORT;
	query.AmPm_supported = NOT_SUPPORT;

	TOUCH_I("%s %2d %2d\n", __func__,
		query.h24_supported, query.AmPm_supported);

	memcpy(buf, (char *)&query, sizeof(struct ExtWatchFontTimeQuery));
	return sizeof(struct ExtWatchFontTimeQuery);
}
static int ext_watch_set_current_time(struct device *dev)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	u32 rtc_ctrl = EXT_WATCH_RTC_STOP;
	u16 rtc_count = 305;		/* for time, 1 /rtc_ecnt */
	int ret = 0;


	d->watch.ext_wdata.time.rtc_ecnt = 32764;
	d->watch.ext_wdata.time.rtc_sctcnt =
		(int)((d->watch.ext_wdata.time.rtc_sctcnt * rtc_count) / 10);

	ret = lg4945_reg_write(dev, EXT_WATCH_RTC_RUN,
		(u8 *)&rtc_ctrl, sizeof(u32));
	if (ret)
		goto error;
	ret = lg4945_reg_write(dev, EXT_WATCH_RTC_SCT,
		(u8 *)&d->watch.ext_wdata.time.rtc_sct, sizeof(u32));
	if (ret)
		goto error;

	ret = lg4945_reg_write(dev, EXT_WATCH_RTC_SCTCNT,
		(u8 *)&d->watch.ext_wdata.time.rtc_sctcnt, sizeof(u32));
	if (ret)
		goto error;

	rtc_ctrl = d->watch.ext_wdata.time.rtc_ecnt & 0xFFFF;
	ret = lg4945_reg_write(dev, EXT_WATCH_RTC_ECNT,
		(u8 *)&rtc_ctrl, sizeof(u32));
	if (ret)
		goto error;

	rtc_ctrl = EXT_WATCH_RTC_START;
	ret = lg4945_reg_write(dev, EXT_WATCH_RTC_RUN,
		(u8 *)&rtc_ctrl, sizeof(u32));
	if (ret)
		goto error;

	TOUCH_I("%s : %02d:%02d:%02d CLK[%d Hz]\n", __func__,
		d->watch.ext_wdata.time.rtc_sct.hour,
		d->watch.ext_wdata.time.rtc_sct.min,
		d->watch.ext_wdata.time.rtc_sct.sec,
		d->watch.ext_wdata.time.rtc_ecnt);

	return ret;

error:
	TOUCH_E("Fail %d\n", ret);
	return -EIO;
}
static ssize_t store_extwatch_fonteffect_config(struct device *dev,
		const char *buf, size_t count)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	struct ExtWatchFontEffectConfig cfg;
	char period[8] = {0};

	if (atomic_read(&d->block_watch_cfg) == SUPPORT)
		return count;

	memcpy((char *)&cfg, buf, sizeof(struct ExtWatchFontEffectConfig));

	d->watch.ext_wdata.position.h24_en = cfg.h24_en;
	d->watch.ext_wdata.position.zero_disp = cfg.zero_disp;
	d->watch.ext_wdata.position.clock_disp_mode = cfg.clock_disp_type;
	d->watch.ext_wdata.position.midnight_hour_zero_en
		= cfg.midnight_hour_zero_en;
	d->watch.ext_wdata.position.bhprd = cfg.blink.blink_type;
	d->watch.ext_wdata.mode.blink_area.bstartx = cfg.blink.bstartx;
	d->watch.ext_wdata.mode.blink_area.bendx = cfg.blink.bendx;
	d->watch.ext_wdata.time.disp_waton = cfg.watchon;

	switch (cfg.blink.blink_type) {
	default:
	case 0:
		snprintf(period, 8, "Off");
		break;
	case 1:
		snprintf(period, 8, "0.5 sec");
		break;
	case 2:
		snprintf(period, 8, "1 sec");
		break;
	case 3:
		snprintf(period, 8, "2 sec");
		break;
	}

	TOUCH_I("%s : 24h mode %s, Zero Dispaly %s,%s Type %s mode "
		"Blink area [%d , %d] Period %s "
		"Watch On/Off : %s\n", __func__,
		cfg.h24_en ? "Enable" : "Disable",
		cfg.zero_disp ? "Enable" : "Disable",
		cfg.clock_disp_type ? "MM:SS" : "HH:MM",
		cfg.midnight_hour_zero_en ? "00:00" : "12:00",
		cfg.blink.bstartx, cfg.blink.bendx, period,
		d->watch.ext_wdata.time.disp_waton ? "On" : "Off");

	return count;
}
enum error_type ext_watch_set_current_time(struct spi_device *spi, struct ext_watch_cfg *cfg)
{
	u32 rtc_ctrl = EXT_WATCH_RTC_STOP;
	u16 rtc_count = 305;		/* for time, 1 /rtc_ecnt */


	cfg->time.rtc_ecnt = 32764;
	cfg->time.rtc_sctcnt = (int)((cfg->time.rtc_sctcnt * rtc_count) / 10);

	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_RUN,
		(u8 *)&rtc_ctrl, sizeof(u32)), error);

	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_SCT,
		(u8 *)&cfg->time.rtc_sct, sizeof(u32)), error);

	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_SCTCNT,
		(u8 *)&cfg->time.rtc_sctcnt, sizeof(u32)), error);

	rtc_ctrl = cfg->time.rtc_ecnt & 0xFFFF;
	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_ECNT,
		(u8 *)&rtc_ctrl, sizeof(u32)), error);

	rtc_ctrl = EXT_WATCH_RTC_START;
	DO_SAFE(sic_spi_write(spi, EXT_WATCH_RTC_RUN,
		(u8 *)&rtc_ctrl, sizeof(u32)), error);

	TOUCH_I("%s : %02d:%02d:%02d CLK[%d Hz]\n", __func__,
		cfg->time.rtc_sct.hour, cfg->time.rtc_sct.min,
		cfg->time.rtc_sct.sec, cfg->time.rtc_ecnt);

	return NO_ERROR;

error:
	TOUCH_I("%s Fail \n", __func__);
	return ERROR;
}
/* -- power -- */
int touch_power_init(struct device *dev)
{
	struct touch_core_data *ts = to_touch_core(dev);

	TOUCH_TRACE();

	if (gpio_is_valid(ts->vdd_pin)) {
		gpio_request(ts->vdd_pin, "touch-vdd");
	} else {
		ts->vdd = regulator_get(dev, "vdd");
		if (IS_ERR(ts->vdd))
			TOUCH_I("regulator \"vdd\" not exist\n");
	}

	if (gpio_is_valid(ts->vio_pin)) {
		gpio_request(ts->vio_pin, "touch-vio");
	} else {
		ts->vio = regulator_get(dev, "vio");
		if (IS_ERR(ts->vio))
			TOUCH_I("regulator \"vio\" not exist\n");
	}

	return 0;
}
int write_file(char *filename, char *data)
{
	struct file *file;
	loff_t pos = 0;

	file = filp_open(filename,
			O_WRONLY | O_CREAT | O_APPEND, 0666);
	if (IS_ERR(file)) {
		TOUCH_I("%s :  Open file error [ %s ]\n", __func__,
				filename);
		return PTR_ERR(file);
	}

	vfs_write(file, data, strlen(data), &pos);
	filp_close(file, 0);

	return 0;
}
static ssize_t watch_access_read(struct file *filp, struct kobject *kobj,
	struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
{
	struct lg4945_data *d = container_of(kobj, struct lg4945_data, kobj);
	ssize_t retval = -EFAULT;

	if (off == 0 && count == PAGE_SIZE)
		ext_watch_font_dump(d->dev, d->watch.ext_wdata.font_data);

	if (count == 0 && off + count >= d->watch.fontdata_size) {
		TOUCH_I("%s size error offset[%d] size[%d]\n", __func__,
			(int)off, (int)count);
	} else {
		memcpy(buf, &d->watch.ext_wdata.font_data[off], count);
		retval = count;
	}
	return retval;
}
int watch_init(struct device *dev)
{
	int ret = 0;

	TOUCH_I("%s\n", __func__);

	if (touch_mfts_mode_check(dev))
		return -EBUSY;

	ret = ext_watch_set_cfg(dev);
	if (ret)
		TOUCH_E("Fail %d\n", ret);

	ret = ext_watch_onoff(dev);
	if (ret)
		TOUCH_E("Fail %d\n", ret);

	return ret;
}
static int ext_watch_set_position(struct device *dev)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	u8 *ptr = (u8 *)(&d->watch.ext_wdata.position);
	int ret = 0;

	if (d->lcd_mode != LCD_MODE_U3) {
		TOUCH_I("skip %s, lcd mode[U%d]\n", __func__, d->lcd_mode);
	} else {
		ret = lg4945_reg_write(dev, EXT_WATCH_POSITION,
					ptr, sizeof(u32)*5);
		if (ret)
			goto error;
	}
	return ret;
error:
	TOUCH_E("Fail %d\n", ret);
	return -EIO;
}
static int ext_watch_get_current_time(struct device *dev)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	int ret = 0;

	TOUCH_TRACE();
	ret = lg4945_reg_read(dev, EXT_WATCH_RTC_CTST,
		(u8 *)&d->watch.ext_wdata.time.rtc_ctst, sizeof(u32));

	if (ret < 0) {
		TOUCH_E("%s Fail\n", __func__);
		return ret;
	}

	TOUCH_I("%s : %02d:%02d:%02d\n", __func__,
		d->watch.ext_wdata.time.rtc_ctst.hour,
		d->watch.ext_wdata.time.rtc_ctst.min,
		d->watch.ext_wdata.time.rtc_ctst.sec);

	return ret;
}
static ssize_t store_block_cfg(struct device *dev,
		const char *buf, size_t count)
{
	struct lg4945_data *d = to_lg4945_data(dev);
	u8 value;
	u8 zero = '0';

	memcpy(&value, buf, sizeof(u8));

	if (value == NOT_SUPPORT || value == zero)
		value = 0x00;
	else
		value = 0x01;

	atomic_set(&d->block_watch_cfg, value);

	TOUCH_I("%s : %s\n", __func__,
			value ? "BLOCK" : "OPEN");

	return count;
}
static ssize_t store_extwatch_onoff(struct device *dev,
		const char *buf, size_t count)
{
	u8 value;
	u8 zero = '0';
	int ret = 0;

	memcpy(&value, buf, sizeof(u8));

	if (value == POWER_OFF || value == zero)
		value = 0x00;
	else
		value = 0x01;

	ret = ext_watch_shutdown(dev, value);
	if (ret)
		TOUCH_E("Fail %d\n", ret);

	TOUCH_I("%s : %s\n", __func__,
			value ? "START" : "STOP");

	return count;
}