leds-s2mpb02.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. /*
  2. * LED driver for Samsung S2MPB02
  3. *
  4. * Copyright (C) 2014 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. * This driver is based on leds-max77804.c
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/leds.h>
  16. #include <linux/workqueue.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/slab.h>
  19. #include <linux/module.h>
  20. #include <linux/mfd/samsung/s2mpb02.h>
  21. #include <linux/mfd/samsung/s2mpb02-regulator.h>
  22. #include <linux/leds-s2mpb02.h>
  23. #include <linux/ctype.h>
  24. #include <linux/debugfs.h>
  25. #include <linux/gpio.h>
  26. #include <linux/of_gpio.h>
  27. struct device *s2mpb02_led_dev;
  28. struct s2mpb02_led_data **global_led_datas;
  29. bool sysfs_flash_op;
  30. bool flash_config_factory;
  31. #ifdef S2MPB02_FLED_CHANNEL_1
  32. #define S2MPB02_REG_FLED_CTRL S2MPB02_REG_FLED_CTRL1
  33. #define S2MPB02_REG_FLED_CUR S2MPB02_REG_FLED_CUR1
  34. #define S2MPB02_REG_FLED_TIME S2MPB02_REG_FLED_TIME1
  35. #else
  36. #define S2MPB02_REG_FLED_CTRL S2MPB02_REG_FLED_CTRL2
  37. #define S2MPB02_REG_FLED_CUR S2MPB02_REG_FLED_CUR2
  38. #define S2MPB02_REG_FLED_TIME S2MPB02_REG_FLED_TIME2
  39. #endif
  40. //#define DEBUG_READ_REGISTER //To dump register values with /sys/kernel/debug/s2mpb02-led-regs
  41. //#define DEBUG_WRITE_REGISTER //To write register with sysfs
  42. struct s2mpb02_led_data {
  43. struct led_classdev led;
  44. struct s2mpb02_dev *s2mpb02;
  45. struct s2mpb02_led *data;
  46. struct i2c_client *i2c;
  47. struct work_struct work;
  48. struct mutex lock;
  49. spinlock_t value_lock;
  50. int brightness;
  51. };
  52. static u8 leds_mask[S2MPB02_LED_MAX] = {
  53. S2MPB02_FLASH_MASK,
  54. S2MPB02_TORCH_MASK,
  55. };
  56. static u8 leds_shift[S2MPB02_LED_MAX] = {
  57. 4,
  58. 0,
  59. };
  60. #if defined(DEBUG_READ_REGISTER)
  61. #if 0
  62. static void print_all_reg_value(struct i2c_client *client)
  63. {
  64. int ret;
  65. u8 value;
  66. u8 i;
  67. for (i = 0; i <= S2MPB02_REG_LDO_DSCH3; i++) {
  68. ret = s2mpb02_read_reg(client, i, &value);
  69. if (unlikely(ret < 0))
  70. pr_err("[s2mpb02-LED][%s] read failed", __func__);
  71. pr_err("[s2mpb02-LED] register(%x) = %x\n", i, value);
  72. value = 0;
  73. }
  74. }
  75. #endif
  76. static int s2mpb02_debugfs_show(struct seq_file *s, void *data)
  77. {
  78. struct s2mpb02_dev *ldata = s->private;
  79. u8 reg;
  80. u8 reg_data;
  81. int ret;
  82. seq_printf(s, "s2mpb02 IF PMIC :\n");
  83. seq_printf(s, "=============\n");
  84. for (reg = 0; reg <= S2MPB02_REG_LDO_DSCH3; reg++) {
  85. ret = s2mpb02_read_reg(ldata->i2c, reg, &reg_data);
  86. if (unlikely(ret < 0)) {
  87. pr_err("[s2mpb02-LED][%s] read failed", __func__);
  88. }
  89. seq_printf(s, "0x%02x:\t0x%02x\n", reg, reg_data);
  90. }
  91. //print_all_reg_value(ldata->i2c);
  92. seq_printf(s, "\n");
  93. return 0;
  94. }
  95. static int s2mpb02_debugfs_open(struct inode *inode, struct file *file)
  96. {
  97. return single_open(file, s2mpb02_debugfs_show, inode->i_private);
  98. }
  99. static const struct file_operations s2mpb02_debugfs_fops = {
  100. .open = s2mpb02_debugfs_open,
  101. .read = seq_read,
  102. .llseek = seq_lseek,
  103. .release = single_release,
  104. };
  105. #endif
  106. static int s2mpb02_set_bits(struct i2c_client *client, const u8 reg,
  107. const u8 mask, const u8 inval)
  108. {
  109. int ret;
  110. u8 value;
  111. ret = s2mpb02_read_reg(client, reg, &value);
  112. if (unlikely(ret < 0))
  113. return ret;
  114. value = (value & ~mask) | (inval & mask);
  115. ret = s2mpb02_write_reg(client, reg, value);
  116. return ret;
  117. }
  118. static int s2mpb02_led_get_en_value(struct s2mpb02_led_data *led_data, int on)
  119. {
  120. if (on) {
  121. if (led_data->data->id == S2MPB02_FLASH_LED_1)
  122. return ((S2MPB02_FLED_ENABLE << S2MPB02_FLED_ENABLE_SHIFT) |
  123. (S2MPB02_FLED_FLASH_MODE << S2MPB02_FLED_MODE_SHIFT));
  124. /* Turn on FLASH by I2C */
  125. else
  126. return ((S2MPB02_FLED_ENABLE << S2MPB02_FLED_ENABLE_SHIFT) |
  127. (S2MPB02_FLED_TORCH_MODE << S2MPB02_FLED_MODE_SHIFT));
  128. /* Turn on TORCH by I2C */
  129. } else
  130. return (S2MPB02_FLED_DISABLE << S2MPB02_FLED_ENABLE_SHIFT);
  131. /* controlled by GPIO */
  132. }
  133. static void s2mpb02_led_set(struct led_classdev *led_cdev,
  134. enum led_brightness value)
  135. {
  136. unsigned long flags;
  137. struct s2mpb02_led_data *led_data
  138. = container_of(led_cdev, struct s2mpb02_led_data, led);
  139. pr_debug("[LED] %s\n", __func__);
  140. spin_lock_irqsave(&led_data->value_lock, flags);
  141. led_data->data->brightness = min_t(int, (int)value, (int)led_cdev->max_brightness);
  142. spin_unlock_irqrestore(&led_data->value_lock, flags);
  143. schedule_work(&led_data->work);
  144. }
  145. static void led_set(struct s2mpb02_led_data *led_data, enum s2mpb02_led_turn_way turn_way)
  146. {
  147. int ret;
  148. struct s2mpb02_led *data = led_data->data;
  149. int id = data->id;
  150. int value = 0;
  151. if (turn_way == S2MPB02_LED_TURN_WAY_GPIO) {
  152. /* First turn off LED turned on by I2C */
  153. value = s2mpb02_led_get_en_value(led_data, 0);
  154. ret = s2mpb02_set_bits(led_data->i2c,
  155. S2MPB02_REG_FLED_CTRL1, S2MPB02_FLED_ENABLE_MODE_MASK, value);
  156. if (unlikely(ret))
  157. goto error_set_bits;
  158. /* Turn way LED by GPIO */
  159. /* set current */
  160. ret = s2mpb02_set_bits(led_data->i2c, S2MPB02_REG_FLED_CUR1,
  161. leds_mask[id], data->brightness << leds_shift[id]);
  162. if (unlikely(ret))
  163. goto error_set_bits;
  164. value = led_data->data->brightness ? 1 : 0;
  165. gpio_request(led_data->data->gpio, NULL);
  166. gpio_direction_output(led_data->data->gpio, value);
  167. gpio_free(led_data->data->gpio);
  168. } else {
  169. if (led_data->data->brightness == LED_OFF) {
  170. value = s2mpb02_led_get_en_value(led_data, 0);
  171. ret = s2mpb02_set_bits(led_data->i2c,
  172. S2MPB02_REG_FLED_CTRL1, S2MPB02_FLED_ENABLE_MODE_MASK, value);
  173. if (unlikely(ret))
  174. goto error_set_bits;
  175. }
  176. /* set current */
  177. ret = s2mpb02_set_bits(led_data->i2c, S2MPB02_REG_FLED_CUR1,
  178. leds_mask[id], data->brightness << leds_shift[id]);
  179. if (unlikely(ret))
  180. goto error_set_bits;
  181. if (led_data->data->brightness != LED_OFF) {
  182. /* Turn on LED by I2C */
  183. value = s2mpb02_led_get_en_value(led_data, 1);
  184. ret = s2mpb02_set_bits(led_data->i2c,
  185. S2MPB02_REG_FLED_CTRL1, S2MPB02_FLED_ENABLE_MODE_MASK, value);
  186. if (unlikely(ret))
  187. goto error_set_bits;
  188. }
  189. }
  190. return;
  191. error_set_bits:
  192. pr_err("%s: can't set led level %d\n", __func__, ret);
  193. return;
  194. }
  195. static void s2mpb02_led_work(struct work_struct *work)
  196. {
  197. struct s2mpb02_led_data *led_data
  198. = container_of(work, struct s2mpb02_led_data, work);
  199. pr_debug("[LED] %s\n", __func__);
  200. if (sysfs_flash_op) {
  201. pr_warn("%s : The camera led control is not allowed"
  202. "because sysfs led control already used it\n", __FUNCTION__);
  203. return;
  204. }
  205. mutex_lock(&led_data->lock);
  206. led_set(led_data, S2MPB02_LED_TURN_WAY_I2C);
  207. mutex_unlock(&led_data->lock);
  208. }
  209. static int s2mpb02_led_setup(struct s2mpb02_led_data *led_data)
  210. {
  211. int ret = 0;
  212. struct s2mpb02_led *data = led_data->data;
  213. int id = data->id;
  214. int value;
  215. /* Disable Low Voltage operating mode control */
  216. ret |= s2mpb02_update_reg(led_data->i2c, S2MPB02_REG_FLED_CTRL1,
  217. S2MPB02_FLED_CTRL1_LV_DISABLE, S2MPB02_FLED_CTRL1_LV_EN_MASK);
  218. /* set operating minimum voltage */
  219. ret |= s2mpb02_update_reg(led_data->i2c, S2MPB02_REG_FLED_CTRL1,
  220. S2MPB02_LV_SEL_VOLT(3000), S2MPB02_LV_SEL_VOUT_MASK);
  221. /* set current & timeout */
  222. ret |= s2mpb02_update_reg(led_data->i2c, S2MPB02_REG_FLED_CUR1,
  223. data->brightness << leds_shift[id], leds_mask[id]);
  224. ret |= s2mpb02_update_reg(led_data->i2c, S2MPB02_REG_FLED_TIME1,
  225. data->timeout << leds_shift[id], leds_mask[id]);
  226. value = s2mpb02_led_get_en_value(led_data, 0);
  227. ret |= s2mpb02_update_reg(led_data->i2c,
  228. S2MPB02_REG_FLED_CTRL1, value, S2MPB02_FLED_ENABLE_MODE_MASK);
  229. #if defined(CONFIG_SAMSUNG_SECURE_CAMERA)
  230. ret |= s2mpb02_ir_led_init();
  231. #endif
  232. return ret;
  233. }
  234. void s2mpb02_led_get_status(struct led_classdev *led_cdev, bool status, bool onoff)
  235. {
  236. int ret = 0;
  237. u8 value[6] = {0, };
  238. struct s2mpb02_led_data *led_data
  239. = container_of(led_cdev, struct s2mpb02_led_data, led);
  240. ret = s2mpb02_read_reg(led_data->i2c, 0x12, &value[0]); //Fled_ctrl1
  241. ret |= s2mpb02_read_reg(led_data->i2c, 0x13, &value[1]); //Fled_ctrl2
  242. ret |= s2mpb02_read_reg(led_data->i2c, 0x14, &value[2]); //Fled_cur1
  243. ret |= s2mpb02_read_reg(led_data->i2c, 0x15, &value[3]); //Fled_time1
  244. ret |= s2mpb02_read_reg(led_data->i2c, 0x16, &value[4]); //Fled_cur2
  245. ret |= s2mpb02_read_reg(led_data->i2c, 0x17, &value[5]); //Fled_time2
  246. if (unlikely(ret < 0)) {
  247. printk("%s : error to get dt node\n", __func__);
  248. }
  249. printk("%s[%d, %d] : Fled_ctrl1 = 0x%12x, Fled_ctrl2 = 0x%13x, Fled_cur1 = 0x%14x, "
  250. "Fled_time1 = 0x%15x, Fled_cur2 = 0x%16x, Fled_time2 = 0x%17x\n",
  251. __func__, status, onoff, value[0], value[1], value[2], value[3], value[4], value[5]);
  252. }
  253. int s2mpb02_led_en(int mode, int onoff, enum s2mpb02_led_turn_way turn_way)
  254. {
  255. int ret = 0;
  256. int i = 0;
  257. if (global_led_datas == NULL) {
  258. pr_err("<%s> global_led_datas is NULL\n", __func__);
  259. return -1;
  260. }
  261. for (i = 0; i < S2MPB02_LED_MAX; i++) {
  262. if (global_led_datas[i] == NULL) {
  263. pr_err("<%s> global_led_datas[%d] is NULL\n", __func__, i);
  264. return -1;
  265. }
  266. }
  267. if (onoff > 0) {/* enable */
  268. pr_info("<%s> enable %d, %d\n", __func__, onoff, mode);
  269. if (mode == S2MPB02_TORCH_LED_1) {
  270. if (onoff >= S2MPB02_TORCH_OUT_I_MAX)
  271. onoff = S2MPB02_TORCH_OUT_I_MAX-1;
  272. } else if (mode == S2MPB02_FLASH_LED_1) {
  273. if (onoff >= S2MPB02_FLASH_OUT_I_MAX)
  274. onoff = S2MPB02_FLASH_OUT_I_MAX-1;
  275. } else {
  276. pr_err("<%s> mode %d is invalid\n", __func__, mode);
  277. return -1;
  278. }
  279. global_led_datas[mode]->data->brightness = onoff;
  280. } else {/* disable */
  281. pr_info("<%s> disable %d, %d\n", __func__, onoff, mode);
  282. global_led_datas[mode]->data->brightness = 0;
  283. }
  284. led_set(global_led_datas[mode], turn_way);
  285. return ret;
  286. }
  287. EXPORT_SYMBOL(s2mpb02_led_en);
  288. #ifdef DEBUG_WRITE_REGISTER
  289. ssize_t s2mpb02_write(struct device *dev,
  290. struct device_attribute *attr, const char *buf,
  291. size_t count)
  292. {
  293. unsigned int value = 0;
  294. unsigned char reg = 0;
  295. unsigned char data = 0;
  296. if (buf == NULL || kstrtouint(buf, 16, &value)) {
  297. pr_err("[%s] error buf is NULL\n", __func__);
  298. return -1;
  299. }
  300. reg = value >> 8;
  301. data = value & 0xFF;
  302. pr_info("[%s] reg: %x, data: %x\n", __func__, reg, data);
  303. s2mpb02_write_reg(global_led_datas[0]->i2c, reg, data);
  304. return count;
  305. }
  306. static DEVICE_ATTR(s2mpb02_cam_reg, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH,
  307. NULL, s2mpb02_write);
  308. #endif
  309. #if defined(CONFIG_SAMSUNG_SECURE_CAMERA)
  310. int s2mpb02_ir_led_init(void)
  311. {
  312. int ret = 0;
  313. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_CTRL2, 0x38);
  314. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_CUR2, 0xAF);
  315. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_TIME2, 0x34);
  316. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_TIME2, 0x35);
  317. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRON1, 0x19);
  318. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRON2, 0x0B);
  319. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRD1, 0x00);
  320. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRD2, 0X2C);
  321. #if 1 //TEMP_845
  322. s2mpb02_ir_led_current(5);
  323. s2mpb02_ir_led_pulse_width(240);
  324. s2mpb02_ir_led_pulse_delay(0);
  325. s2mpb02_ir_led_max_time(0);
  326. #endif
  327. return ret;
  328. }
  329. EXPORT_SYMBOL(s2mpb02_ir_led_init);
  330. int s2mpb02_ir_led_current(int32_t current_value)
  331. {
  332. int ret = 0;
  333. unsigned int value = 0;
  334. unsigned char data = 0;
  335. if (current_value > 0)
  336. value = current_value - 1;
  337. pr_info("[%s] led current value : %u [current_value::%d]\n", __func__, value, current_value);
  338. data = ((value & 0x0F) << 4) | 0x0F;
  339. ret = s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_CUR2, data);
  340. if (ret < 0)
  341. pr_err("[%s] i2c write error", __func__);
  342. return ret;
  343. }
  344. EXPORT_SYMBOL(s2mpb02_ir_led_current);
  345. int s2mpb02_ir_led_pulse_width(int32_t width)
  346. {
  347. unsigned int value = width;
  348. unsigned char iron1 = 0;
  349. unsigned char iron2 = 0;
  350. int ret = 0;
  351. pr_info("[%s] led pulse_width value : %u\n", __func__, value);
  352. iron1 = (value >> 2) & 0xFF;
  353. iron2 = ((value & 0x03) << 6) | 0x0B;
  354. pr_info("[%s] IRON1(0x%02x), IRON2(0x%02x)\n", __func__, iron1, iron2);
  355. /* set 0x18, 0x19 */
  356. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRON1, iron1);
  357. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRON2, iron2);
  358. if (ret < 0)
  359. pr_err("[%s] i2c write error", __func__);
  360. return ret;
  361. }
  362. EXPORT_SYMBOL(s2mpb02_ir_led_pulse_width);
  363. int s2mpb02_ir_led_pulse_delay(int32_t delay)
  364. {
  365. unsigned int value = delay;
  366. unsigned char ird1 = 0;
  367. unsigned char ird2 = 0;
  368. int ret = 0;
  369. pr_info("[%s] led pulse_delay value : %u\n", __func__, value);
  370. ird1 = (value >> 2) & 0xFF;
  371. ird2 = ((value & 0x03) << 6) | 0x2C; /* value 0x2C means RSVD[5:0] Reserved */
  372. pr_info("[%s] IRD1(0x%02x), IRD2(0x%02x)\n", __func__, ird1, ird2);
  373. /* set 0x18, 0x19 */
  374. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRD1, ird1);
  375. ret |= s2mpb02_write_reg(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRD2, ird2);
  376. if (ret < 0)
  377. pr_err("[%s] i2c write error", __func__);
  378. return ret;
  379. }
  380. EXPORT_SYMBOL(s2mpb02_ir_led_pulse_delay);
  381. int s2mpb02_ir_led_max_time(int32_t max_time)
  382. {
  383. int ret = 0;
  384. pr_info("[%s] led max_time value : %u\n", __func__, max_time);
  385. ret |= s2mpb02_set_bits(global_led_datas[0]->i2c, S2MPB02_REG_FLED_CTRL2,
  386. S2MPB02_FLED2_MAX_TIME_CLEAR_MASK, 0x00);
  387. ret |= s2mpb02_set_bits(global_led_datas[0]->i2c, S2MPB02_REG_FLED_TIME2,
  388. S2MPB02_FLED2_MAX_TIME_EN_MASK, 0x00);
  389. if (max_time > 0) {
  390. ret |= s2mpb02_set_bits(global_led_datas[0]->i2c, S2MPB02_REG_FLED_TIME2,
  391. S2MPB02_FLED2_MAX_TIME_EN_MASK, 0x01);
  392. ret |= s2mpb02_set_bits(global_led_datas[0]->i2c, S2MPB02_REG_FLED_IRON2,
  393. S2MPB02_FLED2_MAX_TIME_MASK, (u8) max_time - 1);
  394. }
  395. return ret;
  396. }
  397. EXPORT_SYMBOL(s2mpb02_ir_led_max_time);
  398. #endif
  399. ssize_t s2mpb02_store(const char *buf)
  400. {
  401. int i = 0, ret = 0;
  402. int onoff = -1;
  403. sysfs_flash_op = 0;
  404. if (buf == NULL || kstrtouint(buf, 10, &onoff))
  405. return -1;
  406. if (global_led_datas == NULL) {
  407. pr_err("<%s> global_led_datas is NULL\n", __func__);
  408. return -1;
  409. }
  410. for (i = 0; i < S2MPB02_LED_MAX; i++) {
  411. if (global_led_datas[i] == NULL) {
  412. pr_err("<%s> global_led_datas[%d] is NULL\n", __func__, i);
  413. return -1;
  414. }
  415. }
  416. pr_info("<%s> sysfs torch/flash value %d\n", __func__, onoff);
  417. if (onoff == 0) {
  418. // Torch OFF
  419. onoff = 0;
  420. } else if (onoff == 1) {
  421. // Torch ON
  422. onoff = S2MPB02_TORCH_OUT_I_60MA;
  423. } else if (onoff == 100) {
  424. // Factory Torch ON
  425. onoff = S2MPB02_TORCH_OUT_I_240MA;
  426. } else if (onoff == 200) {
  427. pr_info("<%s> sysfs flash value %d\n", __func__, onoff);
  428. /* Factory mode Turn on Flash */
  429. /* set reserved reg. 0x63 for continuous flash on */
  430. flash_config_factory = true;
  431. ret = s2mpb02_write_reg(global_led_datas[S2MPB02_FLASH_LED_1]->i2c, 0x63, 0x5F);
  432. if (ret < 0)
  433. pr_info("[LED]%s , failed set flash register setting\n", __func__);
  434. onoff = S2MPB02_FLASH_OUT_I_300MA;
  435. } else if (onoff == 1001) {
  436. // level 1 (Flashlight level 1)
  437. onoff = S2MPB02_TORCH_OUT_I_40MA;
  438. } else if (onoff == 1002) {
  439. // level 2 (Flashlight level 2)
  440. onoff = S2MPB02_TORCH_OUT_I_60MA;
  441. } else if (onoff == 1003) {
  442. // level 3
  443. onoff = S2MPB02_TORCH_OUT_I_80MA;
  444. } else if (onoff == 1004) {
  445. // level 4 (Flashlight level 3)
  446. onoff = S2MPB02_TORCH_OUT_I_100MA;
  447. } else if (onoff == 1005) {
  448. // level 5
  449. onoff = S2MPB02_TORCH_OUT_I_120MA;
  450. } else if (onoff == 1006) {
  451. // level 6 (Flashlight level 4)
  452. onoff = S2MPB02_TORCH_OUT_I_160MA;
  453. } else if (onoff == 1007) {
  454. // level 7
  455. onoff = S2MPB02_TORCH_OUT_I_180MA;
  456. } else if (onoff == 1008) {
  457. // level 8
  458. onoff = S2MPB02_TORCH_OUT_I_180MA;
  459. } else if (onoff == 1009) {
  460. // level 9 (Flashlight level 5)
  461. onoff = S2MPB02_TORCH_OUT_I_200MA;
  462. } else if (onoff == 1010) {
  463. // level 10
  464. onoff = S2MPB02_TORCH_OUT_I_200MA;
  465. } else if ((2001 <= onoff) && (onoff <= 2015)) {
  466. // Torch ON for tunning : Step 20mA ~ 300mA
  467. onoff = onoff - 2000;
  468. pr_info("<%s> torch level %d\n", __func__, onoff);
  469. } else {
  470. pr_err("<%s> value %d is invalid\n", __func__, onoff);
  471. onoff = 0;
  472. }
  473. if (flash_config_factory) {
  474. if (onoff == 0) {
  475. s2mpb02_write_reg(global_led_datas[S2MPB02_FLASH_LED_1]->i2c, 0x63, 0x7F);
  476. flash_config_factory = false;
  477. }
  478. #if defined(S2MPB02_FLED_CONTROLED_BY_GPIO)
  479. s2mpb02_led_en(S2MPB02_FLASH_LED_1, onoff, S2MPB02_LED_TURN_WAY_GPIO);
  480. #else
  481. s2mpb02_led_en(S2MPB02_FLASH_LED_1, onoff, S2MPB02_LED_TURN_WAY_I2C);
  482. #endif
  483. } else
  484. #if defined(S2MPB02_FLED_CONTROLED_BY_GPIO)
  485. s2mpb02_led_en(S2MPB02_TORCH_LED_1, onoff, S2MPB02_LED_TURN_WAY_GPIO);
  486. #else
  487. s2mpb02_led_en(S2MPB02_TORCH_LED_1, onoff, S2MPB02_LED_TURN_WAY_I2C);
  488. #endif
  489. if (onoff)
  490. sysfs_flash_op = 1;
  491. return 0;
  492. }
  493. EXPORT_SYMBOL(s2mpb02_store);
  494. ssize_t s2mpb02_show(char *buf)
  495. {
  496. int i = 0;
  497. if (global_led_datas == NULL) {
  498. pr_err("<%s> global_led_datas is NULL\n", __func__);
  499. return sprintf(buf, "%d\n", -1);
  500. }
  501. for (i = 0; i < S2MPB02_LED_MAX; i++) {
  502. if (global_led_datas[i] == NULL) {
  503. pr_err("<%s> global_led_datas[%d] is NULL\n", __func__, i);
  504. return sprintf(buf, "%d\n", -1);
  505. }
  506. }
  507. if (global_led_datas[S2MPB02_TORCH_LED_1]->data->brightness == LED_OFF) {
  508. return sprintf(buf, "%d\n", 0);
  509. } else {
  510. return sprintf(buf, "%d\n", global_led_datas[S2MPB02_TORCH_LED_1]->data->brightness);
  511. }
  512. }
  513. EXPORT_SYMBOL(s2mpb02_show);
  514. #if defined(CONFIG_OF)
  515. static int of_s2mpb02_led_dt(struct s2mpb02_dev *iodev,
  516. struct s2mpb02_led_platform_data *pdata)
  517. {
  518. struct device_node *led_np, *np, *c_np;
  519. int ret;
  520. u32 temp;
  521. const char *temp_str;
  522. int index;
  523. led_np = iodev->dev->of_node;
  524. if (!led_np) {
  525. pr_err("<%s> could not find led sub-node\n", __func__);
  526. return -ENODEV;
  527. }
  528. np = of_find_node_by_name(led_np, "torch");
  529. if (!np) {
  530. pr_err("<%s> could not find led sub-node\n",
  531. __func__);
  532. return -EINVAL;
  533. }
  534. pdata->num_leds = of_get_child_count(np);
  535. for_each_child_of_node(np, c_np) {
  536. ret = of_property_read_u32(c_np, "id", &temp);
  537. if (ret < 0)
  538. goto dt_err;
  539. index = temp;
  540. pdata->leds[index].id = temp;
  541. ret = of_property_read_string(c_np, "ledname", &temp_str);
  542. if (ret < 0)
  543. goto dt_err;
  544. pdata->leds[index].name = temp_str;
  545. ret = of_property_read_u32(c_np, "brightness", &temp);
  546. if (ret < 0)
  547. goto dt_err;
  548. if (temp > S2MPB02_FLASH_TORCH_CURRENT_MAX)
  549. temp = S2MPB02_FLASH_TORCH_CURRENT_MAX;
  550. pdata->leds[index].brightness = temp;
  551. ret = of_property_read_u32(c_np, "timeout", &temp);
  552. if (ret < 0)
  553. goto dt_err;
  554. if (temp > S2MPB02_TIMEOUT_MAX)
  555. temp = S2MPB02_TIMEOUT_MAX;
  556. pdata->leds[index].timeout = temp;
  557. ret = of_property_read_string(c_np, "default-trigger", &temp_str);
  558. if (ret < 0)
  559. goto dt_err;
  560. pdata->leds[index].default_trigger = temp_str;
  561. #if defined(S2MPB02_FLED_CONTROLED_BY_GPIO)
  562. temp = of_gpio_count(c_np);
  563. if (temp > 0) {
  564. pdata->leds[index].gpio = of_get_gpio(c_np, 0);
  565. }
  566. #endif
  567. }
  568. of_node_put(led_np);
  569. return 0;
  570. dt_err:
  571. pr_err("%s failed to get a dt info\n", __func__);
  572. return ret;
  573. }
  574. #endif /* CONFIG_OF */
  575. static int s2mpb02_led_probe(struct platform_device *pdev)
  576. {
  577. int ret = 0;
  578. int i;
  579. struct s2mpb02_dev *s2mpb02 = dev_get_drvdata(pdev->dev.parent);
  580. #ifndef CONFIG_OF
  581. struct s2mpb02_platform_data *s2mpb02_pdata
  582. = dev_get_platdata(s2mpb02->dev);
  583. #endif
  584. struct s2mpb02_led_platform_data *pdata;
  585. struct s2mpb02_led_data *led_data;
  586. struct s2mpb02_led *data;
  587. struct s2mpb02_led_data **led_datas;
  588. #ifdef CONFIG_OF
  589. pdata = kzalloc(sizeof(struct s2mpb02_led_platform_data), GFP_KERNEL);
  590. if (!pdata) {
  591. pr_err("%s: failed to allocate driver data\n", __func__);
  592. return -ENOMEM;
  593. }
  594. ret = of_s2mpb02_led_dt(s2mpb02, pdata);
  595. if (ret < 0) {
  596. pr_err("s2mpb02-torch : %s not found torch dt! ret[%d]\n",
  597. __func__, ret);
  598. kfree(pdata);
  599. return ret;
  600. }
  601. #else
  602. pdata = s2mpb02_pdata->led_data;
  603. if (pdata == NULL) {
  604. pr_err("[LED] no platform data for this led is found\n");
  605. return -EFAULT;
  606. }
  607. #endif
  608. sysfs_flash_op = 0; //default off
  609. global_led_datas = kzalloc(sizeof(struct s2mpb02_led_data *)*S2MPB02_LED_MAX, GFP_KERNEL);
  610. led_datas = kzalloc(sizeof(struct s2mpb02_led_data *)
  611. * S2MPB02_LED_MAX, GFP_KERNEL);
  612. if (unlikely(!led_datas)) {
  613. pr_err("[LED] memory allocation error %s", __func__);
  614. kfree(pdata);
  615. return -ENOMEM;
  616. }
  617. platform_set_drvdata(pdev, led_datas);
  618. pr_info("[LED] %s %d leds\n", __func__, pdata->num_leds);
  619. for (i = 0; i != pdata->num_leds; ++i) {
  620. pr_info("%s led%d setup ...\n", __func__, i);
  621. data = kzalloc(sizeof(struct s2mpb02_led), GFP_KERNEL);
  622. if (unlikely(!data)) {
  623. pr_err("[LED] memory allocation error %s\n", __func__);
  624. ret = -ENOMEM;
  625. continue;
  626. }
  627. memcpy(data, &(pdata->leds[i]), sizeof(struct s2mpb02_led));
  628. led_data = kzalloc(sizeof(struct s2mpb02_led_data),
  629. GFP_KERNEL);
  630. global_led_datas[i] = led_data;
  631. led_datas[i] = led_data;
  632. if (unlikely(!led_data)) {
  633. pr_err("[LED] memory allocation error %s\n", __func__);
  634. ret = -ENOMEM;
  635. kfree(data);
  636. continue;
  637. }
  638. led_data->s2mpb02 = s2mpb02;
  639. led_data->i2c = s2mpb02->i2c;
  640. led_data->data = data;
  641. led_data->led.name = data->name;
  642. led_data->led.brightness_set = s2mpb02_led_set;
  643. led_data->led.brightness = LED_OFF;
  644. led_data->brightness = data->brightness;
  645. led_data->led.flags = 0;
  646. led_data->led.max_brightness = LED_FULL;
  647. led_data->led.default_trigger = data->default_trigger;
  648. mutex_init(&led_data->lock);
  649. spin_lock_init(&led_data->value_lock);
  650. INIT_WORK(&led_data->work, s2mpb02_led_work);
  651. ret = led_classdev_register(&pdev->dev, &led_data->led);
  652. if (unlikely(ret)) {
  653. pr_err("unable to register LED\n");
  654. cancel_work_sync(&led_data->work);
  655. mutex_destroy(&led_data->lock);
  656. kfree(data);
  657. kfree(led_data);
  658. led_datas[i] = NULL;
  659. ret = -EFAULT;
  660. continue;
  661. }
  662. ret = s2mpb02_led_setup(led_data);
  663. if (unlikely(ret)) {
  664. pr_err("unable to register LED\n");
  665. cancel_work_sync(&led_data->work);
  666. mutex_destroy(&led_data->lock);
  667. led_classdev_unregister(&led_data->led);
  668. kfree(data);
  669. kfree(led_data);
  670. led_datas[i] = NULL;
  671. ret = -EFAULT;
  672. }
  673. }
  674. #if defined(DEBUG_READ_REGISTER)
  675. (void)debugfs_create_file("s2mpb02-led-regs", S_IRUGO, NULL,
  676. (void *)s2mpb02, &s2mpb02_debugfs_fops);
  677. #endif
  678. #ifdef CONFIG_OF
  679. kfree(pdata);
  680. #endif
  681. pr_info("<%s> end\n", __func__);
  682. return ret;
  683. }
  684. static int s2mpb02_led_remove(struct platform_device *pdev)
  685. {
  686. struct s2mpb02_led_data **led_datas = platform_get_drvdata(pdev);
  687. int i;
  688. for (i = 0; i != S2MPB02_LED_MAX; ++i) {
  689. if (led_datas[i] == NULL)
  690. continue;
  691. cancel_work_sync(&led_datas[i]->work);
  692. mutex_destroy(&led_datas[i]->lock);
  693. led_classdev_unregister(&led_datas[i]->led);
  694. kfree(led_datas[i]->data);
  695. kfree(led_datas[i]);
  696. }
  697. kfree(led_datas);
  698. if (global_led_datas != NULL)
  699. kfree(global_led_datas);
  700. return 0;
  701. }
  702. static struct platform_driver s2mpb02_led_driver = {
  703. .probe = s2mpb02_led_probe,
  704. .remove = s2mpb02_led_remove,
  705. .driver = {
  706. .name = "s2mpb02-led",
  707. .owner = THIS_MODULE,
  708. .suppress_bind_attrs = true,
  709. },
  710. };
  711. static int __init s2mpb02_led_init(void)
  712. {
  713. return platform_driver_register(&s2mpb02_led_driver);
  714. }
  715. module_init(s2mpb02_led_init);
  716. static void __exit s2mpb02_led_exit(void)
  717. {
  718. platform_driver_unregister(&s2mpb02_led_driver);
  719. }
  720. module_exit(s2mpb02_led_exit);
  721. MODULE_DESCRIPTION("S2MPB02 LED driver");
  722. MODULE_LICENSE("GPL");
  723. MODULE_SOFTDEP("pre: s2mpb02-regulator");