PageRenderTime 82ms CodeModel.GetById 46ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/video/backlight/hub_aat2862.c

http://github.com/CyanogenMod/lge-kernel-sniper
C | 807 lines | 595 code | 158 blank | 54 comment | 41 complexity | 27f85780727a5c9b60f37930253408d9 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1. /* drivers/video/backlight/e920_aat2862.c
  2. *
  3. * Copyright (C) 2010 LGE, Inc
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/platform_device.h>
  16. #include <linux/module.h>
  17. #include <linux/device.h>
  18. #include <linux/delay.h>
  19. #include <linux/backlight.h>
  20. #include <linux/fb.h>
  21. #include <linux/i2c.h>
  22. #include <linux/string.h>
  23. #include <asm/system.h>
  24. #include <mach/hardware.h>
  25. #include <mach/gpio.h>
  26. #include <plat/mux.h>
  27. #include <linux/leds.h>
  28. #include <plat/board.h>
  29. #include <linux/earlysuspend.h>
  30. #include <linux/i2c/twl.h>
  31. #define TWL_LEDA (OMAP_MAX_GPIO_LINES + TWL4030_GPIO_MAX)
  32. #define RGB_LED_CNTL 128
  33. static unsigned touch_key_bl_gpio;
  34. extern unsigned int system_rev;
  35. #define SEND_SC654_SPIF_ADDR(d) do {\
  36. int len = d;\
  37. gpio_set_value(touch_key_bl_gpio, 0);\
  38. udelay(1);\
  39. while(len--) {\
  40. gpio_set_value(touch_key_bl_gpio, 1);\
  41. udelay(1);\
  42. gpio_set_value(touch_key_bl_gpio, 0);\
  43. udelay(1);\
  44. }\
  45. gpio_set_value(touch_key_bl_gpio, 1);\
  46. udelay(560);\
  47. } while(0)
  48. #define SEND_SC654_SPIF_DATA(d) SEND_SC654_SPIF_ADDR(d)
  49. #define TOUCH_KEY_BL_INIT() do {\
  50. if(system_rev >= 2) {\
  51. touch_key_bl_gpio = RGB_LED_CNTL;\
  52. } else {\
  53. touch_key_bl_gpio = TWL_LEDA;\
  54. }\
  55. if (0 > gpio_request(touch_key_bl_gpio, "touch_keybl"))\
  56. printk (KERN_ERR "touch_keybl gpio_request failed\n");\
  57. if(system_rev >= 2) {\
  58. gpio_direction_output(touch_key_bl_gpio, 1);\
  59. mdelay(1);\
  60. }\
  61. } while(0)
  62. #define TOUCH_KEY_BL_ON() do {\
  63. if(system_rev >= 2) {\
  64. /*fade on*/\
  65. /*SEND_SC654_SPIF_ADDR(4);*/\
  66. /*SEND_SC654_SPIF_DATA(0);*/\
  67. /*SEND_SC654_SPIF_ADDR(1);*/\
  68. /*SEND_SC654_SPIF_DATA(4);*/\
  69. /*SEND_SC654_SPIF_ADDR(4);*/\
  70. /*SEND_SC654_SPIF_DATA(1);*/\
  71. /*led on*/\
  72. SEND_SC654_SPIF_ADDR(0);\
  73. SEND_SC654_SPIF_DATA(0x1f);\
  74. SEND_SC654_SPIF_ADDR(1);\
  75. SEND_SC654_SPIF_DATA(0xd);/*red*/\
  76. SEND_SC654_SPIF_ADDR(2);\
  77. SEND_SC654_SPIF_DATA(0x12);/*green*/\
  78. SEND_SC654_SPIF_ADDR(3);\
  79. SEND_SC654_SPIF_DATA(0x12);/*blue*/\
  80. } else {\
  81. gpio_set_value(touch_key_bl_gpio, 0);\
  82. }\
  83. } while(0)
  84. #define TOUCH_KEY_BL_OFF() do {\
  85. if(system_rev >= 2) {\
  86. /*fade enable*/\
  87. /*SEND_SC654_SPIF_ADDR(4);*/\
  88. /*SEND_SC654_SPIF_DATA(1);*/\
  89. /*led off*/\
  90. SEND_SC654_SPIF_ADDR(0);\
  91. SEND_SC654_SPIF_DATA(0);\
  92. } else {\
  93. gpio_set_value(touch_key_bl_gpio, 1);\
  94. }\
  95. } while(0)
  96. static struct i2c_client *aat2862_i2c_client;
  97. #define I2C_NO_REG 0xFF
  98. #define MAX_BRIGHTNESS 0x15 // 0000 1010 = 20.32mA
  99. #define DEFAULT_BRIGHTNESS 0x0D // 0000 1101 = 12.58mA
  100. #define MODULE_NAME "hub_aat2862"
  101. #define BL_ON 1
  102. #define BL_OFF 0
  103. #define MAX_LDO_REG 8
  104. static u8 mirror_reg[MAX_LDO_REG] = {0,};
  105. struct aat2862_device {
  106. struct i2c_client *client;
  107. struct backlight_device *bl_dev;
  108. struct early_suspend early_suspend;
  109. };
  110. struct bl_ctrl_data {
  111. unsigned short reg;
  112. unsigned short val;
  113. };
  114. #ifdef CONFIG_HAS_EARLYSUSPEND
  115. static void aat2862_early_suspend(struct early_suspend *h);
  116. static void aat2862_late_resume(struct early_suspend *h);
  117. static int early_bl_timer = 1;
  118. static int early_bl_value = 0;
  119. #endif
  120. #define LCD_CP_EN 62
  121. #define HUB_I2C_BL_NAME "hub_i2c_bl"
  122. #define LDO_AB_LEVEL_REG 0x24
  123. #define LDO_CD_LEVEL_REG 0x25
  124. #define LDO_ABCD_EN_REG 0x26
  125. static const struct i2c_device_id hub_bl_id[] = {
  126. { HUB_I2C_BL_NAME, 0 },
  127. //{ }
  128. { },
  129. };
  130. static int aat2862_write_reg(struct i2c_client *client, unsigned char reg, unsigned char val);
  131. static int aat2862_read_reg(struct i2c_client *client, unsigned char reg, unsigned char *ret);
  132. unsigned int cur_main_lcd_level = DEFAULT_BRIGHTNESS;
  133. static unsigned int saved_main_lcd_level = DEFAULT_BRIGHTNESS;
  134. #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
  135. static int backlight_status = BL_ON;
  136. #else
  137. static int backlight_status = BL_OFF;
  138. #endif
  139. static struct aat2862_device *main_aat2862_dev = NULL;
  140. #if 0
  141. static struct bl_ctrl_data pwron_seq[]=
  142. {
  143. #if defined(CONFIG_MACH_LGE_HUB_REV_A)
  144. {LDO_AB_LEVEL_REG,0x4A}, /* LDOA 1.8V_LCD_IOVCC(0100), LDOB 2.8V_LCD_VCC_VCI (1010) */
  145. {LDO_CD_LEVEL_REG,0xAA}, /* LDOC 2.8V_TOUCH_VDD (1010), LDOD 2.8V_TOUCH_VCPIN (1010) */
  146. #else
  147. {LDO_AB_LEVEL_REG,0x4C}, /* LDOA 1.8V_LCD_IOVCC(0100), LDOB 3.0V_LCD_VCC_VCI (1100) */
  148. {LDO_CD_LEVEL_REG,0x4C}, /* LDOC 1.8V_TOUCH_VDD (0100), LDOD 3.0V_TOUCH_VCPIN (1100) */
  149. #endif
  150. //{LDO_ABCD_EN_REG, 0x01}, //Enable all LDOs
  151. {LDO_ABCD_EN_REG, 0x0F}, //Enable all LDOs
  152. //{0x03, 0xFF-DEFAULT_BRIGHTNESS}, // Main BL ctrl.
  153. //{0x04, 0x7F-DEFAULT_BRIGHTNESS}, // Sub BL ctrl.
  154. //{0x05, 0x7F-DEFAULT_BRIGHTNESS}, // Aux1 BL ctrl.
  155. //{0x06, 0x7F-DEFAULT_BRIGHTNESS}, // Aux2 BL ctrl.
  156. {I2C_NO_REG, 0x00} /* End of array */
  157. };
  158. #endif
  159. void aat2862_hreset(void)
  160. {
  161. gpio_set_value(LCD_CP_EN, 1);
  162. udelay(10);
  163. gpio_set_value(LCD_CP_EN, 0);
  164. udelay(1000);
  165. gpio_set_value(LCD_CP_EN, 1);
  166. udelay(10);
  167. }
  168. static int aat2862_write_reg(struct i2c_client *client, unsigned char reg, unsigned char val)
  169. {
  170. int err;
  171. u8 buf[2];
  172. struct i2c_msg msg = {
  173. client->addr, 0, 2, buf
  174. };
  175. buf[0] = reg;
  176. buf[1] = val;
  177. if ((err = i2c_transfer(client->adapter, &msg, 1)) < 0) {
  178. dev_err(&client->dev, "i2c write error\n");
  179. }
  180. return 0;
  181. }
  182. static int aat2862_read_reg(struct i2c_client *client, unsigned char reg, unsigned char *ret)
  183. {
  184. int err;
  185. unsigned char buf = reg;
  186. struct i2c_msg msg[2] = {
  187. { client->addr, 0, 1, &buf },
  188. { client->addr, I2C_M_RD, 1, ret}
  189. };
  190. if ((err = i2c_transfer(client->adapter, msg, 2)) < 0) {
  191. dev_err(&client->dev, "i2c read error\n");
  192. }
  193. return 0;
  194. }
  195. void aat2862_init(struct i2c_client *client)
  196. {
  197. //unsigned i;
  198. gpio_request(LCD_CP_EN, "lcd bl");
  199. gpio_direction_output(LCD_CP_EN, 1);
  200. aat2862_hreset();
  201. #if 0
  202. for (i = 0; pwron_seq[i].reg != I2C_NO_REG; i++) {
  203. aat2862_write_reg(client, pwron_seq[i].reg, pwron_seq[i].val);
  204. mdelay(10);
  205. }
  206. backlight_status = BL_ON;
  207. #endif
  208. }
  209. void aat2862_ldo_enable(unsigned char num, int enable)
  210. {
  211. unsigned char org;
  212. aat2862_read_reg(aat2862_i2c_client, LDO_ABCD_EN_REG, &org);
  213. if(enable)
  214. {
  215. aat2862_write_reg(aat2862_i2c_client, LDO_ABCD_EN_REG, org | (1<< num));
  216. }
  217. else
  218. {
  219. aat2862_write_reg(aat2862_i2c_client, LDO_ABCD_EN_REG, org & ~(1<<num));
  220. }
  221. }
  222. EXPORT_SYMBOL(aat2862_ldo_enable);
  223. static void aat2862_ldo_read(u8 reg , u8 *val)
  224. {
  225. if (reg < 0 || reg > MAX_LDO_REG - 1)
  226. {
  227. printk("[LDO] Hub ldo invalid register access\n");
  228. return;
  229. }
  230. *val = i2c_smbus_read_byte_data(aat2862_i2c_client, reg);
  231. printk("[LDO] ldo Reg read 0x%X: Val=0x%X\n", (u8)reg, (u8)*val);
  232. }
  233. static int aat2862_ldo_write(u8 reg , u8 val)
  234. {
  235. int ret = -1 ;
  236. if (reg < 0 || reg > MAX_LDO_REG - 1)
  237. {
  238. printk("[LDO] Hub ldo invalid register access\n");
  239. return ret;
  240. }
  241. ret = i2c_smbus_write_byte_data(aat2862_i2c_client, reg , val);
  242. if(ret >= 0)
  243. {
  244. mirror_reg[reg] = val;
  245. printk("[LDO] Hub ldo Write Reg. = 0x%X, Value 0x%X\n", reg, val);
  246. }
  247. return ret;
  248. }
  249. static inline int aat2862_clear_n_set(u8 clear, u8 set, u8 reg)
  250. {
  251. int ret;
  252. u8 val = 0;
  253. /* Gets the initial register value */
  254. aat2862_ldo_read(reg, &val);
  255. /* Clearing all those bits to clear */
  256. val &= ~(clear);
  257. /* Setting all those bits to set */
  258. val |= set;
  259. /* Update the register */
  260. ret = aat2862_ldo_write(reg, val);
  261. if (ret)
  262. return ret;
  263. return 0;
  264. }
  265. /*
  266. Bit3 Bit2 Bit1 Bit0 VLDO(V)
  267. 0 0 0 0 1.2
  268. 0 0 0 1 1.3
  269. 0 0 1 0 1.5
  270. 0 0 1 1 1.6
  271. 0 1 0 0 1.8
  272. 0 1 0 1 2.0
  273. 0 1 1 0 2.2
  274. 0 1 1 1 2.5
  275. 1 0 0 0 2.6
  276. 1 0 0 1 2.7
  277. 1 0 1 0 2.8
  278. 1 0 1 1 2.9
  279. 1 1 0 0 3.0
  280. 1 1 0 1 3.1
  281. 1 1 1 0 3.2
  282. 1 1 1 1 3.3
  283. */
  284. typedef enum
  285. {
  286. VLDO_1_2V, /* 0 */
  287. VLDO_1_3V,
  288. VLDO_1_5V,
  289. VLDO_1_6V,
  290. VLDO_1_8V,
  291. VLDO_2_0V, /* 5 */
  292. VLDO_2_2V,
  293. VLDO_2_5V,
  294. VLDO_2_6V,
  295. VLDO_2_7V,
  296. VLDO_2_8V, /* 10 */
  297. VLDO_2_9V,
  298. VLDO_3_0V,
  299. VLDO_3_1V,
  300. VLDO_3_2V,
  301. VLDO_3_3V, /* 15 */
  302. VLDO_MAX, /* 16 */
  303. } AAT2862_VLDO;
  304. typedef enum
  305. {
  306. ENLDO_A, /* 0 */
  307. ENLDO_B,
  308. ENLDO_C,
  309. ENLDO_D,
  310. ENLDO_MAX, /* 5 */
  311. } AAT2862_ENLDO;
  312. void aat2862_set_ldo(bool enable, AAT2862_ENLDO ldo_num, AAT2862_VLDO level)
  313. {
  314. // if(!is_enabled)
  315. return;
  316. if(enable)
  317. {
  318. switch(ldo_num)
  319. {
  320. case ENLDO_A:
  321. aat2862_ldo_write(LDO_AB_LEVEL_REG, level<<4);
  322. break;
  323. case ENLDO_B:
  324. aat2862_ldo_write(LDO_AB_LEVEL_REG, level);
  325. break;
  326. case ENLDO_C:
  327. aat2862_ldo_write(LDO_CD_LEVEL_REG, level<<4);
  328. break;
  329. case ENLDO_D:
  330. aat2862_ldo_write(LDO_CD_LEVEL_REG, level);
  331. break;
  332. default:
  333. printk("[LDO] Hub ldo invalid register access\n");
  334. return;
  335. }
  336. aat2862_clear_n_set(0, 1<<ldo_num, LDO_ABCD_EN_REG);
  337. }
  338. else
  339. {
  340. aat2862_clear_n_set(1<<ldo_num, 0, LDO_ABCD_EN_REG);
  341. }
  342. }
  343. EXPORT_SYMBOL(aat2862_set_ldo);
  344. static void aat2862_touch_ldo_enable(struct i2c_client *client, int on)
  345. {
  346. #if 0
  347. aat2862_set_ldo(1, ENLDO_D, VLDO_3_0V);
  348. msleep(1);
  349. aat2862_set_ldo(1, ENLDO_C, VLDO_1_8V);
  350. #endif
  351. if(on)
  352. {
  353. aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x0B);
  354. mdelay(5);
  355. aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x0F);
  356. }
  357. else
  358. {
  359. aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x0B);
  360. mdelay(5);
  361. aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x03);
  362. }
  363. // printk(KERN_WARNING"[!] %s()\n", __func__);
  364. }
  365. static void aat2862_set_main_current_level(struct i2c_client *client, int level)
  366. {
  367. struct aat2862_device *dev;
  368. unsigned char val;
  369. dev = (struct aat2862_device *)i2c_get_clientdata(client);
  370. cur_main_lcd_level = level;
  371. dev->bl_dev->props.brightness = cur_main_lcd_level;
  372. aat2862_write_reg(client, 0x0,0xff); /* LCD channel enable */
  373. val = 0xFF - level;
  374. //val = 0xC0 | (backlight_status<<5) | level;
  375. aat2862_write_reg(client, 0x03, val);
  376. if(level > 0x3F){
  377. val = 0;
  378. }else{
  379. val = 0x3F - level;
  380. }
  381. aat2862_write_reg(client, 0x04, val);
  382. aat2862_write_reg(client, 0x05, val);
  383. aat2862_write_reg(client, 0x06, val);
  384. mdelay(1);
  385. }
  386. static void leds_brightness_set(struct led_classdev *led_cdev, enum led_brightness value)
  387. {
  388. value = value/12;
  389. if (value > MAX_BRIGHTNESS)
  390. value = MAX_BRIGHTNESS;
  391. if(early_bl_timer == 0)
  392. {
  393. early_bl_value = value;
  394. return;
  395. }
  396. aat2862_set_main_current_level(aat2862_i2c_client, value);
  397. cur_main_lcd_level = value;
  398. return;
  399. }
  400. static struct led_classdev lcd_backlight = {
  401. .name = "lcd-backlight",
  402. .brightness = MAX_BRIGHTNESS,
  403. .brightness_set = leds_brightness_set,
  404. };
  405. void aat2862_backlight_on(void)
  406. {
  407. printk("%s received (prev backlight_status: %s)\n", __func__, backlight_status?"ON":"OFF");
  408. if (backlight_status == BL_ON) return;
  409. TOUCH_KEY_BL_ON();
  410. //aat2862_set_main_current_level(main_aat2862_dev->client, DEFAULT_BRIGHTNESS);
  411. aat2862_set_main_current_level(main_aat2862_dev->client, early_bl_value);
  412. backlight_status = BL_ON;
  413. return;
  414. }
  415. EXPORT_SYMBOL(aat2862_backlight_on);
  416. void aat2862_backlight_off(void)
  417. {
  418. if (backlight_status == BL_OFF) return;
  419. saved_main_lcd_level = cur_main_lcd_level;
  420. aat2862_set_main_current_level(main_aat2862_dev->client, 0);
  421. backlight_status = BL_OFF;
  422. TOUCH_KEY_BL_OFF();
  423. return;
  424. }
  425. EXPORT_SYMBOL(aat2862_backlight_off);
  426. static int hub_bl_set_intensity(struct backlight_device *bd)
  427. {
  428. struct i2c_client *client = to_i2c_client(bd->dev.parent);
  429. aat2862_set_main_current_level(client, bd->props.brightness);
  430. cur_main_lcd_level = bd->props.brightness;
  431. return 0;
  432. }
  433. static int hub_bl_get_intensity(struct backlight_device *bd)
  434. {
  435. struct i2c_client *client = to_i2c_client(bd->dev.parent);
  436. unsigned char val=0;
  437. aat2862_read_reg(client, 0x03, &val);
  438. val &= 0x1f;
  439. return (int)val;
  440. }
  441. ssize_t lcd_backlight_show_level(struct device *dev, struct device_attribute *attr, char *buf)
  442. {
  443. int r;
  444. r = snprintf(buf, PAGE_SIZE, "LCD Backlight Level is : %d\n", cur_main_lcd_level);
  445. return r;
  446. }
  447. ssize_t lcd_backlight_store_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  448. {
  449. int level;
  450. struct i2c_client *client = to_i2c_client(dev);
  451. if (!count)
  452. return -EINVAL;
  453. level = simple_strtoul(buf, NULL, 10);
  454. if (level > MAX_BRIGHTNESS)
  455. level = MAX_BRIGHTNESS;
  456. aat2862_set_main_current_level(client, level);
  457. cur_main_lcd_level = level;
  458. return count;
  459. }
  460. static int aat2862_bl_resume(struct i2c_client *client);
  461. static int aat2862_bl_suspend(struct i2c_client *client, pm_message_t state);
  462. ssize_t lcd_backlight_show_on_off(struct device *dev, struct device_attribute *attr, char *buf)
  463. {
  464. int r;
  465. r = snprintf(buf, PAGE_SIZE, "%d\n", backlight_status);
  466. //printk("%s received (prev backlight_status: %s)\n", __func__, backlight_status?"ON":"OFF");
  467. return r;
  468. }
  469. ssize_t lcd_backlight_store_on_off(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  470. {
  471. int on_off;
  472. struct i2c_client *client = to_i2c_client(dev);
  473. if (!count)
  474. return -EINVAL;
  475. printk("%s received (prev backlight_status: %s)\n", __func__, backlight_status?"ON":"OFF");
  476. on_off = simple_strtoul(buf, NULL, 10);
  477. printk(KERN_ERR "%d",on_off);
  478. if(on_off == 1){
  479. early_bl_value=DEFAULT_BRIGHTNESS;
  480. aat2862_bl_resume(client);
  481. }else if(on_off == 0)
  482. aat2862_bl_suspend(client, PMSG_SUSPEND);
  483. return count;
  484. }
  485. ssize_t gpio_test_show(struct device *dev, struct device_attribute *attr, char *buf)
  486. {
  487. int r;
  488. printk("gpio_test_show");
  489. return r;
  490. }
  491. ssize_t gpio_test_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  492. {
  493. int num_gpio, num_direction, num_value;
  494. char *last;
  495. struct i2c_client *client = to_i2c_client(dev);
  496. if (!count)
  497. return -EINVAL;
  498. num_gpio = simple_strtoul(buf, &last, 10);
  499. ++last;
  500. num_direction = simple_strtoul(last, &last, 10);
  501. ++last;
  502. num_value = simple_strtoul(last, &last, 10);
  503. printk("gpio_test num_gpio = %d num_direction = %d num_value=%d \n",num_gpio, num_direction, num_value);
  504. if((1) && (num_direction==0 ||num_direction==1)&& (num_direction==0 ||num_direction==1) )
  505. {
  506. gpio_direction_output(num_gpio, num_direction);
  507. gpio_set_value(num_gpio, num_value);
  508. }
  509. else
  510. printk("wrong number!!!!!!!!!!!\n");
  511. return count;
  512. }
  513. DEVICE_ATTR(level, 0664, lcd_backlight_show_level, lcd_backlight_store_level);
  514. DEVICE_ATTR(backlight_on_off, 0666, lcd_backlight_show_on_off, lcd_backlight_store_on_off);
  515. DEVICE_ATTR(gpio_test, 0666, gpio_test_show, gpio_test_store);
  516. static struct backlight_ops hub_bl_ops = {
  517. .update_status = hub_bl_set_intensity,
  518. .get_brightness = hub_bl_get_intensity,
  519. };
  520. static int __init aat2862_probe(struct i2c_client *i2c_dev, const struct i2c_device_id *id)
  521. {
  522. struct aat2862_device *dev;
  523. struct backlight_device *bl_dev;
  524. int err;
  525. printk(KERN_INFO"%s: i2c probe start\n", __func__);
  526. aat2862_i2c_client = i2c_dev;
  527. dev = kzalloc(sizeof(struct aat2862_device), GFP_KERNEL);
  528. if(dev == NULL) {
  529. dev_err(&i2c_dev->dev,"fail alloc for aat2862_device\n");
  530. return 0;
  531. }
  532. main_aat2862_dev = dev;
  533. bl_dev = backlight_device_register(HUB_I2C_BL_NAME, &i2c_dev->dev, NULL, &hub_bl_ops);
  534. bl_dev->props.max_brightness = MAX_BRIGHTNESS;
  535. bl_dev->props.brightness = DEFAULT_BRIGHTNESS;
  536. bl_dev->props.power = FB_BLANK_UNBLANK;
  537. dev->bl_dev = bl_dev;
  538. dev->client = i2c_dev;
  539. i2c_set_clientdata(i2c_dev, dev);
  540. //aat2862_init(i2c_dev);
  541. aat2862_touch_ldo_enable(i2c_dev, 1);
  542. led_classdev_register(&i2c_dev->dev, &lcd_backlight);
  543. aat2862_set_main_current_level(i2c_dev, DEFAULT_BRIGHTNESS);
  544. err = device_create_file(&i2c_dev->dev, &dev_attr_level);
  545. err = device_create_file(&i2c_dev->dev, &dev_attr_backlight_on_off);
  546. err = device_create_file(&i2c_dev->dev, &dev_attr_gpio_test);
  547. #ifdef CONFIG_HAS_EARLYSUSPEND
  548. dev->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
  549. dev->early_suspend.suspend = aat2862_early_suspend;
  550. dev->early_suspend.resume = aat2862_late_resume;
  551. register_early_suspend(&dev->early_suspend);
  552. #endif
  553. gpio_request(LCD_CP_EN, "LCD_CP_EN");
  554. TOUCH_KEY_BL_INIT();
  555. TOUCH_KEY_BL_ON();
  556. return 0;
  557. }
  558. static int aat2862_remove(struct i2c_client *i2c_dev)
  559. {
  560. struct aat2862_device *dev = i2c_get_clientdata(i2c_dev);
  561. unregister_early_suspend(&dev->early_suspend);
  562. gpio_free(LCD_CP_EN);
  563. device_remove_file(&i2c_dev->dev, &dev_attr_level);
  564. device_remove_file(&i2c_dev->dev, &dev_attr_backlight_on_off);
  565. device_remove_file(&i2c_dev->dev, &dev_attr_gpio_test);
  566. dev = (struct aat2862_device *)i2c_get_clientdata(i2c_dev);
  567. backlight_device_unregister(dev->bl_dev);
  568. i2c_set_clientdata(i2c_dev, NULL);
  569. return 0;
  570. }
  571. static int aat2862_suspend(struct i2c_client *client, pm_message_t state)
  572. {
  573. printk(KERN_INFO"%s: new state: %d\n",__func__, state.event);
  574. client->dev.power.power_state = state;
  575. aat2862_touch_ldo_enable(client, 0);
  576. mdelay(5);
  577. aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x00);
  578. gpio_direction_output(LCD_CP_EN, 0);
  579. return 0;
  580. }
  581. #ifdef CONFIG_HAS_EARLYSUSPEND
  582. static int aat2862_bl_suspend(struct i2c_client *client, pm_message_t state)
  583. {
  584. printk(KERN_INFO"%s: new state: %d\n",__func__, state.event);
  585. //client->dev.power.power_state = state;
  586. aat2862_backlight_off();
  587. aat2862_write_reg(client, 0x03, 0x0F);
  588. aat2862_write_reg(client, 0x04, 0x0F);
  589. aat2862_write_reg(client, 0x05, 0x0F);
  590. aat2862_write_reg(client, 0x06, 0x0F);
  591. early_bl_timer = 0;
  592. return 0;
  593. }
  594. #endif
  595. static int aat2862_resume(struct i2c_client *client)
  596. {
  597. aat2862_init(client);
  598. printk(KERN_INFO"%s: old state: %d\n",__func__, client->dev.power.power_state.event);
  599. client->dev.power.power_state = PMSG_ON;
  600. aat2862_write_reg(client, LDO_AB_LEVEL_REG, 0x4C);
  601. aat2862_write_reg(client, LDO_CD_LEVEL_REG, 0x4C);
  602. aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x03);
  603. mdelay(5);
  604. aat2862_touch_ldo_enable(client, 1);
  605. // aat2862_write_reg(client, LDO_ABCD_EN_REG, 0x0F);
  606. // mdelay(10);
  607. //aat2862_backlight_on();
  608. return 0;
  609. }
  610. #ifdef CONFIG_HAS_EARLYSUSPEND
  611. static int aat2862_bl_resume(struct i2c_client *client)
  612. {
  613. early_bl_timer = 1;
  614. aat2862_backlight_on();
  615. return 0;
  616. }
  617. static void aat2862_early_suspend(struct early_suspend *h)
  618. {
  619. struct aat2862_device *dev;
  620. dev = container_of(h, struct aat2862_device, early_suspend);
  621. aat2862_bl_suspend(dev->client, PMSG_SUSPEND);
  622. }
  623. static void aat2862_late_resume(struct early_suspend *h)
  624. {
  625. struct aat2862_device *dev;
  626. dev = container_of(h, struct aat2862_device, early_suspend);
  627. aat2862_bl_resume(dev->client);
  628. }
  629. #endif
  630. static struct i2c_driver main_aat2862_driver = {
  631. .probe = aat2862_probe,
  632. .remove = aat2862_remove,
  633. .suspend = aat2862_suspend,
  634. .resume = aat2862_resume,
  635. .id_table = hub_bl_id,
  636. .driver = {
  637. .name = HUB_I2C_BL_NAME,
  638. },
  639. };
  640. static int __init lcd_backlight_init(void)
  641. {
  642. static int err=0;
  643. err = i2c_add_driver(&main_aat2862_driver);
  644. return err;
  645. }
  646. module_init(lcd_backlight_init);
  647. MODULE_DESCRIPTION("AAT2862 Backlight Control");
  648. MODULE_AUTHOR("kyungtae Oh <kyungtae.oh@lge.com>");
  649. MODULE_LICENSE("GPL");