leds-ktd2026.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. /*
  2. * leds_ktd2026.c - driver for KTD2026 led driver chip
  3. *
  4. * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
  5. *
  6. * Contact: Hyoyoung Kim <hyway.kim@samsung.com>
  7. *
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; version 2 of the License.
  12. *
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/device.h>
  18. #include <linux/i2c.h>
  19. #include <linux/delay.h>
  20. #include <linux/slab.h>
  21. #include <linux/fs.h>
  22. #include <linux/uaccess.h>
  23. #include <linux/leds.h>
  24. #include <linux/leds-ktd2026.h>
  25. #include <linux/workqueue.h>
  26. #include <linux/wakelock.h>
  27. #undef AN3029_COMPATIBLE
  28. #if defined(CONFIG_SEC_FACTORY)
  29. #if defined (CONFIG_SEC_ATLANTIC_PROJECT)
  30. static int batt_id_value;
  31. static int jig_power_on_value;
  32. #if defined(CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION)
  33. extern int get_lcd_attached(void);
  34. #endif
  35. static int __init get_batt_id_value_cmdline(char *mode)
  36. {
  37. batt_id_value = mode[0]-48; // Converting Char to Int
  38. return 0;
  39. }
  40. static int __init jig_power_on_value_cmdline(char *mode)
  41. {
  42. jig_power_on_value = mode[0]-48;
  43. return 0;
  44. }
  45. __setup( "jig_power_on=0x", jig_power_on_value_cmdline );
  46. __setup( "batt_id_value=0x", get_batt_id_value_cmdline );
  47. #endif
  48. #endif
  49. /* KTD2026 register map */
  50. #define KTD2026_REG_EN_RST 0x00
  51. #define KTD2026_REG_FLASH_PERIOD 0x01
  52. #define KTD2026_REG_PWM1_TIMER 0x02
  53. #define KTD2026_REG_PWM2_TIMER 0x03
  54. #define KTD2026_REG_LED_EN 0x04
  55. #define KTD2026_REG_TRISE_TFALL 0x05
  56. #define KTD2026_REG_LED1 0x06
  57. #define KTD2026_REG_LED2 0x07
  58. #define KTD2026_REG_LED3 0x08
  59. #define KTD2026_REG_MAX 0x09
  60. #define KTD2026_TIME_UNIT 500
  61. /* MASK */
  62. #define CNT_TIMER_SLOT_MASK 0x07
  63. #define CNT_ENABLE_MASK 0x18
  64. #define CNT_RISEFALL_TSCALE_MASK 0x60
  65. #define CNT_TIMER_SLOT_SHIFT 0x00
  66. #define CNT_ENABLE_SHIFT 0x03
  67. #define CNT_RISEFALL_TSCALE_SHIFT 0x05
  68. #define LED_R_MASK 0x00ff0000
  69. #define LED_G_MASK 0x0000ff00
  70. #define LED_B_MASK 0x000000ff
  71. #define LED_R_SHIFT 16
  72. #define LED_G_SHIFT 8
  73. #define KTD2026_RESET 0x07
  74. #define LED_MAX_CURRENT 0x30
  75. #define LED_DEFAULT_CURRENT 0x20
  76. #define LED_LOW_CURRENT 0x07
  77. #define LED_OFF 0x00
  78. #define MAX_NUM_LEDS 3
  79. static u8 led_dynamic_current = LED_DEFAULT_CURRENT;
  80. static u8 led_lowpower_mode = 0x0;
  81. enum ktd2026_led_mode {
  82. LED_EN_OFF = 0,
  83. LED_EN_ON = 1,
  84. LED_EN_PWM1 = 2,
  85. LED_EN_PWM2 = 3,
  86. };
  87. enum ktd2026_pwm{
  88. PWM1 = 0,
  89. PWM2 = 1,
  90. };
  91. static struct ktd2026_led_conf led_conf[] = {
  92. {
  93. .name = "led_r",
  94. .brightness = LED_OFF,
  95. .max_brightness = LED_MAX_CURRENT,
  96. .flags = 0,
  97. }, {
  98. .name = "led_g",
  99. .brightness = LED_OFF,
  100. .max_brightness = LED_MAX_CURRENT,
  101. .flags = 0,
  102. }, {
  103. .name = "led_b",
  104. .brightness = LED_OFF,
  105. .max_brightness = LED_MAX_CURRENT,
  106. .flags = 0,
  107. }
  108. };
  109. enum ktd2026_led_enum {
  110. LED_R = 0,
  111. LED_G = 2,
  112. LED_B = 4,
  113. };
  114. struct ktd2026_led {
  115. u8 channel;
  116. u8 brightness;
  117. struct led_classdev cdev;
  118. struct work_struct brightness_work;
  119. unsigned long delay_on_time_ms;
  120. unsigned long delay_off_time_ms;
  121. };
  122. struct ktd2026_data {
  123. struct i2c_client *client;
  124. struct mutex mutex;
  125. struct ktd2026_led leds[MAX_NUM_LEDS];
  126. u8 shadow_reg[KTD2026_REG_MAX];
  127. };
  128. struct i2c_client *b_client;
  129. #define SEC_LED_SPECIFIC
  130. #ifdef SEC_LED_SPECIFIC
  131. extern struct class *sec_class;
  132. static struct device *led_dev;
  133. /*path : /sys/class/sec/led/led_pattern*/
  134. /*path : /sys/class/sec/led/led_blink*/
  135. /*path : /sys/class/sec/led/led_brightness*/
  136. /*path : /sys/class/leds/led_r/brightness*/
  137. /*path : /sys/class/leds/led_g/brightness*/
  138. /*path : /sys/class/leds/led_b/brightness*/
  139. #endif
  140. static void ktd2026_leds_on(enum ktd2026_led_enum led,
  141. enum ktd2026_led_mode mode, u8 bright);
  142. static inline struct ktd2026_led *cdev_to_led(struct led_classdev *cdev)
  143. {
  144. return container_of(cdev, struct ktd2026_led, cdev);
  145. }
  146. static int leds_i2c_write_all(struct i2c_client *client)
  147. {
  148. struct ktd2026_data *data = i2c_get_clientdata(client);
  149. int ret = 0;
  150. int retry = 0;
  151. mutex_lock(&data->mutex);
  152. do
  153. {
  154. ret = i2c_smbus_write_i2c_block_data(client,
  155. KTD2026_REG_EN_RST, KTD2026_REG_MAX,
  156. &data->shadow_reg[KTD2026_REG_EN_RST]);
  157. if (ret < 0) {
  158. dev_err(&client->adapter->dev,
  159. "%s: failure on i2c block write\n",
  160. __func__);
  161. retry++;
  162. if(retry > 10)
  163. {
  164. dev_err(&client->adapter->dev,
  165. "%s: retry > 10 : Fatal i2c error\n",
  166. __func__);
  167. break;
  168. }
  169. msleep(100);
  170. }
  171. } while(ret < 0);
  172. mutex_unlock(&data->mutex);
  173. return ret;
  174. }
  175. void ktd2026_set_brightness(struct led_classdev *cdev,
  176. enum led_brightness brightness)
  177. {
  178. struct ktd2026_led *led = cdev_to_led(cdev);
  179. led->brightness = (u8)brightness;
  180. schedule_work(&led->brightness_work);
  181. }
  182. static void ktd2026_led_brightness_work(struct work_struct *work)
  183. {
  184. struct i2c_client *client = b_client;
  185. struct ktd2026_led *led = container_of(work,
  186. struct ktd2026_led, brightness_work);
  187. if (led->brightness==0)
  188. ktd2026_leds_on(led->channel, LED_EN_OFF, 0);
  189. else ktd2026_leds_on(led->channel, LED_EN_ON, led->brightness);
  190. leds_i2c_write_all(client);
  191. }
  192. /* leds_set_slope_mode function and leds_on are for compatiblity
  193. * with AN3029A LED Driver , thus depricated.
  194. *
  195. * leds_set_slope_mode() sets correct values to corresponding shadow registers.
  196. * led: stands for LED_R or LED_G or LED_B.
  197. * delay: represents for starting delay time in multiple of .5 second.
  198. * dutymax: led at slope lighting maximum PWM Duty setting.
  199. * dutymid: led at slope lighting middle PWM Duty setting.
  200. * dutymin: led at slope lighting minimum PWM Duty Setting.
  201. * slptt1: total time of slope operation 1 and 2, in multiple of .5 second.
  202. * slptt2: total time of slope operation 3 and 4, in multiple of .5 second.
  203. * dt1: detention time at each step in slope operation 1, in multiple of 4ms.
  204. * dt2: detention time at each step in slope operation 2, in multiple of 4ms.
  205. * dt3: detention time at each step in slope operation 3, in multiple of 4ms.
  206. * dt4: detention time at each step in slope operation 4, in multiple of 4ms.
  207. */
  208. #ifdef AN3029_COMPATIBLE
  209. static void leds_set_slope_mode(struct i2c_client *client,
  210. enum ktd2026_led_enum led, u8 delay,
  211. u8 dutymax, u8 dutymid, u8 dutymin,
  212. u8 slptt1, u8 slptt2,
  213. u8 dt1, u8 dt2, u8 dt3, u8 dt4)
  214. {
  215. struct ktd2026_data *data = i2c_get_clientdata(client);
  216. data->shadow_reg[KTD2026_REG_FLASH_PERIOD]
  217. = (slptt1 + slptt2) * 4 + 2;
  218. data->shadow_reg[KTD2026_REG_PWM1_TIMER]
  219. = slptt1*255 / (slptt1 + slptt2);
  220. data->shadow_reg[KTD2026_REG_TRISE_TFALL]
  221. = ((dt3+dt4)*5 << 4) + (dt1+dt2)*5;
  222. }
  223. static void leds_on(enum ktd2026_led_enum led, bool on, bool slopemode,
  224. u8 ledcc)
  225. {
  226. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  227. if(led == LED_R)data->shadow_reg[KTD2026_REG_LED1] = ledcc;
  228. if(led == LED_G)data->shadow_reg[KTD2026_REG_LED2] = ledcc;
  229. if(led == LED_B)data->shadow_reg[KTD2026_REG_LED3] = ledcc;
  230. if (on)
  231. {
  232. if (slopemode)
  233. data->shadow_reg[KTD2026_REG_LED_EN]
  234. |= LED_EN_PWM1 << led;
  235. else data->shadow_reg[KTD2026_REG_LED_EN] |= LED_EN_ON << led;
  236. }
  237. else
  238. /*off*/
  239. data->shadow_reg[KTD2026_REG_LED_EN] &= ~(LED_EN_PWM2 << led);
  240. }
  241. #endif
  242. static void ktd2026_leds_on(enum ktd2026_led_enum led,
  243. enum ktd2026_led_mode mode, u8 bright)
  244. {
  245. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  246. data->shadow_reg[KTD2026_REG_LED1 + led/2] = bright;
  247. if(mode == LED_EN_OFF)
  248. data->shadow_reg[KTD2026_REG_LED_EN] &= ~(LED_EN_PWM2 << led);
  249. else
  250. data->shadow_reg[KTD2026_REG_LED_EN] |= mode << led;
  251. }
  252. void ktd2026_set_timerslot_control(int timer_slot)
  253. {
  254. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  255. data->shadow_reg[KTD2026_REG_EN_RST] &= ~(CNT_TIMER_SLOT_MASK);
  256. data->shadow_reg[KTD2026_REG_EN_RST]
  257. |= timer_slot << CNT_TIMER_SLOT_SHIFT;
  258. }
  259. /* Flash period = period * 0.128 + 0.256
  260. exception 0 = 0.128s
  261. please refer to data sheet for detail */
  262. void ktd2026_set_period(int period)
  263. {
  264. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  265. data->shadow_reg[KTD2026_REG_FLASH_PERIOD] = period;
  266. }
  267. /* MAX duty = 0xFF (99.6%) , min duty = 0x0 (0%) , 0.4% scale */
  268. void ktd2026_set_pwm_duty(enum ktd2026_pwm pwm, int duty)
  269. {
  270. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  271. data->shadow_reg[KTD2026_REG_PWM1_TIMER + pwm] = duty;
  272. }
  273. /* Rise Ramp Time = trise * 96 (ms) */
  274. /* minimum rise ramp time = 1.5ms when traise is set to 0 */
  275. /* Tscale */
  276. /* 0 = 1x 1 = 2x slower 2 = 4x slower 3 = 8x slower */
  277. void ktd2026_set_trise_tfall(int trise, int tfall, int tscale)
  278. {
  279. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  280. data->shadow_reg[KTD2026_REG_TRISE_TFALL] = (tfall << 4) + trise;
  281. data->shadow_reg[KTD2026_REG_EN_RST] &= ~(CNT_RISEFALL_TSCALE_MASK);
  282. data->shadow_reg[KTD2026_REG_EN_RST]
  283. |= tscale << CNT_RISEFALL_TSCALE_SHIFT;
  284. }
  285. void ktd2026_set_sleep(int sleep)
  286. {
  287. struct ktd2026_data *data = i2c_get_clientdata(b_client);
  288. if (sleep)
  289. {
  290. int val;
  291. val = 0x1 << CNT_ENABLE_SHIFT;
  292. data->shadow_reg[KTD2026_REG_EN_RST] |= val;
  293. }
  294. else
  295. data->shadow_reg[KTD2026_REG_EN_RST] &= ~CNT_ENABLE_MASK;
  296. }
  297. #ifdef SEC_LED_SPECIFIC
  298. static void ktd2026_reset(void)
  299. {
  300. int retval;
  301. struct i2c_client *client;
  302. client = b_client;
  303. ktd2026_leds_on(LED_R, LED_EN_OFF, 0);
  304. ktd2026_leds_on(LED_G, LED_EN_OFF, 0);
  305. ktd2026_leds_on(LED_B, LED_EN_OFF, 0);
  306. retval = leds_i2c_write_all(client);
  307. if (retval)
  308. pr_err("%s:leds_i2c_write_all failed\n", __func__);
  309. ktd2026_set_timerslot_control(0); /* Tslot1 */
  310. ktd2026_set_period(0);
  311. ktd2026_set_pwm_duty(PWM1, 0);
  312. ktd2026_set_pwm_duty(PWM2, 0);
  313. ktd2026_set_trise_tfall(0, 0, 0);
  314. /* get into sleep mode after turing off all the leds */
  315. ktd2026_set_sleep(1);
  316. retval = leds_i2c_write_all(client);
  317. if (retval)
  318. pr_err("%s:leds_i2c_write_all failed\n", __func__);
  319. /* reset sleep mode, so that next i2c command
  320. would not make the driver IC go into sleep mode */
  321. ktd2026_set_sleep(0);
  322. }
  323. void ktd2026_start_led_pattern(enum ktd2026_pattern mode)
  324. {
  325. int retval;
  326. struct i2c_client *client;
  327. client = b_client;
  328. if (mode > POWERING)
  329. return;
  330. /* Set all LEDs Off */
  331. ktd2026_reset();
  332. if (mode == LED_OFF)
  333. return;
  334. /* Set to low power consumption mode */
  335. if (led_lowpower_mode == 1)
  336. led_dynamic_current = LED_LOW_CURRENT;
  337. else
  338. led_dynamic_current = LED_DEFAULT_CURRENT;
  339. switch (mode) {
  340. case CHARGING:
  341. ktd2026_leds_on(LED_R, LED_EN_ON, led_dynamic_current);
  342. break;
  343. case CHARGING_ERR:
  344. ktd2026_set_timerslot_control(1); /* Tslot2 */
  345. ktd2026_set_period(6);
  346. ktd2026_set_pwm_duty(PWM1, 127);
  347. ktd2026_set_pwm_duty(PWM2, 127);
  348. ktd2026_set_trise_tfall(0, 0, 0);
  349. ktd2026_leds_on(LED_R, LED_EN_PWM2, led_dynamic_current);
  350. break;
  351. case MISSED_NOTI:
  352. ktd2026_set_timerslot_control(1); /* Tslot2 */
  353. ktd2026_set_period(41);
  354. ktd2026_set_pwm_duty(PWM1, 232);
  355. ktd2026_set_pwm_duty(PWM2, 23);
  356. ktd2026_set_trise_tfall(0, 0, 0);
  357. ktd2026_leds_on(LED_B, LED_EN_PWM2, led_dynamic_current);
  358. break;
  359. case LOW_BATTERY:
  360. ktd2026_set_timerslot_control(1); /* Tslot2 */
  361. ktd2026_set_period(41);
  362. ktd2026_set_pwm_duty(PWM1, 232);
  363. ktd2026_set_pwm_duty(PWM2, 23);
  364. ktd2026_set_trise_tfall(0, 0, 0);
  365. ktd2026_leds_on(LED_R, LED_EN_PWM2, led_dynamic_current);
  366. break;
  367. case FULLY_CHARGED:
  368. ktd2026_leds_on(LED_G, LED_EN_ON, led_dynamic_current);
  369. break;
  370. case POWERING:
  371. ktd2026_set_timerslot_control(0); /* Tslot1 */
  372. ktd2026_set_period(14);
  373. ktd2026_set_pwm_duty(PWM1, 128);
  374. ktd2026_set_trise_tfall(7, 7, 0);
  375. ktd2026_leds_on(LED_B, LED_EN_ON, led_dynamic_current/2);
  376. ktd2026_leds_on(LED_G, LED_EN_PWM1, led_dynamic_current/3);
  377. break;
  378. default:
  379. return;
  380. break;
  381. }
  382. retval = leds_i2c_write_all(client);
  383. if (retval)
  384. pr_err("%s:leds_i2c_write_all failed\n", __func__);
  385. }
  386. EXPORT_SYMBOL(ktd2026_start_led_pattern);
  387. static void ktd2026_set_led_blink(enum ktd2026_led_enum led,
  388. unsigned int delay_on_time,
  389. unsigned int delay_off_time,
  390. u8 brightness)
  391. {
  392. int on_time, off_time;
  393. if (brightness == LED_OFF) {
  394. ktd2026_leds_on(led, LED_EN_OFF, brightness);
  395. return;
  396. }
  397. if (brightness > LED_MAX_CURRENT)
  398. brightness = LED_MAX_CURRENT;
  399. if (delay_off_time == LED_OFF) {
  400. ktd2026_leds_on(led, LED_EN_ON, brightness);
  401. return;
  402. } else
  403. ktd2026_leds_on(led, LED_EN_PWM1, brightness);
  404. on_time = (delay_on_time + KTD2026_TIME_UNIT - 1) / KTD2026_TIME_UNIT;
  405. off_time = (delay_off_time + KTD2026_TIME_UNIT - 1) / KTD2026_TIME_UNIT;
  406. ktd2026_set_timerslot_control(0); /* Tslot1 */
  407. ktd2026_set_period((on_time+off_time) * 4 + 2);
  408. ktd2026_set_pwm_duty(PWM1, on_time*255 / (on_time + off_time));
  409. ktd2026_set_trise_tfall(0, 0, 0);
  410. pr_info("%s:on_time=%d, off_time=%d, period=%d, duty=%d\n" ,
  411. __func__, on_time, off_time, (on_time+off_time) * 4 + 2,
  412. on_time * 255 / (on_time + off_time) );
  413. }
  414. static ssize_t store_ktd2026_led_lowpower(struct device *dev,
  415. struct device_attribute *devattr,
  416. const char *buf, size_t count)
  417. {
  418. int retval;
  419. u8 led_lowpower;
  420. struct ktd2026_data *data = dev_get_drvdata(dev);
  421. retval = kstrtou8(buf, 0, &led_lowpower);
  422. if (retval != 0) {
  423. dev_err(&data->client->dev, "fail to get led_lowpower.\n");
  424. return count;
  425. }
  426. led_lowpower_mode = led_lowpower;
  427. pr_info("%s:led_lowpower mode set to %i\n", __func__, led_lowpower);
  428. return count;
  429. }
  430. static ssize_t store_ktd2026_led_brightness(struct device *dev,
  431. struct device_attribute *devattr,
  432. const char *buf, size_t count)
  433. {
  434. int retval;
  435. u8 brightness;
  436. struct ktd2026_data *data = dev_get_drvdata(dev);
  437. retval = kstrtou8(buf, 0, &brightness);
  438. if (retval != 0) {
  439. dev_err(&data->client->dev, "fail to get led_brightness.\n");
  440. return count;
  441. }
  442. if (brightness > LED_MAX_CURRENT)
  443. brightness = LED_MAX_CURRENT;
  444. led_dynamic_current = brightness;
  445. pr_info("%s:led brightness set to %i\n", __func__, brightness);
  446. return count;
  447. }
  448. static ssize_t store_ktd2026_led_br_lev(struct device *dev,
  449. struct device_attribute *devattr,
  450. const char *buf, size_t count)
  451. {
  452. int retval;
  453. unsigned long brightness_lev;
  454. struct ktd2026_data *data = dev_get_drvdata(dev);
  455. retval = kstrtoul(buf, 16, &brightness_lev);
  456. if (retval != 0) {
  457. dev_err(&data->client->dev, "fail to get led_br_lev.\n");
  458. return count;
  459. }
  460. return count;
  461. }
  462. static ssize_t store_ktd2026_led_pattern(struct device *dev,
  463. struct device_attribute *devattr,
  464. const char *buf, size_t count)
  465. {
  466. int retval;
  467. unsigned int mode = 0;
  468. struct ktd2026_data *data = dev_get_drvdata(dev);
  469. retval = sscanf(buf, "%d", &mode);
  470. if (retval == 0) {
  471. dev_err(&data->client->dev, "fail to get led_pattern mode.\n");
  472. return count;
  473. }
  474. ktd2026_start_led_pattern(mode);
  475. pr_info("%s:led pattern : %d is activated(Type:%d)\n",
  476. __func__, mode, led_lowpower_mode);
  477. return count;
  478. }
  479. static ssize_t store_ktd2026_led_blink(struct device *dev,
  480. struct device_attribute *devattr,
  481. const char *buf, size_t count)
  482. {
  483. /* ex) echo 0x201000 2000 500 > led_blink */
  484. /* brightness r=20 g=10 b=00, ontime=2000ms, offtime=500ms */
  485. /* minimum timeunit of 500ms */
  486. int retval;
  487. unsigned int led_brightness = 0;
  488. unsigned int delay_on_time = 0;
  489. unsigned int delay_off_time = 0;
  490. struct ktd2026_data *data = dev_get_drvdata(dev);
  491. u8 led_r_brightness = 0;
  492. u8 led_g_brightness = 0;
  493. u8 led_b_brightness = 0;
  494. retval = sscanf(buf, "0x%x %d %d", &led_brightness,
  495. &delay_on_time, &delay_off_time);
  496. if (retval == 0) {
  497. dev_err(&data->client->dev, "fail to get led_blink value.\n");
  498. return count;
  499. }
  500. /*Reset ktd2026*/
  501. ktd2026_start_led_pattern(LED_OFF);
  502. /*Set LED blink mode*/
  503. led_r_brightness = ((u32)led_brightness & LED_R_MASK) >> LED_R_SHIFT;
  504. led_g_brightness = ((u32)led_brightness & LED_G_MASK) >> LED_G_SHIFT;
  505. led_b_brightness = ((u32)led_brightness & LED_B_MASK);
  506. ktd2026_set_led_blink(LED_R, delay_on_time,
  507. delay_off_time, led_r_brightness);
  508. ktd2026_set_led_blink(LED_G, delay_on_time,
  509. delay_off_time, led_g_brightness);
  510. ktd2026_set_led_blink(LED_B, delay_on_time,
  511. delay_off_time, led_b_brightness);
  512. leds_i2c_write_all(data->client);
  513. pr_info("%s:led_blink is called, Color:0x%X Brightness:%i\n",
  514. __func__, led_brightness, led_dynamic_current);
  515. return count;
  516. }
  517. void ktd2026_led_blink(int rgb, int on, int off)
  518. {
  519. unsigned int led_brightness = rgb;
  520. unsigned int delay_on_time = on;
  521. unsigned int delay_off_time = off;
  522. u8 led_r_brightness = 0;
  523. u8 led_g_brightness = 0;
  524. u8 led_b_brightness = 0;
  525. /*Reset ktd2026*/
  526. ktd2026_start_led_pattern(LED_OFF);
  527. /*Set LED blink mode*/
  528. led_r_brightness = ((u32)led_brightness & LED_R_MASK) >> LED_R_SHIFT;
  529. led_g_brightness = ((u32)led_brightness & LED_G_MASK) >> LED_G_SHIFT;
  530. led_b_brightness = ((u32)led_brightness & LED_B_MASK);
  531. ktd2026_set_led_blink(LED_R, delay_on_time,
  532. delay_off_time, led_r_brightness);
  533. ktd2026_set_led_blink(LED_G, delay_on_time,
  534. delay_off_time, led_g_brightness);
  535. ktd2026_set_led_blink(LED_B, delay_on_time,
  536. delay_off_time, led_b_brightness);
  537. leds_i2c_write_all(b_client);
  538. pr_info("%s:led_blink is called, Color:0x%X Brightness:%i\n",
  539. __func__, led_brightness, led_dynamic_current);
  540. }
  541. EXPORT_SYMBOL(ktd2026_led_blink);
  542. static ssize_t store_led_r(struct device *dev,
  543. struct device_attribute *devattr, const char *buf, size_t count)
  544. {
  545. struct ktd2026_data *data = dev_get_drvdata(dev);
  546. int ret;
  547. u8 brightness;
  548. ret = kstrtou8(buf, 0, &brightness);
  549. if (ret != 0) {
  550. dev_err(&data->client->dev, "fail to get brightness.\n");
  551. goto out;
  552. }
  553. if (brightness == 0)
  554. ktd2026_leds_on(LED_R, LED_EN_OFF, 0);
  555. else
  556. ktd2026_leds_on(LED_R, LED_EN_ON, brightness);
  557. leds_i2c_write_all(data->client);
  558. out:
  559. return count;
  560. }
  561. static ssize_t store_led_g(struct device *dev,
  562. struct device_attribute *devattr, const char *buf, size_t count)
  563. {
  564. struct ktd2026_data *data = dev_get_drvdata(dev);
  565. int ret;
  566. u8 brightness;
  567. ret = kstrtou8(buf, 0, &brightness);
  568. if (ret != 0) {
  569. dev_err(&data->client->dev, "fail to get brightness.\n");
  570. goto out;
  571. }
  572. if (brightness == 0)
  573. ktd2026_leds_on(LED_G, LED_EN_OFF, 0);
  574. else
  575. ktd2026_leds_on(LED_G, LED_EN_ON, brightness);
  576. leds_i2c_write_all(data->client);
  577. out:
  578. return count;
  579. }
  580. static ssize_t store_led_b(struct device *dev,
  581. struct device_attribute *devattr, const char *buf, size_t count)
  582. {
  583. struct ktd2026_data *data = dev_get_drvdata(dev);
  584. int ret;
  585. u8 brightness;
  586. ret = kstrtou8(buf, 0, &brightness);
  587. if (ret != 0) {
  588. dev_err(&data->client->dev, "fail to get brightness.\n");
  589. goto out;
  590. }
  591. if (brightness == 0)
  592. ktd2026_leds_on(LED_B, LED_EN_OFF, 0);
  593. else
  594. ktd2026_leds_on(LED_B, LED_EN_ON, brightness);
  595. leds_i2c_write_all(data->client);
  596. out:
  597. return count;
  598. }
  599. #endif
  600. /* Added for led common class */
  601. static ssize_t led_delay_on_show(struct device *dev,
  602. struct device_attribute *attr, char *buf)
  603. {
  604. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  605. struct ktd2026_led *led = cdev_to_led(led_cdev);
  606. return sprintf(buf, "%lu\n", led->delay_on_time_ms);
  607. }
  608. static ssize_t led_delay_on_store(struct device *dev,
  609. struct device_attribute *attr,
  610. const char *buf, size_t len)
  611. {
  612. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  613. struct ktd2026_led *led = cdev_to_led(led_cdev);
  614. unsigned long time;
  615. if (kstrtoul(buf, 0, &time))
  616. return -EINVAL;
  617. led->delay_on_time_ms = (int)time;
  618. return len;
  619. }
  620. static ssize_t led_delay_off_show(struct device *dev,
  621. struct device_attribute *attr, char *buf)
  622. {
  623. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  624. struct ktd2026_led *led = cdev_to_led(led_cdev);
  625. return sprintf(buf, "%lu\n", led->delay_off_time_ms);
  626. }
  627. static ssize_t led_delay_off_store(struct device *dev,
  628. struct device_attribute *attr,
  629. const char *buf, size_t len)
  630. {
  631. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  632. struct ktd2026_led *led = cdev_to_led(led_cdev);
  633. unsigned long time;
  634. if (kstrtoul(buf, 0, &time))
  635. return -EINVAL;
  636. led->delay_off_time_ms = (int)time;
  637. return len;
  638. }
  639. static ssize_t led_blink_store(struct device *dev,
  640. struct device_attribute *attr,
  641. const char *buf, size_t len)
  642. {
  643. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  644. struct ktd2026_led *led = cdev_to_led(led_cdev);
  645. unsigned long blink_set;
  646. if (kstrtoul(buf, 0, &blink_set))
  647. return -EINVAL;
  648. if (!blink_set) {
  649. led->delay_on_time_ms = LED_OFF;
  650. ktd2026_set_brightness(led_cdev, LED_OFF);
  651. }
  652. led_blink_set(led_cdev,
  653. &led->delay_on_time_ms, &led->delay_off_time_ms);
  654. return len;
  655. }
  656. /* permission for sysfs node */
  657. static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
  658. static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
  659. static DEVICE_ATTR(blink, 0644, NULL, led_blink_store);
  660. #ifdef SEC_LED_SPECIFIC
  661. /* below nodes is SAMSUNG specific nodes */
  662. static DEVICE_ATTR(led_r, 0664, NULL, store_led_r);
  663. static DEVICE_ATTR(led_g, 0664, NULL, store_led_g);
  664. static DEVICE_ATTR(led_b, 0664, NULL, store_led_b);
  665. /* led_pattern node permission is 664 */
  666. /* To access sysfs node from other groups */
  667. static DEVICE_ATTR(led_pattern, 0664, NULL, \
  668. store_ktd2026_led_pattern);
  669. static DEVICE_ATTR(led_blink, 0664, NULL, \
  670. store_ktd2026_led_blink);
  671. static DEVICE_ATTR(led_br_lev, 0664, NULL, \
  672. store_ktd2026_led_br_lev);
  673. static DEVICE_ATTR(led_brightness, 0664, NULL, \
  674. store_ktd2026_led_brightness);
  675. static DEVICE_ATTR(led_lowpower, 0664, NULL, \
  676. store_ktd2026_led_lowpower);
  677. #endif
  678. static struct attribute *led_class_attrs[] = {
  679. &dev_attr_delay_on.attr,
  680. &dev_attr_delay_off.attr,
  681. &dev_attr_blink.attr,
  682. NULL,
  683. };
  684. static struct attribute_group common_led_attr_group = {
  685. .attrs = led_class_attrs,
  686. };
  687. #ifdef SEC_LED_SPECIFIC
  688. static struct attribute *sec_led_attributes[] = {
  689. &dev_attr_led_r.attr,
  690. &dev_attr_led_g.attr,
  691. &dev_attr_led_b.attr,
  692. &dev_attr_led_pattern.attr,
  693. &dev_attr_led_blink.attr,
  694. &dev_attr_led_br_lev.attr,
  695. &dev_attr_led_brightness.attr,
  696. &dev_attr_led_lowpower.attr,
  697. NULL,
  698. };
  699. static struct attribute_group sec_led_attr_group = {
  700. .attrs = sec_led_attributes,
  701. };
  702. #endif
  703. static int __devinit initialize_channel(struct i2c_client *client,
  704. struct ktd2026_led *led, int channel)
  705. {
  706. struct device *dev = &client->dev;
  707. int ret;
  708. led->channel = channel * 2;
  709. led->cdev.brightness_set = ktd2026_set_brightness;
  710. led->cdev.name = led_conf[channel].name;
  711. led->cdev.brightness = led_conf[channel].brightness;
  712. led->cdev.max_brightness = led_conf[channel].max_brightness;
  713. led->cdev.flags = led_conf[channel].flags;
  714. ret = led_classdev_register(dev, &led->cdev);
  715. if (ret < 0) {
  716. dev_err(dev, "can not register led channel : %d\n", channel);
  717. return ret;
  718. }
  719. ret = sysfs_create_group(&led->cdev.dev->kobj,
  720. &common_led_attr_group);
  721. if (ret < 0) {
  722. dev_err(dev, "can not register sysfs attribute\n");
  723. return ret;
  724. }
  725. return 0;
  726. }
  727. static int __devinit ktd2026_probe(struct i2c_client *client,
  728. const struct i2c_device_id *id)
  729. {
  730. struct ktd2026_data *data;
  731. int ret, i;
  732. pr_info("%s\n", __func__);
  733. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  734. dev_err(&client->dev, "need I2C_FUNC_I2C.\n");
  735. return -ENODEV;
  736. }
  737. if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
  738. dev_err(&client->dev, "need I2C_FUNC_SMBUS_BYTE_DATA.\n");
  739. return -EIO;
  740. }
  741. if (client->dev.of_node) {
  742. data = kzalloc(sizeof(*data), GFP_KERNEL);
  743. if (!data) {
  744. dev_err(&client->adapter->dev,
  745. "failed to allocate driver data.\n");
  746. return -ENOMEM;
  747. }
  748. } else
  749. data = client->dev.platform_data;
  750. i2c_set_clientdata(client, data);
  751. data->client = client;
  752. b_client = client;
  753. mutex_init(&data->mutex);
  754. /* initialize LED */
  755. /* turn off all leds */
  756. ktd2026_leds_on(LED_R, LED_EN_OFF, 0);
  757. #if defined(CONFIG_SEC_FACTORY)
  758. #if defined (CONFIG_SEC_ATLANTIC_PROJECT)
  759. if(batt_id_value == 0)
  760. ret = 1;
  761. else
  762. ret = 0;
  763. #if defined(CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION)
  764. if(get_lcd_attached() == 0) // When LCD Not connected turning RED LED on
  765. ret++;;
  766. #endif
  767. if(jig_power_on_value == 0)
  768. ret++;
  769. if(ret == 3) // case when LCD not connected,battery power on and jig off
  770. ktd2026_leds_on(LED_R, LED_EN_ON, 30);
  771. #endif //ATLANTIC FLAG
  772. #endif
  773. ktd2026_leds_on(LED_G, LED_EN_OFF, 0);
  774. ktd2026_leds_on(LED_B, LED_EN_OFF, 0);
  775. ktd2026_set_timerslot_control(0); /* Tslot1 */
  776. ktd2026_set_period(0);
  777. ktd2026_set_pwm_duty(PWM1, 0);
  778. ktd2026_set_pwm_duty(PWM2, 0);
  779. ktd2026_set_trise_tfall(0, 0, 0);
  780. for (i = 0; i < MAX_NUM_LEDS; i++) {
  781. ret = initialize_channel(client, &data->leds[i], i);
  782. if (ret < 0) {
  783. dev_err(&client->adapter->dev, "failure on initialization\n");
  784. goto exit;
  785. }
  786. INIT_WORK(&(data->leds[i].brightness_work),
  787. ktd2026_led_brightness_work);
  788. }
  789. leds_i2c_write_all(client);
  790. #ifdef SEC_LED_SPECIFIC
  791. led_dev = device_create(sec_class, NULL, 0, data, "led");
  792. if (IS_ERR(led_dev)) {
  793. dev_err(&client->dev,
  794. "Failed to create device for samsung specific led\n");
  795. ret = -ENODEV;
  796. goto exit;
  797. }
  798. ret = sysfs_create_group(&led_dev->kobj, &sec_led_attr_group);
  799. if (ret) {
  800. dev_err(&client->dev,
  801. "Failed to create sysfs group for samsung specific led\n");
  802. goto exit;
  803. }
  804. #endif
  805. return ret;
  806. exit:
  807. mutex_destroy(&data->mutex);
  808. kfree(data);
  809. return ret;
  810. }
  811. static int __devexit ktd2026_remove(struct i2c_client *client)
  812. {
  813. struct ktd2026_data *data = i2c_get_clientdata(client);
  814. int i;
  815. dev_dbg(&client->adapter->dev, "%s\n", __func__);
  816. pr_info("%s\n", __func__);
  817. ktd2026_reset();
  818. #ifdef SEC_LED_SPECIFIC
  819. sysfs_remove_group(&led_dev->kobj, &sec_led_attr_group);
  820. #endif
  821. for (i = 0; i < MAX_NUM_LEDS; i++) {
  822. sysfs_remove_group(&data->leds[i].cdev.dev->kobj,
  823. &common_led_attr_group);
  824. led_classdev_unregister(&data->leds[i].cdev);
  825. cancel_work_sync(&data->leds[i].brightness_work);
  826. }
  827. mutex_destroy(&data->mutex);
  828. kfree(data);
  829. return 0;
  830. }
  831. static void ktd2026_shutdown(struct i2c_client *i2c)
  832. {
  833. pr_info("%s: turn off leds\n", __func__);
  834. ktd2026_reset();
  835. }
  836. static struct i2c_device_id ktd2026_id[] = {
  837. {"ktd2026", 0},
  838. {},
  839. };
  840. #ifdef CONFIG_OF
  841. static struct of_device_id ktd2026_match_table[] = {
  842. { .compatible = "leds,ktd2026",},
  843. { },
  844. };
  845. #else
  846. #define ktd2026_match_table NULL
  847. #endif
  848. MODULE_DEVICE_TABLE(i2c, ktd2026_id);
  849. static struct i2c_driver ktd2026_i2c_driver = {
  850. .driver = {
  851. .owner = THIS_MODULE,
  852. .name = "ktd2026",
  853. .of_match_table = ktd2026_match_table,
  854. },
  855. .id_table = ktd2026_id,
  856. .probe = ktd2026_probe,
  857. .remove = __devexit_p(ktd2026_remove),
  858. .shutdown = ktd2026_shutdown,
  859. };
  860. static int __init ktd2026_init(void)
  861. {
  862. return i2c_add_driver(&ktd2026_i2c_driver);
  863. }
  864. static void __exit ktd2026_exit(void)
  865. {
  866. i2c_del_driver(&ktd2026_i2c_driver);
  867. }
  868. late_initcall(ktd2026_init);
  869. module_exit(ktd2026_exit);
  870. MODULE_DESCRIPTION("KTD2026 LED driver");
  871. MODULE_AUTHOR("Hyoyoung Kim <hyway.kim@samsung.com");
  872. MODULE_LICENSE("GPL");