leds-sec-backlight.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /* Copyright (c) 2013, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/leds.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/of_gpio.h>
  18. #include <linux/gpio.h>
  19. #include <linux/of.h>
  20. #include <linux/printk.h>
  21. #include <linux/delay.h>
  22. #include <linux/slab.h>
  23. #define LED_GPIO_BACKLIGHT_DRIVER_NAME "sec,leds-gpio-bkl"
  24. #define LED_TRIGGER_DEFAULT "none"
  25. struct led_brt_value {
  26. int os_value; /* Platform setting values*/
  27. int ic_value; /* Chip Setting values*/
  28. };
  29. struct led_gpio_bkl_data {
  30. int led_ctrl;
  31. int brightness;
  32. int max_brt_value, min_brt_value, dimming_value, max_brt_in_blu;
  33. int brt_table_len;
  34. int easyscale_addr;
  35. const char* control_type;
  36. struct led_brt_value *brt_table;
  37. struct led_classdev cdev;
  38. #ifdef CONFIG_BACKLIGHT_KTD2801
  39. int express_wire;
  40. #endif
  41. };
  42. static struct of_device_id led_gpio_bkl_of_match[] = {
  43. {.compatible = LED_GPIO_BACKLIGHT_DRIVER_NAME,},
  44. {},
  45. };
  46. static DEFINE_SPINLOCK(bl_ctrl_lock);
  47. #if defined(CONFIG_GET_LCD_ATTACHED)
  48. extern int get_lcd_attached(void);
  49. #endif
  50. #ifdef CONFIG_BACKLIGHT_KTD2801
  51. #define MAX_BRIGHTNESS 255
  52. #define DEFAULT_BRIGHTNESS 122
  53. #define MAX_BRIGHTNESS_IN_BLU 32
  54. #define KTD2801_DATA_BITS 8
  55. #define KTD2801_T_OFF 5
  56. #define KTD2801_T_EW_DET 300
  57. #define KTD2801_T_EW_DELAY 200
  58. #define KTD2801_T_EW_WIN 1
  59. #define KTD2801_T_DS 5
  60. #define KTD2801_T_EOD_H 400
  61. #define KTD2801_T_EOD_L 30
  62. #define KTD2801_T_H_LB 30
  63. #define KTD2801_T_L_LB 70
  64. #define KTD2801_T_H_HB 70
  65. #define KTD2801_T_L_HB 30
  66. #define MAX_BRIGHTNESS_IN_BLU 32
  67. static int easy_scale_send_bit (unsigned gpio, bool bit)
  68. {
  69. if (!bit) { /* Send bit 0 */
  70. gpio_direction_output(gpio, 0);
  71. udelay(KTD2801_T_L_LB);
  72. gpio_direction_output(gpio, 1);
  73. udelay(KTD2801_T_H_LB);
  74. return 0;
  75. } else { /* Send bit 1 */
  76. gpio_direction_output(gpio, 0);
  77. udelay(KTD2801_T_L_HB);
  78. gpio_direction_output(gpio, 1);
  79. udelay(KTD2801_T_H_HB);
  80. return 0;
  81. }
  82. }
  83. static void easy_scale_type_set_brightness(struct led_classdev *led_cdev,
  84. enum led_brightness value)
  85. {
  86. struct led_gpio_bkl_data *bkl_led =
  87. container_of(led_cdev, struct led_gpio_bkl_data, cdev);
  88. int brightness_idx = 0;
  89. if (value > 255 || value < 0 ) {
  90. pr_info("BL : Error level = %d\n", value);
  91. return; /* Add Exception over 255 */
  92. }
  93. if (value > 0) {
  94. for (brightness_idx = 0; brightness_idx < bkl_led->brt_table_len; brightness_idx++) {
  95. if (value <= bkl_led->brt_table[brightness_idx].os_value)
  96. break;
  97. }
  98. } else {
  99. gpio_direction_output(bkl_led->led_ctrl, 0);
  100. mdelay(KTD2801_T_OFF);
  101. bkl_led->express_wire = 0;
  102. pr_info("KTD2801 BL : level = %d, index = %d\n", value, brightness_idx);
  103. bkl_led->brightness = brightness_idx;
  104. return;
  105. }
  106. pr_info("KTD2801 BL : level = %d, index = %d\n", value, brightness_idx);
  107. if (bkl_led->brightness != brightness_idx) {
  108. int i = 0;
  109. if(!bkl_led->express_wire) /* express wire dimming */
  110. {
  111. gpio_direction_output(bkl_led->led_ctrl, 0);
  112. mdelay(KTD2801_T_OFF);
  113. gpio_direction_output(bkl_led->led_ctrl, 1);
  114. udelay(KTD2801_T_EW_DELAY);
  115. gpio_direction_output(bkl_led->led_ctrl, 0);
  116. udelay(KTD2801_T_EW_DET);
  117. gpio_direction_output(bkl_led->led_ctrl, 1);
  118. mdelay(KTD2801_T_EW_WIN);
  119. bkl_led->express_wire = 1;
  120. }
  121. gpio_direction_output(bkl_led->led_ctrl, 1); /* Data start */
  122. udelay(KTD2801_T_DS);
  123. for (i = 0; i < KTD2801_DATA_BITS ; i++) /* Send DATA */
  124. easy_scale_send_bit(bkl_led->led_ctrl, bkl_led->brt_table[brightness_idx].ic_value & (0x1 << (7-i)));
  125. gpio_direction_output(bkl_led->led_ctrl, 0); /* EOD */
  126. udelay(KTD2801_T_EOD_L);
  127. gpio_direction_output(bkl_led->led_ctrl, 1);
  128. udelay(KTD2801_T_EOD_H);
  129. }
  130. bkl_led->brightness = brightness_idx;
  131. return ;
  132. }
  133. #else
  134. #define MAX_BRIGHTNESS 255
  135. #define DEFAULT_BRIGHTNESS 122
  136. #define MAX_BRIGHTNESS_IN_BLU 32
  137. #define TPS61158_DATA_BITS 8
  138. #define TPS61158_ADDRESS_BITS 8
  139. #define TPS61158_TIME_T_EOS 300
  140. #define TPS61158_TIME_ES_DET_DELAY 150
  141. #define TPS61158_TIME_ES_DET_TIME 500
  142. #define TPS61158_TIME_T_START 10
  143. #define TPS61158_TIME_DATA_DELAY_SHORT 180
  144. #define TPS61158_TIME_DATA_DELAY_LONG 400
  145. #define MAX_BRIGHTNESS_IN_BLU 32
  146. static int easy_scale_send_bit (unsigned gpio, bool bit)
  147. {
  148. if (bit) { /* Send bit 1 */
  149. gpio_direction_output(gpio, 0);
  150. udelay(TPS61158_TIME_DATA_DELAY_SHORT);
  151. gpio_direction_output(gpio, 1);
  152. udelay(TPS61158_TIME_DATA_DELAY_LONG);
  153. return 0;
  154. } else { /* Send bit 0 */
  155. gpio_direction_output(gpio, 0);
  156. udelay(TPS61158_TIME_DATA_DELAY_LONG);
  157. gpio_direction_output(gpio, 1);
  158. udelay(TPS61158_TIME_DATA_DELAY_SHORT);
  159. return 0;
  160. }
  161. }
  162. static void easy_scale_type_set_brightness(struct led_classdev *led_cdev,
  163. enum led_brightness value)
  164. {
  165. struct led_gpio_bkl_data *bkl_led =
  166. container_of(led_cdev, struct led_gpio_bkl_data, cdev);
  167. int brightness_idx = 0;
  168. if (value > 255 || value < 0 ) {
  169. pr_info("BL : Error level = %d\n", value);
  170. return; /* Add Exception over 255 */
  171. }
  172. if (value > 0) {
  173. for (brightness_idx = 0; brightness_idx < bkl_led->brt_table_len; brightness_idx++) {
  174. if (value <= bkl_led->brt_table[brightness_idx].os_value)
  175. break;
  176. }
  177. } else {
  178. gpio_direction_output(bkl_led->led_ctrl, 0);
  179. mdelay(3);
  180. pr_info("BL : level = %d, index = %d\n", value, brightness_idx);
  181. bkl_led->brightness = brightness_idx;
  182. return;
  183. }
  184. pr_info("BL : level = %d, index = %d\n", value, brightness_idx);
  185. if (bkl_led->brightness != brightness_idx) {
  186. int i = 0;
  187. gpio_direction_output(bkl_led->led_ctrl, 0);
  188. udelay(TPS61158_TIME_T_EOS);
  189. gpio_direction_output(bkl_led->led_ctrl, 1);
  190. udelay(TPS61158_TIME_ES_DET_DELAY);
  191. gpio_direction_output(bkl_led->led_ctrl, 0);
  192. udelay(TPS61158_TIME_ES_DET_TIME);
  193. gpio_direction_output(bkl_led->led_ctrl, 1);
  194. mdelay(3);
  195. udelay(500); /* ES window time */
  196. for (i = 0; i < TPS61158_DATA_BITS ; i++) /* Send DATA */
  197. easy_scale_send_bit(bkl_led->led_ctrl, bkl_led->easyscale_addr & (0x1 << i));
  198. gpio_direction_output(bkl_led->led_ctrl, 0); /* 2nd FLAG */
  199. udelay(TPS61158_TIME_T_EOS);
  200. gpio_direction_output(bkl_led->led_ctrl, 1);
  201. udelay(TPS61158_TIME_T_START);
  202. for (i = 0; i < TPS61158_DATA_BITS ; i++) /* Send DATA */
  203. easy_scale_send_bit(bkl_led->led_ctrl, bkl_led->brt_table[brightness_idx].ic_value & (0x1 << i));
  204. gpio_direction_output(bkl_led->led_ctrl, 0); /* 3rd FLAG */
  205. udelay(TPS61158_TIME_T_EOS);
  206. gpio_direction_output(bkl_led->led_ctrl, 1); /* BL brightness enable */
  207. }
  208. bkl_led->brightness = brightness_idx;
  209. return ;
  210. }
  211. #endif
  212. static void gpio_swing_type_set_brightness(struct led_classdev *led_cdev,
  213. enum led_brightness value)
  214. {
  215. struct led_gpio_bkl_data *bkl_led =
  216. container_of(led_cdev, struct led_gpio_bkl_data, cdev);
  217. int brightness_idx = 0;
  218. #if defined(CONFIG_GET_LCD_ATTACHED)
  219. if(get_lcd_attached() == 0)
  220. {
  221. pr_info("%s: get_lcd_attached(0)! Backlight IC off\n",__func__);
  222. gpio_set_value(bkl_led->led_ctrl, 0);
  223. mdelay(50);
  224. return;
  225. }
  226. #endif
  227. if (value > 255 || value < 0 ) {
  228. pr_info("BL : Error level = %d\n", value);
  229. return; /* Add Exception over 255 */
  230. }
  231. if (value > 0) {
  232. if(value < bkl_led->min_brt_value) {
  233. brightness_idx = bkl_led->dimming_value;
  234. } else if(value >= bkl_led->max_brt_value) {
  235. brightness_idx = bkl_led->brt_table[bkl_led->brt_table_len-1].ic_value;
  236. } else {
  237. int i;
  238. for (i = 0; i < bkl_led->brt_table_len; i++) {
  239. if (value <= bkl_led->brt_table[i].os_value) {
  240. brightness_idx = bkl_led->brt_table[i].ic_value;
  241. break;
  242. }
  243. }
  244. }
  245. } else {
  246. gpio_set_value(bkl_led->led_ctrl, 0);
  247. mdelay(3);
  248. pr_info("BL : level = %d, index = %d\n", value, brightness_idx);
  249. bkl_led->brightness = brightness_idx;
  250. return;
  251. }
  252. pr_info("BL : level = %d, index = %d\n", value, brightness_idx);
  253. if(bkl_led->brightness != brightness_idx)
  254. {
  255. if (!brightness_idx) {
  256. gpio_set_value(bkl_led->led_ctrl, 0);
  257. mdelay(50);
  258. } else {
  259. int pulse;
  260. if (unlikely(bkl_led->brightness < 0)) {
  261. int val = gpio_get_value(bkl_led->led_ctrl);
  262. if (val) {
  263. bkl_led->brightness = 0;
  264. gpio_set_value(bkl_led->led_ctrl, 0);
  265. mdelay(50);
  266. pr_info("BL : LCD Baklight init in boot time on kernel\n");
  267. }
  268. }
  269. if (!bkl_led->brightness) {
  270. gpio_set_value(bkl_led->led_ctrl, 1);
  271. udelay(100);
  272. bkl_led->brightness = bkl_led->max_brt_in_blu;
  273. }
  274. pulse = (brightness_idx - bkl_led->brightness + bkl_led->max_brt_in_blu) % bkl_led->max_brt_in_blu;
  275. pr_debug("BL : ctrl_pls = %d, cur_pls = %d, bef_pls = %d\n", pulse, brightness_idx, bkl_led->brightness);
  276. for (; pulse > 0; pulse--) {
  277. gpio_set_value(bkl_led->led_ctrl, 0);
  278. udelay(2);
  279. gpio_set_value(bkl_led->led_ctrl, 1);
  280. udelay(2);
  281. }
  282. }
  283. bkl_led->brightness = brightness_idx;
  284. }
  285. mdelay(1);
  286. }
  287. static void led_gpio_brightness_set(struct led_classdev *led_cdev,
  288. enum led_brightness value)
  289. {
  290. struct led_gpio_bkl_data *bkl_led =
  291. container_of(led_cdev, struct led_gpio_bkl_data, cdev);
  292. spin_lock(&bl_ctrl_lock);
  293. if(!strcmp("easy_scale", bkl_led->control_type)) {
  294. easy_scale_type_set_brightness(led_cdev, value);
  295. } else if(!strcmp("gpio_swing", bkl_led->control_type)) {
  296. gpio_swing_type_set_brightness(led_cdev, value);
  297. } else {
  298. dev_err(bkl_led->cdev.dev, "%s:%d control type is not supported\n",
  299. __func__, __LINE__);
  300. }
  301. spin_unlock(&bl_ctrl_lock);
  302. }
  303. static enum led_brightness led_gpio_brightness_get(struct led_classdev
  304. *led_cdev)
  305. {
  306. struct led_gpio_bkl_data *bkl_led =
  307. container_of(led_cdev, struct led_gpio_bkl_data, cdev);
  308. return bkl_led->brightness;
  309. }
  310. int __devinit led_gpio_bkl_probe(struct platform_device *pdev)
  311. {
  312. int rc = 0, i;
  313. u32 tmp;
  314. const char *temp_str;
  315. struct led_gpio_bkl_data *bkl_led = NULL;
  316. struct device_node *node = pdev->dev.of_node;
  317. bkl_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_bkl_data),
  318. GFP_KERNEL);
  319. if (bkl_led == NULL) {
  320. dev_err(&pdev->dev, "%s:%d Unable to allocate memory\n",
  321. __func__, __LINE__);
  322. return -ENOMEM;
  323. }
  324. bkl_led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
  325. rc = of_property_read_string(node, "linux,default-trigger", &temp_str);
  326. if (!rc)
  327. bkl_led->cdev.default_trigger = temp_str;
  328. bkl_led->led_ctrl = of_get_named_gpio(node, "sec,led-ctrl", 0);
  329. if (bkl_led->led_ctrl < 0) {
  330. dev_err(&pdev->dev,
  331. "Looking up %s property in node %s failed. rc = %d\n",
  332. "flash-en", node->full_name, bkl_led->led_ctrl);
  333. goto error;
  334. } else {
  335. rc = gpio_request(bkl_led->led_ctrl, "led_ctrl");
  336. if (rc) {
  337. dev_err(&pdev->dev,
  338. "%s: Failed to request gpio %d,rc = %d\n",
  339. __func__, bkl_led->led_ctrl, rc);
  340. goto error;
  341. }
  342. }
  343. bkl_led->control_type = of_get_property(node,
  344. "sec,control-type", NULL);
  345. rc = of_property_read_u32(node,
  346. "sec,brightness-table-len", &tmp);
  347. bkl_led->brt_table_len = (!rc ? tmp : false);
  348. bkl_led->brightness = -1;
  349. bkl_led->brt_table = (struct led_brt_value *)kzalloc(sizeof(struct led_brt_value) * bkl_led->brt_table_len, GFP_KERNEL);
  350. rc = of_property_read_u32_array(node, "sec,brightness-table", (u32 *)bkl_led->brt_table, bkl_led->brt_table_len*2);
  351. for (i = 0 ; i < bkl_led->brt_table_len; i++ ) {
  352. pr_debug("BL : [%d] %d %d\n",i, bkl_led->brt_table[i].os_value, bkl_led->brt_table[i].ic_value);
  353. }
  354. rc = of_property_read_u32(node,
  355. "sec,max-brightness-value", &tmp);
  356. bkl_led->max_brt_value = (!rc ? tmp : false);
  357. rc = of_property_read_u32(node,
  358. "sec,min-brightness-value", &tmp);
  359. bkl_led->min_brt_value = (!rc ? tmp : false);
  360. rc = of_property_read_u32(node,
  361. "sec,dimming-value", &tmp);
  362. bkl_led->dimming_value = (!rc ? tmp : false);
  363. rc = of_property_read_u32(node,
  364. "sec,max-brightness-in-blu-value", &tmp);
  365. bkl_led->max_brt_in_blu = (!rc ? tmp : false);
  366. rc = of_property_read_u32(node,
  367. "sec,easyscale-address", &tmp);
  368. bkl_led->easyscale_addr = (!rc ? tmp : false);
  369. gpio_tlmm_config(GPIO_CFG(bkl_led->led_ctrl, 0,
  370. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
  371. GPIO_CFG_2MA), GPIO_CFG_ENABLE);
  372. platform_set_drvdata(pdev, bkl_led);
  373. bkl_led->cdev.max_brightness = LED_FULL;
  374. bkl_led->cdev.brightness_set = led_gpio_brightness_set;
  375. bkl_led->cdev.brightness_get = led_gpio_brightness_get;
  376. #ifdef CONFIG_BACKLIGHT_KTD2801
  377. bkl_led->express_wire = 0;
  378. #endif
  379. rc = led_classdev_register(&pdev->dev, &bkl_led->cdev);
  380. if (rc) {
  381. dev_err(&pdev->dev, "%s: Failed to register led dev. rc = %d\n",
  382. __func__, rc);
  383. goto error;
  384. }
  385. return 0;
  386. error:
  387. devm_kfree(&pdev->dev, bkl_led);
  388. return rc;
  389. }
  390. int __devexit led_gpio_bkl_remove(struct platform_device *pdev)
  391. {
  392. struct led_gpio_bkl_data *bkl_led =
  393. (struct led_gpio_bkl_data *)platform_get_drvdata(pdev);
  394. led_classdev_unregister(&bkl_led->cdev);
  395. devm_kfree(&pdev->dev, bkl_led);
  396. return 0;
  397. }
  398. static struct platform_driver led_gpio_bkl_driver = {
  399. .probe = led_gpio_bkl_probe,
  400. .remove = __devexit_p(led_gpio_bkl_remove),
  401. .driver = {
  402. .name = LED_GPIO_BACKLIGHT_DRIVER_NAME,
  403. .owner = THIS_MODULE,
  404. .of_match_table = led_gpio_bkl_of_match,
  405. }
  406. };
  407. static int __init led_gpio_bkl_init(void)
  408. {
  409. return platform_driver_register(&led_gpio_bkl_driver);
  410. }
  411. static void __exit led_gpio_bkl_exit(void)
  412. {
  413. return platform_driver_unregister(&led_gpio_bkl_driver);
  414. }
  415. late_initcall(led_gpio_bkl_init);
  416. module_exit(led_gpio_bkl_exit);
  417. MODULE_DESCRIPTION("QCOM GPIO LEDs driver");
  418. MODULE_LICENSE("GPL v2");
  419. MODULE_ALIAS("leds:leds-msm-gpio-flash");