edp-eeprom.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097
  1. /*
  2. * cypress_touchkey.c - Platform data for edp eeprom driver
  3. *
  4. * Copyright (C) 2011 Samsung Electronics
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. */
  11. #include <linux/kernel.h>
  12. #include <asm/unaligned.h>
  13. //#include <mach/cpufreq.h>
  14. #include <linux/input/mt.h>
  15. #include <linux/of_gpio.h>
  16. #include <linux/regulator/consumer.h>
  17. #include <linux/module.h>
  18. #include <linux/input.h>
  19. #include <linux/init.h>
  20. #include <linux/slab.h>
  21. #include <linux/i2c.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/irq.h>
  24. #include <linux/delay.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/gpio.h>
  27. #include <linux/miscdevice.h>
  28. #include <linux/earlysuspend.h>
  29. #include <linux/regulator/consumer.h>
  30. #include <asm/mach-types.h>
  31. #include <linux/device.h>
  32. #include <linux/of_gpio.h>
  33. #include "mdss.h"
  34. #include "mdss_panel.h"
  35. #include "mdss_mdp.h"
  36. #include "mdss_edp.h"
  37. #if defined(CONFIG_SEC_LT03_PROJECT)
  38. #include "n1_power_save.h"
  39. #elif defined(CONFIG_SEC_PICASSO_PROJECT)
  40. #include "picasso_power_save.h"
  41. #else ////defined(CONFIG_SEC_VIENNA_PROJECT) || defined(CONFIG_SEC_V2_PROJECT)
  42. #include "v1_power_save.h"
  43. #endif
  44. #if defined(CONFIG_EDP_TCON_MDNIE)
  45. #include "edp_tcon_mdnie.h"
  46. #endif
  47. #define DDI_VIDEO_ENHANCE_TUNING
  48. #if defined(DDI_VIDEO_ENHANCE_TUNING)
  49. #include <linux/syscalls.h>
  50. #include <asm/uaccess.h>
  51. #include <linux/slab.h>
  52. #include <linux/lcd.h>
  53. #endif
  54. #if defined(CONFIG_SEC_LT03_PROJECT) || defined(CONFIG_SEC_PICASSO_PROJECT)
  55. #define LOWEST_PWM_DUTY 10
  56. #else
  57. #define LOWEST_PWM_DUTY 20
  58. #endif
  59. extern struct mutex edp_power_state_chagne;
  60. struct edp_eeprom_platform_data {
  61. int gpio_sda;
  62. u32 sda_gpio_flags;
  63. int gpio_scl;
  64. u32 scl_gpio_flags;
  65. /*for tuning sysfs*/
  66. struct device *dev;
  67. int mode;
  68. int lux;
  69. int auto_br;
  70. int power_save_mode;
  71. };
  72. struct edp_eeprom_info {
  73. struct i2c_client *client;
  74. struct edp_eeprom_platform_data *pdata;
  75. };
  76. static struct class *tcon_class;
  77. static struct edp_eeprom_info *global_pinfo;
  78. extern int get_edp_power_state(void);
  79. static void eeprom_request_gpio_slave(struct edp_eeprom_platform_data *pdata)
  80. {
  81. pr_info("%s gpio_scl : %d , gpio_sda : %d", __func__, pdata->gpio_scl, pdata->gpio_sda);
  82. gpio_tlmm_config(GPIO_CFG(pdata->gpio_scl, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  83. gpio_tlmm_config(GPIO_CFG(pdata->gpio_sda, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  84. }
  85. static void eeprom_request_gpio_master(struct edp_eeprom_platform_data *pdata)
  86. {
  87. pr_info("%s gpio_scl : %d , gpio_sda : %d", __func__, pdata->gpio_scl, pdata->gpio_sda);
  88. gpio_tlmm_config(GPIO_CFG(pdata->gpio_scl, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  89. gpio_tlmm_config(GPIO_CFG(pdata->gpio_sda, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  90. }
  91. static int eeprom_i2c_read(struct i2c_client *client,
  92. u16 reg, u8 *val, unsigned int len)
  93. {
  94. int err = 0;
  95. struct i2c_adapter *adapter = client->adapter;
  96. struct i2c_msg msg[2];
  97. u8 buf1[] = { reg >> 8, reg & 0xFF };
  98. msg[0].addr = client->addr;
  99. msg[0].flags = 0x00;
  100. msg[0].len = 2;
  101. msg[0].buf = buf1;
  102. msg[1].addr = client->addr;
  103. msg[1].flags = I2C_M_RD;
  104. msg[1].len = 1;
  105. msg[1].buf = val;
  106. err = i2c_transfer(adapter, msg, 2);
  107. if (err == 2)
  108. pr_debug("%s ok", __func__);
  109. else
  110. pr_info("%s fail err = %d", __func__, err);
  111. return err;
  112. }
  113. static int eeprom_i2c_write(struct i2c_client *client,
  114. u16 *reg, u8 *val, unsigned int len)
  115. {
  116. int err = 0;
  117. struct i2c_adapter *adapter = client->adapter;
  118. struct i2c_msg msg[len];
  119. u8 buf[len][3];
  120. int loop;
  121. for (loop = 0; loop < len; loop++) {
  122. buf[loop][0] = reg[loop] >> 8;
  123. buf[loop][1] = reg[loop] & 0xFF;
  124. buf[loop][2] = val[loop];
  125. msg[loop].addr = client->addr;
  126. msg[loop].flags = 0x00;
  127. msg[loop].len = 3;
  128. msg[loop].buf = &buf[loop][0];
  129. }
  130. err = i2c_transfer(adapter, msg, len);
  131. if (err == len)
  132. pr_debug("%s ok", __func__);
  133. else
  134. pr_info("%s fail err = %d", __func__, err);
  135. return err;
  136. }
  137. void tcon_i2c_slave_change(void)
  138. {
  139. unsigned char data[3];
  140. /* i2c slave change */
  141. data[0] = 0x03;
  142. data[1] = 0x13;
  143. data[2] = 0xBB;
  144. aux_tx(0x491, data, 3);
  145. data[0] = 0x03;
  146. data[1] = 0x14;
  147. data[2] = 0xBB;
  148. aux_tx(0x491, data, 3);
  149. if (global_pinfo)
  150. eeprom_request_gpio_master(global_pinfo->pdata);
  151. else
  152. pr_info("%s global_pinfo is NULL", __func__);
  153. #if defined(CONFIG_EDP_TCON_MDNIE)
  154. /* TO enable MDNIE*/
  155. data[0] = 0x08;
  156. aux_tx(0x720, data, 1);
  157. update_mdnie_register();
  158. #endif
  159. }
  160. static void tcon_init_setting(void)
  161. {
  162. u16 i2c_addr[4];
  163. u8 i2c_data[4];
  164. unsigned char data[3];
  165. /* i2c slave change */
  166. data[0] = 0x03;
  167. data[1] = 0x13;
  168. data[2] = 0xBB;
  169. aux_tx(0x491, data, 3);
  170. data[0] = 0x03;
  171. data[1] = 0x14;
  172. data[2] = 0xBB;
  173. aux_tx(0x491, data, 3);
  174. /* TO enable MDNIE*/
  175. data[0] = 0x08;
  176. aux_tx(0x720, data, 1);
  177. /* TCON SETTING FOR ESD RECOVERY*/
  178. data[0] = 0x81;
  179. data[1] = 0x68;
  180. data[2] = 0x04;
  181. aux_tx(0x491, data, sizeof(data));
  182. if (!global_pinfo) {
  183. pr_info("%s global_pinfo is NULL", __func__);
  184. return ;
  185. }
  186. eeprom_request_gpio_master(global_pinfo->pdata);
  187. /* low revision panel needs update display resolution */
  188. i2c_addr[0] = 0xCB2; i2c_data[0] = 0x0;
  189. i2c_addr[1] = 0xCB3; i2c_data[1] = 0x0A;
  190. i2c_addr[2] = 0xCB4; i2c_data[2] = 0x40;
  191. i2c_addr[3] = 0xCB5; i2c_data[3] = 0x06;
  192. eeprom_i2c_write(global_pinfo->client, i2c_addr, i2c_data, 4);
  193. }
  194. int mdnie_tune_cmd(short *tune_data, int len)
  195. {
  196. int data_pos;
  197. u16 i2c_addr[len];
  198. u8 i2c_data[len];
  199. mutex_lock(&edp_power_state_chagne);
  200. if (!get_edp_power_state()) {
  201. pr_info("%s get_edp_power_state off", __func__);
  202. mutex_unlock(&edp_power_state_chagne);
  203. return -EINVAL;
  204. }
  205. if (!global_pinfo) {
  206. pr_info("%s global_pinfo is NULL", __func__);
  207. mutex_unlock(&edp_power_state_chagne);
  208. return -EINVAL;
  209. }
  210. //Send Tune Commands
  211. for(data_pos = 0;data_pos < len ;data_pos++) {
  212. i2c_addr[data_pos] = tune_data[data_pos * 2];
  213. i2c_data[data_pos] = (char)(tune_data[(data_pos * 2)+1]);
  214. }
  215. eeprom_i2c_write(global_pinfo->client, i2c_addr, i2c_data, len);
  216. #if 0
  217. for(data_pos = 0;data_pos < len ;data_pos++) {
  218. eeprom_i2c_read(global_pinfo->client, tune_data[data_pos * 2], data, 1);
  219. pr_info("0x%04x,0x%02x\n", tune_data[data_pos * 2], data[0]);
  220. }
  221. #endif
  222. mutex_unlock(&edp_power_state_chagne);
  223. return 0;
  224. }
  225. #if defined(DDI_VIDEO_ENHANCE_TUNING)
  226. #define MAX_FILE_NAME 128
  227. #define TUNING_FILE_PATH "/sdcard/"
  228. #define MDNIE_TUNE_SIZE 98
  229. static char tuning_file[MAX_FILE_NAME];
  230. static short mdni_addr[MDNIE_TUNE_SIZE];
  231. static char mdni_tuning_val[MDNIE_TUNE_SIZE];
  232. #define TCON_TUNE_SIZE 20
  233. static short tcon_addr[TCON_TUNE_SIZE];
  234. static char tcon_tuning_val[TCON_TUNE_SIZE];
  235. static char char_to_dec(char data1, char data2)
  236. {
  237. char dec;
  238. dec = 0;
  239. if (data1 >= 'a') {
  240. data1 -= 'a';
  241. data1 += 10;
  242. } else if (data1 >= 'A') {
  243. data1 -= 'A';
  244. data1 += 10;
  245. } else
  246. data1 -= '0';
  247. dec = data1 << 4;
  248. if (data2 >= 'a') {
  249. data2 -= 'a';
  250. data2 += 10;
  251. } else if (data2 >= 'A') {
  252. data2 -= 'A';
  253. data2 += 10;
  254. } else
  255. data2 -= '0';
  256. dec |= data2;
  257. return dec;
  258. }
  259. static void sending_tune_cmd(struct edp_eeprom_info *info, char *src, int len)
  260. {
  261. int data_pos;
  262. int cmd_step;
  263. int cmd_pos;
  264. char data[3] = {0,};
  265. cmd_step = 0;
  266. cmd_pos = 0;
  267. for (data_pos = 0; data_pos < len;) {
  268. /* skip comments*/
  269. while(*(src+data_pos++) != 0x0A) ;
  270. if(*(src + data_pos) == '0') {
  271. //Addr
  272. mdni_addr[cmd_pos] = char_to_dec(*(src + data_pos),*(src + data_pos + 1))<<8 | char_to_dec(*(src + data_pos + 2),*(src + data_pos + 3));
  273. data_pos += 5;
  274. if((*(src + data_pos) == '0') && (*(src + data_pos + 1) == 'x'))
  275. mdni_tuning_val[cmd_pos] = char_to_dec(*(src + data_pos+2),*(src + data_pos + 3));
  276. data_pos += 4;
  277. cmd_pos += 1;
  278. }
  279. }
  280. printk(KERN_INFO "\n");
  281. for (data_pos = 0; data_pos < MDNIE_TUNE_SIZE ; data_pos++)
  282. printk(KERN_INFO "0x%04x,0x%02x \n", mdni_addr[data_pos],mdni_tuning_val[data_pos]);
  283. printk(KERN_INFO "\n");
  284. //Send Tune Commands
  285. eeprom_i2c_write(info->client, mdni_addr, mdni_tuning_val, MDNIE_TUNE_SIZE);
  286. for(data_pos = 0;data_pos < cmd_pos ;data_pos++) {
  287. eeprom_i2c_read(info->client, mdni_addr[data_pos], data, 1);
  288. pr_info("0x%04x,0x%02x\n",mdni_addr[data_pos], data[0]);
  289. }
  290. }
  291. static void sending_tcon_tuen_cmd(struct edp_eeprom_info *info, char *src, int len)
  292. {
  293. int data_pos;
  294. int cmd_step;
  295. int cmd_pos;
  296. char data;
  297. u16 i2c_addr;
  298. u8 i2c_data;
  299. cmd_step = 0;
  300. cmd_pos = 0;
  301. for (data_pos = 0; data_pos < len;) {
  302. if(*(src + data_pos) == '0') {
  303. //Addr
  304. tcon_addr[cmd_pos] = char_to_dec(*(src + data_pos),*(src + data_pos + 1))<<8 | char_to_dec(*(src + data_pos + 2),*(src + data_pos + 3));
  305. data_pos += 5;
  306. if((*(src + data_pos) == '0') && (*(src + data_pos + 1) == 'x'))
  307. tcon_tuning_val[cmd_pos] = char_to_dec(*(src + data_pos+2),*(src + data_pos + 3));
  308. data_pos += 4;
  309. cmd_pos += 1;
  310. } else
  311. data_pos++;
  312. }
  313. pr_info("cmd_pos : %d", cmd_pos);
  314. for (data_pos = 0; data_pos < cmd_pos ; data_pos++)
  315. pr_info("0x%04x,0x%02x", tcon_addr[data_pos],tcon_tuning_val[data_pos]);
  316. //Send Tune Commands
  317. eeprom_i2c_write(info->client, tcon_addr, tcon_tuning_val, TCON_TUNE_SIZE);
  318. //Enable double bufferd regiset
  319. i2c_addr = 0x0F10; i2c_data = 0x80;
  320. eeprom_i2c_write(info->client, &i2c_addr, &i2c_data, 1);
  321. for(data_pos = 0;data_pos < cmd_pos ;data_pos++) {
  322. eeprom_i2c_read(info->client, tcon_addr[data_pos], &data, 1);
  323. pr_info("0x%04x,0x%02x\n",tcon_addr[data_pos], data);
  324. }
  325. }
  326. static void load_tuning_file(struct edp_eeprom_info *info, char *filename, int mdnie)
  327. {
  328. struct file *filp;
  329. char *dp;
  330. long l;
  331. loff_t pos;
  332. int ret;
  333. mm_segment_t fs;
  334. pr_info("%s called loading file name : [%s]\n", __func__,
  335. filename);
  336. fs = get_fs();
  337. set_fs(get_ds());
  338. filp = filp_open(filename, O_RDONLY, 0);
  339. if (IS_ERR(filp)) {
  340. printk(KERN_ERR "%s File open failed\n", __func__);
  341. goto err;
  342. }
  343. l = filp->f_path.dentry->d_inode->i_size;
  344. pr_info("%s Loading File Size : %ld(bytes)", __func__, l);
  345. dp = kmalloc(l + 10, GFP_KERNEL);
  346. if (dp == NULL) {
  347. pr_info("Can't not alloc memory for tuning file load\n");
  348. filp_close(filp, current->files);
  349. goto err;
  350. }
  351. pos = 0;
  352. memset(dp, 0, l);
  353. pr_info("%s before vfs_read()\n", __func__);
  354. ret = vfs_read(filp, (char __user *)dp, l, &pos);
  355. pr_info("%s after vfs_read()\n", __func__);
  356. if (ret != l) {
  357. pr_info("vfs_read() filed ret : %d\n", ret);
  358. kfree(dp);
  359. filp_close(filp, current->files);
  360. goto err;
  361. }
  362. filp_close(filp, current->files);
  363. set_fs(fs);
  364. if (get_edp_power_state()) {
  365. if (mdnie)
  366. sending_tune_cmd(info, dp, l);
  367. else
  368. sending_tcon_tuen_cmd(info, dp, l);
  369. } else
  370. pr_info("%s get_edp_power_state off", __func__);
  371. kfree(dp);
  372. return;
  373. err:
  374. set_fs(fs);
  375. }
  376. static ssize_t tuning_show(struct device *dev,
  377. struct device_attribute *attr, char *buf)
  378. {
  379. int ret = 0;
  380. ret = snprintf(buf, MAX_FILE_NAME, "Tunned File Name : %s\n",
  381. tuning_file);
  382. return ret;
  383. }
  384. static ssize_t tuning_store(struct device *dev,
  385. struct device_attribute *attr, const char *buf,
  386. size_t size)
  387. {
  388. char *pt;
  389. struct edp_eeprom_info *info;
  390. info = dev_get_drvdata(dev);
  391. memset(tuning_file, 0, sizeof(tuning_file));
  392. snprintf(tuning_file, MAX_FILE_NAME, "%s%s", TUNING_FILE_PATH, buf);
  393. pt = tuning_file;
  394. while (*pt) {
  395. if (*pt == '\r' || *pt == '\n') {
  396. *pt = 0;
  397. break;
  398. }
  399. pt++;
  400. }
  401. pr_info("%s:%s\n", __func__, tuning_file);
  402. load_tuning_file(info, tuning_file, 1);
  403. return size;
  404. }
  405. static DEVICE_ATTR(tuning, 0664, tuning_show, tuning_store);
  406. #endif
  407. #if defined(CONFIG_LCD_CLASS_DEVICE) && defined(DDI_VIDEO_ENHANCE_TUNING)
  408. static struct lcd_ops edp_samsung_disp_props = {
  409. .get_power = NULL,
  410. .set_power = NULL,
  411. };
  412. #endif
  413. int tcon_tune_value(struct edp_eeprom_info *pinfo)
  414. {
  415. int ret = 0;
  416. struct tcon_reg_info *tune_value;
  417. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  418. u16 i2c_addr;
  419. u8 i2c_data;
  420. mutex_lock(&edp_power_state_chagne);
  421. if (!get_edp_power_state()) {
  422. pr_info("%s get_edp_power_state off", __func__);
  423. mutex_unlock(&edp_power_state_chagne);
  424. return -EINVAL;
  425. }
  426. pr_info("%s [set tcon] : mode : %d, br : %d, lux : %d power_save_mode : %d", __func__,
  427. pdata->mode, pdata->auto_br, pdata->lux, pdata->power_save_mode);
  428. if (pdata->power_save_mode) {
  429. if (pdata->mode == 1 || pdata->mode == 2 || pdata->mode == 3)
  430. tune_value = power_save_tune_value[1][1][1]; /*TCON_VIDEO*/
  431. else if (pdata->mode == 8)
  432. tune_value = power_save_tune_value[1][1][8]; /*TCON_BROWSER*/
  433. else
  434. tune_value = power_save_tune_value[1][1][0]; /*TCON_POWER_SAVE*/
  435. } else
  436. tune_value = power_save_tune_value[pdata->auto_br][pdata->lux][pdata->mode];
  437. if (!tune_value) {
  438. pr_err("%s tcon value is null", __func__);
  439. mutex_unlock(&edp_power_state_chagne);
  440. return -EINVAL;
  441. }
  442. eeprom_i2c_write(pinfo->client, tune_value->addr, tune_value->data, tune_value->reg_cnt);
  443. //Enable double bufferd regiset
  444. i2c_addr = 0x0F10; i2c_data = 0x80;
  445. eeprom_i2c_write(pinfo->client, &i2c_addr, &i2c_data, 1);
  446. #if 0
  447. for(loop = 0; loop < tune_value->reg_cnt; loop++) {
  448. unsigned char val;
  449. eeprom_i2c_read(pinfo->client, tune_value->addr[loop], &val, 1);
  450. pr_info("%s read addr : 0x%x data : 0x%x", __func__, tune_value->addr[loop], val);
  451. }
  452. #endif
  453. mutex_unlock(&edp_power_state_chagne);
  454. tcon_pwm_duty(0, 0);
  455. return ret;
  456. }
  457. void restore_set_tcon(void)
  458. {
  459. if (global_pinfo) {
  460. tcon_init_setting();
  461. tcon_tune_value(global_pinfo);
  462. #if defined(CONFIG_EDP_TCON_MDNIE)
  463. update_mdnie_register();
  464. #endif
  465. }
  466. }
  467. void tcon_under_lowest_percentage_duty(void)
  468. {
  469. u16 i2c_addr[3];
  470. u8 i2c_data[3];
  471. mutex_lock(&edp_power_state_chagne);
  472. if (!get_edp_power_state()) {
  473. pr_info("%s get_edp_power_state off", __func__);
  474. mutex_unlock(&edp_power_state_chagne);
  475. return ;
  476. }
  477. if (global_pinfo && global_pinfo->client) {
  478. i2c_addr[0] = 0x0DB9; i2c_data[0] = 0x7F; /* under 20% parameter 1*/
  479. i2c_addr[1] = 0x0DBA; i2c_data[1] = 0xFF; /* under 20% parameter 2*/
  480. i2c_addr[2] = 0x0F10; i2c_data[2] = 0x80; /* Enable double bufferd regiset */
  481. eeprom_i2c_write(global_pinfo->client, i2c_addr, i2c_data, 3);
  482. }
  483. mutex_unlock(&edp_power_state_chagne);
  484. }
  485. void tcon_pwm_duty(int pwm_duty, int updata_from_backlight)
  486. {
  487. static int pre_duty = 100;
  488. static int lowest_pwm_duty = LOWEST_PWM_DUTY;
  489. if (updata_from_backlight) {
  490. if (pwm_duty < lowest_pwm_duty && pre_duty >= lowest_pwm_duty) {
  491. pre_duty = pwm_duty;
  492. tcon_under_lowest_percentage_duty();
  493. pr_info("%s pwm under 20%% duty ratio : %d backlight update : %d", __func__, pwm_duty, updata_from_backlight);
  494. } else if (pwm_duty >= lowest_pwm_duty && pre_duty < lowest_pwm_duty) {
  495. pre_duty = pwm_duty;
  496. tcon_tune_value(global_pinfo);
  497. pr_info("%s pwm over 20%% duty ratio : %d", __func__, pwm_duty);
  498. }
  499. } else {
  500. if (pre_duty < lowest_pwm_duty) {
  501. tcon_under_lowest_percentage_duty();
  502. pr_info("%s pwm under 20%% duty ratio : %d backlight update : %d", __func__, pwm_duty, updata_from_backlight);
  503. }
  504. }
  505. }
  506. static ssize_t disp_lcdtype_show(struct device *dev,
  507. struct device_attribute *attr, char *buf)
  508. {
  509. #if defined(CONFIG_MACH_VIENNA_LTE) || defined(CONFIG_MACH_V2LTEEUR)
  510. snprintf(buf, 30, "INH_LSL122DL01\n");
  511. #else // CONFIG_SEC_LT03_PROJECT
  512. snprintf(buf, 30, "INH_LSL101DL01\n");
  513. #endif
  514. return strnlen(buf, 30);
  515. }
  516. static DEVICE_ATTR(lcd_type, S_IRUGO, disp_lcdtype_show, NULL);
  517. static ssize_t auto_brightness_show(struct device *dev,
  518. struct device_attribute *attr, char *buf)
  519. {
  520. return 0;
  521. }
  522. static ssize_t auto_brightness_store(struct device *dev,
  523. struct device_attribute *attr, const char *buf, size_t size)
  524. {
  525. return size;
  526. }
  527. static DEVICE_ATTR(auto_brightness, S_IRUGO | S_IWUSR | S_IWGRP,
  528. auto_brightness_show, auto_brightness_store);
  529. static ssize_t show_lux(struct device *dev,
  530. struct device_attribute *dev_attr, char *buf)
  531. {
  532. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  533. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  534. return sprintf(buf, "%d\n", pdata->lux);
  535. }
  536. static ssize_t store_lux(struct device *dev,
  537. struct device_attribute *dev_attr,
  538. const char *buf, size_t count)
  539. {
  540. int ret;
  541. unsigned int value;
  542. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  543. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  544. ret = kstrtouint(buf, 10, &value);
  545. if (ret)
  546. return ret;
  547. if (value >= TCON_LEVEL_MAX) {
  548. dev_err(pdata->dev, "undefied tcon illumiate value : %d\n\n", value);
  549. return count;
  550. }
  551. if (value != pdata->lux) {
  552. pdata->lux = value;
  553. ret = tcon_tune_value(pinfo);
  554. if (ret)
  555. dev_err(pdata->dev, "failed to tune tcon\n");
  556. }
  557. return count;
  558. }
  559. static DEVICE_ATTR(lux, 0664, show_lux, store_lux);
  560. static ssize_t show_mode(struct device *dev,
  561. struct device_attribute *dev_attr, char *buf)
  562. {
  563. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  564. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  565. return sprintf(buf, "%d\n", pdata->mode);
  566. }
  567. static ssize_t store_mode(struct device *dev,
  568. struct device_attribute *dev_attr,
  569. const char *buf, size_t count)
  570. {
  571. int ret;
  572. unsigned int value;
  573. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  574. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  575. ret = kstrtouint(buf, 10, &value);
  576. if (ret)
  577. return ret;
  578. if (value >= TCON_MODE_MAX) {
  579. dev_err(pdata->dev, "undefied tcon mode value : %d\n\n", value);
  580. return count;
  581. }
  582. if (value != pdata->mode) {
  583. pdata->mode = value;
  584. ret = tcon_tune_value(pinfo);
  585. if (ret)
  586. dev_err(pdata->dev, "failed to tune tcon\n");
  587. }
  588. return count;
  589. }
  590. static DEVICE_ATTR(mode, 0664, show_mode, store_mode);
  591. static ssize_t show_auto_br(struct device *dev,
  592. struct device_attribute *dev_attr, char *buf)
  593. {
  594. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  595. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  596. return sprintf(buf, "%d\n", pdata->auto_br);
  597. }
  598. static ssize_t store_auto_br(struct device *dev,
  599. struct device_attribute *dev_attr,
  600. const char *buf, size_t count)
  601. {
  602. int ret;
  603. unsigned int value;
  604. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  605. struct edp_eeprom_platform_data *pdata = pinfo->pdata;
  606. ret = kstrtouint(buf, 10, &value);
  607. if (ret)
  608. return ret;
  609. if (value >= TCON_AUTO_BR_MAX) {
  610. dev_err(pdata->dev, "undefied tcon auto br value : %d\n\n", value);
  611. return count;
  612. }
  613. if (value != pdata->auto_br) {
  614. pdata->auto_br = value;
  615. ret = tcon_tune_value(pinfo);
  616. if (ret)
  617. dev_err(pdata->dev, "failed to tune tcon\n");
  618. }
  619. return count;
  620. }
  621. static DEVICE_ATTR(auto_br, 0664, show_auto_br, store_auto_br);
  622. static ssize_t store_black_test(struct device *dev,
  623. struct device_attribute *dev_attr,
  624. const char *buf, size_t count)
  625. {
  626. int value;
  627. u16 i2c_addr;
  628. u8 i2c_data;
  629. struct edp_eeprom_info *pinfo = dev_get_drvdata(dev);
  630. sscanf(buf, "%d", &value);
  631. if (value) {
  632. mutex_lock(&edp_power_state_chagne);
  633. if (!get_edp_power_state()) {
  634. pr_info("%s get_edp_power_state off", __func__);
  635. mutex_unlock(&edp_power_state_chagne);
  636. return -EAGAIN;
  637. }
  638. eeprom_i2c_write(pinfo->client, TCON_BLACK_IMAGE_BLU_ENABLE.addr,
  639. TCON_BLACK_IMAGE_BLU_ENABLE.data, TCON_BLACK_IMAGE_BLU_ENABLE.reg_cnt);
  640. //Enable double bufferd regiset
  641. i2c_addr = 0x0F10; i2c_data = 0x80;
  642. eeprom_i2c_write(pinfo->client, &i2c_addr, &i2c_data, 1);
  643. mutex_unlock(&edp_power_state_chagne);
  644. } else {
  645. tcon_tune_value(pinfo);
  646. }
  647. pr_info("%s value : %d", __func__, value);
  648. return count;
  649. }
  650. static DEVICE_ATTR(black_test, 0664, NULL, store_black_test);
  651. #if defined(CONFIG_FB_MSM_EDP_SAMSUNG)
  652. int config_cabc(int power_save_mode)
  653. {
  654. if (!global_pinfo)
  655. pr_info("%s global_pinfo is NULL", __func__);
  656. global_pinfo->pdata->power_save_mode = power_save_mode;
  657. tcon_tune_value(global_pinfo);
  658. return 0;
  659. }
  660. int config_i2c_lane(int enable)
  661. {
  662. if (!global_pinfo) {
  663. pr_info("%s global_pinfo is NULL", __func__);
  664. return -ENOMEM;
  665. }
  666. if (enable) {
  667. gpio_request(global_pinfo->pdata->gpio_scl, "edp_scl");
  668. gpio_request(global_pinfo->pdata->gpio_sda, "edp_sda");
  669. } else {
  670. gpio_free(global_pinfo->pdata->gpio_scl);
  671. gpio_free(global_pinfo->pdata->gpio_sda);
  672. }
  673. return 0;
  674. }
  675. #endif
  676. #if defined(DDI_VIDEO_ENHANCE_TUNING)
  677. static ssize_t store_tcon_test(struct device *dev,
  678. struct device_attribute *dev_attr,
  679. const char *buf, size_t count)
  680. {
  681. char *pt;
  682. struct edp_eeprom_info *info;
  683. info = dev_get_drvdata(dev);
  684. memset(tuning_file, 0, sizeof(tuning_file));
  685. snprintf(tuning_file, MAX_FILE_NAME, "%s%s", TUNING_FILE_PATH, buf);
  686. pt = tuning_file;
  687. while (*pt) {
  688. if (*pt == '\r' || *pt == '\n') {
  689. *pt = 0;
  690. break;
  691. }
  692. pt++;
  693. }
  694. pr_info("%s:%s\n", __func__, tuning_file);
  695. load_tuning_file(info, tuning_file, 0);
  696. return count;
  697. }
  698. static DEVICE_ATTR(tcon_test, 0664, NULL, store_tcon_test);
  699. #endif
  700. static struct attribute *sysfs_attributes[] = {
  701. &dev_attr_lux.attr,
  702. &dev_attr_mode.attr,
  703. &dev_attr_auto_br.attr,
  704. &dev_attr_black_test.attr,
  705. #ifdef DDI_VIDEO_ENHANCE_TUNING
  706. &dev_attr_tcon_test.attr,
  707. #endif
  708. NULL
  709. };
  710. static const struct attribute_group sysfs_group = {
  711. .attrs = sysfs_attributes,
  712. };
  713. static int edp_eeprom_parse_dt(struct device *dev,
  714. struct edp_eeprom_platform_data *pdata)
  715. {
  716. struct device_node *np = dev->of_node;
  717. /* reset, irq gpio info */
  718. pdata->gpio_scl = of_get_named_gpio_flags(np, "edp,scl-gpio",
  719. 0, &pdata->scl_gpio_flags);
  720. pdata->gpio_sda = of_get_named_gpio_flags(np, "edp,sda-gpio",
  721. 0, &pdata->sda_gpio_flags);
  722. pr_info("%s gpio_scl : %d , gpio_sda : %d", __func__, pdata->gpio_scl, pdata->gpio_sda);
  723. return 0;
  724. }
  725. static int __devinit edp_eeprom_probe(struct i2c_client *client,
  726. const struct i2c_device_id *id)
  727. {
  728. struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
  729. struct edp_eeprom_platform_data *pdata;
  730. struct edp_eeprom_info *info;
  731. int error;
  732. int ret = 0;
  733. #if defined(CONFIG_LCD_CLASS_DEVICE) && defined(DDI_VIDEO_ENHANCE_TUNING)
  734. struct lcd_device *lcd_device;
  735. struct backlight_device *bd = NULL;
  736. #endif
  737. pr_info("%s", __func__);
  738. if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
  739. return -EIO;
  740. if (client->dev.of_node) {
  741. pdata = devm_kzalloc(&client->dev,
  742. sizeof(struct edp_eeprom_platform_data),
  743. GFP_KERNEL);
  744. if (!pdata) {
  745. dev_info(&client->dev, "Failed to allocate memory\n");
  746. return -ENOMEM;
  747. }
  748. error = edp_eeprom_parse_dt(&client->dev, pdata);
  749. if (error)
  750. return error;
  751. } else
  752. pdata = client->dev.platform_data;
  753. eeprom_request_gpio_slave(pdata);
  754. global_pinfo = info = kzalloc(sizeof(*info), GFP_KERNEL);
  755. if (!info) {
  756. dev_info(&client->dev, "%s: fail to memory allocation.\n", __func__);
  757. goto return_pdata_free;
  758. }
  759. info->client = client;
  760. info->pdata = pdata;
  761. i2c_set_clientdata(client, info);
  762. #if defined(CONFIG_LCD_CLASS_DEVICE) && defined(DDI_VIDEO_ENHANCE_TUNING)
  763. lcd_device = lcd_device_register("panel", &client->dev, info,
  764. &edp_samsung_disp_props);
  765. if (IS_ERR(lcd_device)) {
  766. ret = PTR_ERR(lcd_device);
  767. printk(KERN_ERR "lcd : failed to register device\n");
  768. return ret;
  769. }
  770. ret = sysfs_create_file(&lcd_device->dev.kobj,
  771. &dev_attr_lcd_type.attr);
  772. if (ret) {
  773. pr_info("sysfs create fail-%s\n",
  774. dev_attr_lcd_type.attr.name);
  775. }
  776. ret = sysfs_create_file(&lcd_device->dev.kobj,
  777. &dev_attr_tuning.attr);
  778. if (ret) {
  779. pr_info("sysfs create fail-%s\n",
  780. dev_attr_tuning.attr.name);
  781. }
  782. bd = backlight_device_register("panel", &lcd_device->dev,
  783. NULL, NULL, NULL);
  784. if (IS_ERR(bd)) {
  785. ret = PTR_ERR(bd);
  786. pr_info("backlight : failed to register device\n");
  787. return ret;
  788. }
  789. ret = sysfs_create_file(&bd->dev.kobj,
  790. &dev_attr_auto_brightness.attr);
  791. if (ret) {
  792. pr_info("sysfs create fail-%s\n",
  793. dev_attr_auto_brightness.attr.name);
  794. }
  795. #endif
  796. pdata->mode = 0; /* basic */
  797. pdata->lux = 0;
  798. pdata->auto_br = 0;
  799. pdata->power_save_mode = 0;
  800. tcon_class = class_create(THIS_MODULE, "tcon");
  801. if (IS_ERR(tcon_class)) {
  802. dev_err(&client->dev, "Failed to create class for TCON\n");
  803. goto return_mem_free;
  804. }
  805. pdata->dev = device_create(tcon_class,\
  806. NULL, 0, pdata, "tcon");
  807. if (IS_ERR(pdata->dev)) {
  808. dev_err(&client->dev, "Failed to create device for TCON\n");
  809. goto return_class_remove;
  810. }
  811. ret = sysfs_create_group(&pdata->dev->kobj, &sysfs_group);
  812. if (ret) {
  813. dev_err(&client->dev, "Failed to create sysfs for TCON\n");
  814. goto return_sysfs_remove;
  815. }
  816. dev_set_drvdata(pdata->dev, info);
  817. return error;
  818. return_sysfs_remove:
  819. device_destroy(tcon_class, 0);
  820. return_class_remove:
  821. class_destroy(tcon_class);
  822. return_mem_free:
  823. kfree(info);
  824. return_pdata_free:
  825. kfree(pdata);
  826. return ret;
  827. }
  828. static int __devexit edp_eeprom_remove(struct i2c_client *client)
  829. {
  830. return 0;
  831. }
  832. static const struct i2c_device_id edp_eeprom_id[] = {
  833. {"edp_eeprom", 0},
  834. {}
  835. };
  836. MODULE_DEVICE_TABLE(i2c, edp_eeprom_id);
  837. static struct of_device_id edp_eeprom_match_table[] = {
  838. { .compatible = "edp,eeprom-control",},
  839. { },
  840. };
  841. MODULE_DEVICE_TABLE(of, edp_eeprom_match_table);
  842. struct i2c_driver edp_eeprom_driver = {
  843. .probe = edp_eeprom_probe,
  844. .remove = edp_eeprom_remove,
  845. .driver = {
  846. .name = "edp_eeprom",
  847. .owner = THIS_MODULE,
  848. .of_match_table = edp_eeprom_match_table,
  849. },
  850. .id_table = edp_eeprom_id,
  851. };
  852. static int __init edp_eeprom_init(void)
  853. {
  854. int ret = 0;
  855. pr_info("%s", __func__);
  856. ret = i2c_add_driver(&edp_eeprom_driver);
  857. if (ret) {
  858. printk(KERN_ERR "edp_eeprom_init registration failed. ret= %d\n",
  859. ret);
  860. }
  861. return ret;
  862. }
  863. static void __exit edp_eeprom_exit(void)
  864. {
  865. pr_info("%s", __func__);
  866. i2c_del_driver(&edp_eeprom_driver);
  867. }
  868. module_init(edp_eeprom_init);
  869. module_exit(edp_eeprom_exit);
  870. MODULE_DESCRIPTION("edp eeprom driver");
  871. MODULE_LICENSE("GPL");