leds-lm3556.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /*
  2. * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
  3. * Copyright (C) 2012 Texas Instruments
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Please refer Documentation/leds/leds-lm3556.txt file.
  10. */
  11. #include <linux/module.h>
  12. #include <linux/delay.h>
  13. #include <linux/i2c.h>
  14. #include <linux/leds.h>
  15. #include <linux/slab.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/fs.h>
  18. #include <linux/regmap.h>
  19. #include <linux/platform_data/leds-lm3556.h>
  20. #define REG_FILT_TIME (0x0)
  21. #define REG_IVFM_MODE (0x1)
  22. #define REG_NTC (0x2)
  23. #define REG_INDIC_TIME (0x3)
  24. #define REG_INDIC_BLINK (0x4)
  25. #define REG_INDIC_PERIOD (0x5)
  26. #define REG_TORCH_TIME (0x6)
  27. #define REG_CONF (0x7)
  28. #define REG_FLASH (0x8)
  29. #define REG_I_CTRL (0x9)
  30. #define REG_ENABLE (0xA)
  31. #define REG_FLAG (0xB)
  32. #define REG_MAX (0xB)
  33. #define IVFM_FILTER_TIME_SHIFT (3)
  34. #define UVLO_EN_SHIFT (7)
  35. #define HYSTERSIS_SHIFT (5)
  36. #define IVM_D_TH_SHIFT (2)
  37. #define IVFM_ADJ_MODE_SHIFT (0)
  38. #define NTC_EVENT_LVL_SHIFT (5)
  39. #define NTC_TRIP_TH_SHIFT (2)
  40. #define NTC_BIAS_I_LVL_SHIFT (0)
  41. #define INDIC_RAMP_UP_TIME_SHIFT (3)
  42. #define INDIC_RAMP_DN_TIME_SHIFT (0)
  43. #define INDIC_N_BLANK_SHIFT (4)
  44. #define INDIC_PULSE_TIME_SHIFT (0)
  45. #define INDIC_N_PERIOD_SHIFT (0)
  46. #define TORCH_RAMP_UP_TIME_SHIFT (3)
  47. #define TORCH_RAMP_DN_TIME_SHIFT (0)
  48. #define STROBE_USUAGE_SHIFT (7)
  49. #define STROBE_PIN_POLARITY_SHIFT (6)
  50. #define TORCH_PIN_POLARITY_SHIFT (5)
  51. #define TX_PIN_POLARITY_SHIFT (4)
  52. #define TX_EVENT_LVL_SHIFT (3)
  53. #define IVFM_EN_SHIFT (2)
  54. #define NTC_MODE_SHIFT (1)
  55. #define INDIC_MODE_SHIFT (0)
  56. #define INDUCTOR_I_LIMIT_SHIFT (6)
  57. #define FLASH_RAMP_TIME_SHIFT (3)
  58. #define FLASH_TOUT_TIME_SHIFT (0)
  59. #define TORCH_I_SHIFT (4)
  60. #define FLASH_I_SHIFT (0)
  61. #define NTC_EN_SHIFT (7)
  62. #define TX_PIN_EN_SHIFT (6)
  63. #define STROBE_PIN_EN_SHIFT (5)
  64. #define TORCH_PIN_EN_SHIFT (4)
  65. #define PRECHG_MODE_EN_SHIFT (3)
  66. #define PASS_MODE_ONLY_EN_SHIFT (2)
  67. #define MODE_BITS_SHIFT (0)
  68. #define IVFM_FILTER_TIME_MASK (0x3)
  69. #define UVLO_EN_MASK (0x1)
  70. #define HYSTERSIS_MASK (0x3)
  71. #define IVM_D_TH_MASK (0x7)
  72. #define IVFM_ADJ_MODE_MASK (0x3)
  73. #define NTC_EVENT_LVL_MASK (0x1)
  74. #define NTC_TRIP_TH_MASK (0x7)
  75. #define NTC_BIAS_I_LVL_MASK (0x3)
  76. #define INDIC_RAMP_UP_TIME_MASK (0x7)
  77. #define INDIC_RAMP_DN_TIME_MASK (0x7)
  78. #define INDIC_N_BLANK_MASK (0x7)
  79. #define INDIC_PULSE_TIME_MASK (0x7)
  80. #define INDIC_N_PERIOD_MASK (0x7)
  81. #define TORCH_RAMP_UP_TIME_MASK (0x7)
  82. #define TORCH_RAMP_DN_TIME_MASK (0x7)
  83. #define STROBE_USUAGE_MASK (0x1)
  84. #define STROBE_PIN_POLARITY_MASK (0x1)
  85. #define TORCH_PIN_POLARITY_MASK (0x1)
  86. #define TX_PIN_POLARITY_MASK (0x1)
  87. #define TX_EVENT_LVL_MASK (0x1)
  88. #define IVFM_EN_MASK (0x1)
  89. #define NTC_MODE_MASK (0x1)
  90. #define INDIC_MODE_MASK (0x1)
  91. #define INDUCTOR_I_LIMIT_MASK (0x3)
  92. #define FLASH_RAMP_TIME_MASK (0x7)
  93. #define FLASH_TOUT_TIME_MASK (0x7)
  94. #define TORCH_I_MASK (0x7)
  95. #define FLASH_I_MASK (0xF)
  96. #define NTC_EN_MASK (0x1)
  97. #define TX_PIN_EN_MASK (0x1)
  98. #define STROBE_PIN_EN_MASK (0x1)
  99. #define TORCH_PIN_EN_MASK (0x1)
  100. #define PRECHG_MODE_EN_MASK (0x1)
  101. #define PASS_MODE_ONLY_EN_MASK (0x1)
  102. #define MODE_BITS_MASK (0x13)
  103. #define EX_PIN_CONTROL_MASK (0xF1)
  104. #define EX_PIN_ENABLE_MASK (0x70)
  105. enum lm3556_indic_pulse_time {
  106. PULSE_TIME_0_MS = 0,
  107. PULSE_TIME_32_MS,
  108. PULSE_TIME_64_MS,
  109. PULSE_TIME_92_MS,
  110. PULSE_TIME_128_MS,
  111. PULSE_TIME_160_MS,
  112. PULSE_TIME_196_MS,
  113. PULSE_TIME_224_MS,
  114. PULSE_TIME_256_MS,
  115. PULSE_TIME_288_MS,
  116. PULSE_TIME_320_MS,
  117. PULSE_TIME_352_MS,
  118. PULSE_TIME_384_MS,
  119. PULSE_TIME_416_MS,
  120. PULSE_TIME_448_MS,
  121. PULSE_TIME_480_MS,
  122. };
  123. enum lm3556_indic_n_blank {
  124. INDIC_N_BLANK_0 = 0,
  125. INDIC_N_BLANK_1,
  126. INDIC_N_BLANK_2,
  127. INDIC_N_BLANK_3,
  128. INDIC_N_BLANK_4,
  129. INDIC_N_BLANK_5,
  130. INDIC_N_BLANK_6,
  131. INDIC_N_BLANK_7,
  132. INDIC_N_BLANK_8,
  133. INDIC_N_BLANK_9,
  134. INDIC_N_BLANK_10,
  135. INDIC_N_BLANK_11,
  136. INDIC_N_BLANK_12,
  137. INDIC_N_BLANK_13,
  138. INDIC_N_BLANK_14,
  139. INDIC_N_BLANK_15,
  140. };
  141. enum lm3556_indic_period {
  142. INDIC_PERIOD_0 = 0,
  143. INDIC_PERIOD_1,
  144. INDIC_PERIOD_2,
  145. INDIC_PERIOD_3,
  146. INDIC_PERIOD_4,
  147. INDIC_PERIOD_5,
  148. INDIC_PERIOD_6,
  149. INDIC_PERIOD_7,
  150. };
  151. enum lm3556_mode {
  152. MODES_STASNDBY = 0,
  153. MODES_INDIC,
  154. MODES_TORCH,
  155. MODES_FLASH
  156. };
  157. #define INDIC_PATTERN_SIZE 4
  158. struct indicator {
  159. u8 blinking;
  160. u8 period_cnt;
  161. };
  162. struct lm3556_chip_data {
  163. struct device *dev;
  164. struct led_classdev cdev_flash;
  165. struct led_classdev cdev_torch;
  166. struct led_classdev cdev_indicator;
  167. struct lm3556_platform_data *pdata;
  168. struct regmap *regmap;
  169. struct mutex lock;
  170. unsigned int last_flag;
  171. };
  172. /* indicator pattern */
  173. static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
  174. [0] = {(INDIC_N_BLANK_1 << INDIC_N_BLANK_SHIFT)
  175. | PULSE_TIME_32_MS, INDIC_PERIOD_1},
  176. [1] = {(INDIC_N_BLANK_15 << INDIC_N_BLANK_SHIFT)
  177. | PULSE_TIME_32_MS, INDIC_PERIOD_2},
  178. [2] = {(INDIC_N_BLANK_10 << INDIC_N_BLANK_SHIFT)
  179. | PULSE_TIME_32_MS, INDIC_PERIOD_4},
  180. [3] = {(INDIC_N_BLANK_5 << INDIC_N_BLANK_SHIFT)
  181. | PULSE_TIME_32_MS, INDIC_PERIOD_7},
  182. };
  183. /* chip initialize */
  184. static int __devinit lm3556_chip_init(struct lm3556_chip_data *chip)
  185. {
  186. unsigned int reg_val;
  187. int ret;
  188. struct lm3556_platform_data *pdata = chip->pdata;
  189. /* set config register */
  190. ret = regmap_read(chip->regmap, REG_CONF, &reg_val);
  191. if (ret < 0) {
  192. dev_err(chip->dev, "Failed to read REG_CONF Register\n");
  193. goto out;
  194. }
  195. reg_val &= (~EX_PIN_CONTROL_MASK);
  196. reg_val |= ((pdata->torch_pin_polarity & 0x01)
  197. << TORCH_PIN_POLARITY_SHIFT);
  198. reg_val |= ((pdata->strobe_usuage & 0x01) << STROBE_USUAGE_SHIFT);
  199. reg_val |= ((pdata->strobe_pin_polarity & 0x01)
  200. << STROBE_PIN_POLARITY_SHIFT);
  201. reg_val |= ((pdata->tx_pin_polarity & 0x01) << TX_PIN_POLARITY_SHIFT);
  202. reg_val |= ((pdata->indicator_mode & 0x01) << INDIC_MODE_SHIFT);
  203. ret = regmap_write(chip->regmap, REG_CONF, reg_val);
  204. if (ret < 0) {
  205. dev_err(chip->dev, "Failed to write REG_CONF Regisgter\n");
  206. goto out;
  207. }
  208. /* set enable register */
  209. ret = regmap_read(chip->regmap, REG_ENABLE, &reg_val);
  210. if (ret < 0) {
  211. dev_err(chip->dev, "Failed to read REG_ENABLE Register\n");
  212. goto out;
  213. }
  214. reg_val &= (~EX_PIN_ENABLE_MASK);
  215. reg_val |= ((pdata->torch_pin_en & 0x01) << TORCH_PIN_EN_SHIFT);
  216. reg_val |= ((pdata->strobe_pin_en & 0x01) << STROBE_PIN_EN_SHIFT);
  217. reg_val |= ((pdata->tx_pin_en & 0x01) << TX_PIN_EN_SHIFT);
  218. ret = regmap_write(chip->regmap, REG_ENABLE, reg_val);
  219. if (ret < 0) {
  220. dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
  221. goto out;
  222. }
  223. out:
  224. return ret;
  225. }
  226. /* chip control */
  227. static int lm3556_control(struct lm3556_chip_data *chip,
  228. u8 brightness, enum lm3556_mode opmode)
  229. {
  230. int ret;
  231. struct lm3556_platform_data *pdata = chip->pdata;
  232. ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
  233. if (ret < 0) {
  234. dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
  235. goto out;
  236. }
  237. if (chip->last_flag)
  238. dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
  239. /* brightness 0 means off-state */
  240. if (!brightness)
  241. opmode = MODES_STASNDBY;
  242. switch (opmode) {
  243. case MODES_TORCH:
  244. ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
  245. TORCH_I_MASK << TORCH_I_SHIFT,
  246. (brightness - 1) << TORCH_I_SHIFT);
  247. if (pdata->torch_pin_en)
  248. opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
  249. break;
  250. case MODES_FLASH:
  251. ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
  252. FLASH_I_MASK << FLASH_I_SHIFT,
  253. (brightness - 1) << FLASH_I_SHIFT);
  254. break;
  255. case MODES_INDIC:
  256. ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
  257. TORCH_I_MASK << TORCH_I_SHIFT,
  258. (brightness - 1) << TORCH_I_SHIFT);
  259. break;
  260. case MODES_STASNDBY:
  261. if (pdata->torch_pin_en)
  262. opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
  263. break;
  264. default:
  265. return ret;
  266. }
  267. if (ret < 0) {
  268. dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
  269. goto out;
  270. }
  271. ret = regmap_update_bits(chip->regmap, REG_ENABLE,
  272. MODE_BITS_MASK << MODE_BITS_SHIFT,
  273. opmode << MODE_BITS_SHIFT);
  274. out:
  275. return ret;
  276. }
  277. /* torch */
  278. static void lm3556_torch_brightness_set(struct led_classdev *cdev,
  279. enum led_brightness brightness)
  280. {
  281. struct lm3556_chip_data *chip =
  282. container_of(cdev, struct lm3556_chip_data, cdev_torch);
  283. mutex_lock(&chip->lock);
  284. lm3556_control(chip, brightness, MODES_TORCH);
  285. mutex_unlock(&chip->lock);
  286. }
  287. /* flash */
  288. static void lm3556_strobe_brightness_set(struct led_classdev *cdev,
  289. enum led_brightness brightness)
  290. {
  291. struct lm3556_chip_data *chip =
  292. container_of(cdev, struct lm3556_chip_data, cdev_flash);
  293. mutex_lock(&chip->lock);
  294. lm3556_control(chip, brightness, MODES_FLASH);
  295. mutex_unlock(&chip->lock);
  296. }
  297. /* indicator */
  298. static void lm3556_indicator_brightness_set(struct led_classdev *cdev,
  299. enum led_brightness brightness)
  300. {
  301. struct lm3556_chip_data *chip =
  302. container_of(cdev, struct lm3556_chip_data, cdev_indicator);
  303. mutex_lock(&chip->lock);
  304. lm3556_control(chip, brightness, MODES_INDIC);
  305. mutex_unlock(&chip->lock);
  306. }
  307. /* indicator pattern */
  308. static ssize_t lm3556_indicator_pattern_store(struct device *dev,
  309. struct device_attribute *devAttr,
  310. const char *buf, size_t size)
  311. {
  312. ssize_t ret;
  313. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  314. struct lm3556_chip_data *chip =
  315. container_of(led_cdev, struct lm3556_chip_data, cdev_indicator);
  316. unsigned int state;
  317. ret = kstrtouint(buf, 10, &state);
  318. if (ret)
  319. goto out;
  320. if (state > INDIC_PATTERN_SIZE - 1)
  321. state = INDIC_PATTERN_SIZE - 1;
  322. ret = regmap_write(chip->regmap, REG_INDIC_BLINK,
  323. indicator_pattern[state].blinking);
  324. if (ret < 0) {
  325. dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
  326. goto out;
  327. }
  328. ret = regmap_write(chip->regmap, REG_INDIC_PERIOD,
  329. indicator_pattern[state].period_cnt);
  330. if (ret < 0) {
  331. dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
  332. goto out;
  333. }
  334. return size;
  335. out:
  336. dev_err(chip->dev, "Indicator pattern doesn't saved\n");
  337. return size;
  338. }
  339. static DEVICE_ATTR(pattern, 0666, NULL, lm3556_indicator_pattern_store);
  340. static const struct regmap_config lm3556_regmap = {
  341. .reg_bits = 8,
  342. .val_bits = 8,
  343. .max_register = REG_MAX,
  344. };
  345. /* module initialize */
  346. static int __devinit lm3556_probe(struct i2c_client *client,
  347. const struct i2c_device_id *id)
  348. {
  349. struct lm3556_platform_data *pdata = client->dev.platform_data;
  350. struct lm3556_chip_data *chip;
  351. int err;
  352. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  353. dev_err(&client->dev, "i2c functionality check fail.\n");
  354. return -EOPNOTSUPP;
  355. }
  356. if (pdata == NULL) {
  357. dev_err(&client->dev, "Needs Platform Data.\n");
  358. return -ENODATA;
  359. }
  360. chip =
  361. devm_kzalloc(&client->dev, sizeof(struct lm3556_chip_data),
  362. GFP_KERNEL);
  363. if (!chip)
  364. return -ENOMEM;
  365. chip->dev = &client->dev;
  366. chip->pdata = pdata;
  367. chip->regmap = devm_regmap_init_i2c(client, &lm3556_regmap);
  368. if (IS_ERR(chip->regmap)) {
  369. err = PTR_ERR(chip->regmap);
  370. dev_err(&client->dev, "Failed to allocate register map: %d\n",
  371. err);
  372. return err;
  373. }
  374. mutex_init(&chip->lock);
  375. i2c_set_clientdata(client, chip);
  376. err = lm3556_chip_init(chip);
  377. if (err < 0)
  378. goto err_out;
  379. /* flash */
  380. chip->cdev_flash.name = "flash";
  381. chip->cdev_flash.max_brightness = 16;
  382. chip->cdev_flash.brightness_set = lm3556_strobe_brightness_set;
  383. err = led_classdev_register((struct device *)
  384. &client->dev, &chip->cdev_flash);
  385. if (err < 0)
  386. goto err_out;
  387. /* torch */
  388. chip->cdev_torch.name = "torch";
  389. chip->cdev_torch.max_brightness = 8;
  390. chip->cdev_torch.brightness_set = lm3556_torch_brightness_set;
  391. err = led_classdev_register((struct device *)
  392. &client->dev, &chip->cdev_torch);
  393. if (err < 0)
  394. goto err_create_torch_file;
  395. /* indicator */
  396. chip->cdev_indicator.name = "indicator";
  397. chip->cdev_indicator.max_brightness = 8;
  398. chip->cdev_indicator.brightness_set = lm3556_indicator_brightness_set;
  399. err = led_classdev_register((struct device *)
  400. &client->dev, &chip->cdev_indicator);
  401. if (err < 0)
  402. goto err_create_indicator_file;
  403. err = device_create_file(chip->cdev_indicator.dev, &dev_attr_pattern);
  404. if (err < 0)
  405. goto err_create_pattern_file;
  406. dev_info(&client->dev, "LM3556 is initialized\n");
  407. return 0;
  408. err_create_pattern_file:
  409. led_classdev_unregister(&chip->cdev_indicator);
  410. err_create_indicator_file:
  411. led_classdev_unregister(&chip->cdev_torch);
  412. err_create_torch_file:
  413. led_classdev_unregister(&chip->cdev_flash);
  414. err_out:
  415. return err;
  416. }
  417. static int __devexit lm3556_remove(struct i2c_client *client)
  418. {
  419. struct lm3556_chip_data *chip = i2c_get_clientdata(client);
  420. device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
  421. led_classdev_unregister(&chip->cdev_indicator);
  422. led_classdev_unregister(&chip->cdev_torch);
  423. led_classdev_unregister(&chip->cdev_flash);
  424. regmap_write(chip->regmap, REG_ENABLE, 0);
  425. return 0;
  426. }
  427. static const struct i2c_device_id lm3556_id[] = {
  428. {LM3556_NAME, 0},
  429. {}
  430. };
  431. MODULE_DEVICE_TABLE(i2c, lm3556_id);
  432. static struct i2c_driver lm3556_i2c_driver = {
  433. .driver = {
  434. .name = LM3556_NAME,
  435. .owner = THIS_MODULE,
  436. .pm = NULL,
  437. },
  438. .probe = lm3556_probe,
  439. .remove = __devexit_p(lm3556_remove),
  440. .id_table = lm3556_id,
  441. };
  442. module_i2c_driver(lm3556_i2c_driver);
  443. MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3556");
  444. MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
  445. MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
  446. MODULE_LICENSE("GPL v2");