leds-lm3533.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /*
  2. * leds-lm3533.c -- LM3533 LED driver
  3. *
  4. * Copyright (C) 2011-2012 Texas Instruments
  5. *
  6. * Author: Johan Hovold <jhovold@gmail.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/leds.h>
  15. #include <linux/mfd/core.h>
  16. #include <linux/mutex.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/slab.h>
  19. #include <linux/mfd/lm3533.h>
  20. #define LM3533_LVCTRLBANK_MIN 2
  21. #define LM3533_LVCTRLBANK_MAX 5
  22. #define LM3533_LVCTRLBANK_COUNT 4
  23. #define LM3533_RISEFALLTIME_MAX 7
  24. #define LM3533_ALS_CHANNEL_LV_MIN 1
  25. #define LM3533_ALS_CHANNEL_LV_MAX 2
  26. #define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b
  27. #define LM3533_REG_PATTERN_ENABLE 0x28
  28. #define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71
  29. #define LM3533_REG_PATTERN_HIGH_TIME_BASE 0x72
  30. #define LM3533_REG_PATTERN_RISETIME_BASE 0x74
  31. #define LM3533_REG_PATTERN_FALLTIME_BASE 0x75
  32. #define LM3533_REG_PATTERN_STEP 0x10
  33. #define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK 0x04
  34. #define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK 0x02
  35. #define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK 0x01
  36. #define LM3533_LED_FLAG_PATTERN_ENABLE 1
  37. struct lm3533_led {
  38. struct lm3533 *lm3533;
  39. struct lm3533_ctrlbank cb;
  40. struct led_classdev cdev;
  41. int id;
  42. struct mutex mutex;
  43. unsigned long flags;
  44. };
  45. static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev)
  46. {
  47. return container_of(cdev, struct lm3533_led, cdev);
  48. }
  49. static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led)
  50. {
  51. return led->id + 2;
  52. }
  53. static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base)
  54. {
  55. return base + led->id;
  56. }
  57. static inline u8 lm3533_led_get_pattern(struct lm3533_led *led)
  58. {
  59. return led->id;
  60. }
  61. static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led,
  62. u8 base)
  63. {
  64. return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP;
  65. }
  66. static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
  67. {
  68. u8 mask;
  69. u8 val;
  70. int pattern;
  71. int state;
  72. int ret = 0;
  73. dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable);
  74. mutex_lock(&led->mutex);
  75. state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
  76. if ((enable && state) || (!enable && !state))
  77. goto out;
  78. pattern = lm3533_led_get_pattern(led);
  79. mask = 1 << (2 * pattern);
  80. if (enable)
  81. val = mask;
  82. else
  83. val = 0;
  84. ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask);
  85. if (ret) {
  86. dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n",
  87. pattern, enable);
  88. goto out;
  89. }
  90. __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
  91. out:
  92. mutex_unlock(&led->mutex);
  93. return ret;
  94. }
  95. static int lm3533_led_set(struct led_classdev *cdev,
  96. enum led_brightness value)
  97. {
  98. struct lm3533_led *led = to_lm3533_led(cdev);
  99. dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value);
  100. if (value == 0)
  101. lm3533_led_pattern_enable(led, 0); /* disable blink */
  102. return lm3533_ctrlbank_set_brightness(&led->cb, value);
  103. }
  104. static enum led_brightness lm3533_led_get(struct led_classdev *cdev)
  105. {
  106. struct lm3533_led *led = to_lm3533_led(cdev);
  107. u8 val;
  108. int ret;
  109. ret = lm3533_ctrlbank_get_brightness(&led->cb, &val);
  110. if (ret)
  111. return ret;
  112. dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val);
  113. return val;
  114. }
  115. /* Pattern generator defines (delays in us). */
  116. #define LM3533_LED_DELAY1_VMIN 0x00
  117. #define LM3533_LED_DELAY2_VMIN 0x3d
  118. #define LM3533_LED_DELAY3_VMIN 0x80
  119. #define LM3533_LED_DELAY1_VMAX (LM3533_LED_DELAY2_VMIN - 1)
  120. #define LM3533_LED_DELAY2_VMAX (LM3533_LED_DELAY3_VMIN - 1)
  121. #define LM3533_LED_DELAY3_VMAX 0xff
  122. #define LM3533_LED_DELAY1_TMIN 16384U
  123. #define LM3533_LED_DELAY2_TMIN 1130496U
  124. #define LM3533_LED_DELAY3_TMIN 10305536U
  125. #define LM3533_LED_DELAY1_TMAX 999424U
  126. #define LM3533_LED_DELAY2_TMAX 9781248U
  127. #define LM3533_LED_DELAY3_TMAX 76890112U
  128. /* t_step = (t_max - t_min) / (v_max - v_min) */
  129. #define LM3533_LED_DELAY1_TSTEP 16384
  130. #define LM3533_LED_DELAY2_TSTEP 131072
  131. #define LM3533_LED_DELAY3_TSTEP 524288
  132. /* Delay limits for hardware accelerated blinking (in ms). */
  133. #define LM3533_LED_DELAY_ON_MAX \
  134. ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000)
  135. #define LM3533_LED_DELAY_OFF_MAX \
  136. ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000)
  137. /*
  138. * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step
  139. * size of t_step, where
  140. *
  141. * t_step = (t_max - t_min) / (v_max - v_min)
  142. *
  143. * and updates *t to reflect the mapped value.
  144. */
  145. static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step,
  146. u8 v_min, u8 v_max)
  147. {
  148. unsigned val;
  149. val = (*t + t_step / 2 - t_min) / t_step + v_min;
  150. *t = t_step * (val - v_min) + t_min;
  151. return (u8)val;
  152. }
  153. /*
  154. * Returns time code corresponding to *delay (in ms) and updates *delay to
  155. * reflect actual hardware delay.
  156. *
  157. * Hardware supports 256 discrete delay times, divided into three groups with
  158. * the following ranges and step-sizes:
  159. *
  160. * [ 16, 999] [0x00, 0x3e] step 16 ms
  161. * [ 1130, 9781] [0x3d, 0x7f] step 131 ms
  162. * [10306, 76890] [0x80, 0xff] step 524 ms
  163. *
  164. * Note that delay group 3 is only available for delay_off.
  165. */
  166. static u8 lm3533_led_get_hw_delay(unsigned *delay)
  167. {
  168. unsigned t;
  169. u8 val;
  170. t = *delay * 1000;
  171. if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) {
  172. t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX);
  173. val = time_to_val(&t, LM3533_LED_DELAY3_TMIN,
  174. LM3533_LED_DELAY3_TSTEP,
  175. LM3533_LED_DELAY3_VMIN,
  176. LM3533_LED_DELAY3_VMAX);
  177. } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) {
  178. t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX);
  179. val = time_to_val(&t, LM3533_LED_DELAY2_TMIN,
  180. LM3533_LED_DELAY2_TSTEP,
  181. LM3533_LED_DELAY2_VMIN,
  182. LM3533_LED_DELAY2_VMAX);
  183. } else {
  184. t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX);
  185. val = time_to_val(&t, LM3533_LED_DELAY1_TMIN,
  186. LM3533_LED_DELAY1_TSTEP,
  187. LM3533_LED_DELAY1_VMIN,
  188. LM3533_LED_DELAY1_VMAX);
  189. }
  190. *delay = (t + 500) / 1000;
  191. return val;
  192. }
  193. /*
  194. * Set delay register base to *delay (in ms) and update *delay to reflect
  195. * actual hardware delay used.
  196. */
  197. static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base,
  198. unsigned long *delay)
  199. {
  200. unsigned t;
  201. u8 val;
  202. u8 reg;
  203. int ret;
  204. t = (unsigned)*delay;
  205. /* Delay group 3 is only available for low time (delay off). */
  206. if (base != LM3533_REG_PATTERN_LOW_TIME_BASE)
  207. t = min(t, LM3533_LED_DELAY2_TMAX / 1000);
  208. val = lm3533_led_get_hw_delay(&t);
  209. dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__,
  210. *delay, t, val);
  211. reg = lm3533_led_get_pattern_reg(led, base);
  212. ret = lm3533_write(led->lm3533, reg, val);
  213. if (ret)
  214. dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
  215. *delay = t;
  216. return ret;
  217. }
  218. static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t)
  219. {
  220. return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t);
  221. }
  222. static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t)
  223. {
  224. return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t);
  225. }
  226. static int lm3533_led_blink_set(struct led_classdev *cdev,
  227. unsigned long *delay_on,
  228. unsigned long *delay_off)
  229. {
  230. struct lm3533_led *led = to_lm3533_led(cdev);
  231. int ret;
  232. dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__,
  233. *delay_on, *delay_off);
  234. if (*delay_on > LM3533_LED_DELAY_ON_MAX ||
  235. *delay_off > LM3533_LED_DELAY_OFF_MAX)
  236. return -EINVAL;
  237. if (*delay_on == 0 && *delay_off == 0) {
  238. *delay_on = 500;
  239. *delay_off = 500;
  240. }
  241. ret = lm3533_led_delay_on_set(led, delay_on);
  242. if (ret)
  243. return ret;
  244. ret = lm3533_led_delay_off_set(led, delay_off);
  245. if (ret)
  246. return ret;
  247. return lm3533_led_pattern_enable(led, 1);
  248. }
  249. static ssize_t show_id(struct device *dev,
  250. struct device_attribute *attr, char *buf)
  251. {
  252. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  253. struct lm3533_led *led = to_lm3533_led(led_cdev);
  254. return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
  255. }
  256. /*
  257. * Pattern generator rise/fall times:
  258. *
  259. * 0 - 2048 us (default)
  260. * 1 - 262 ms
  261. * 2 - 524 ms
  262. * 3 - 1.049 s
  263. * 4 - 2.097 s
  264. * 5 - 4.194 s
  265. * 6 - 8.389 s
  266. * 7 - 16.78 s
  267. */
  268. static ssize_t show_risefalltime(struct device *dev,
  269. struct device_attribute *attr,
  270. char *buf, u8 base)
  271. {
  272. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  273. struct lm3533_led *led = to_lm3533_led(led_cdev);
  274. ssize_t ret;
  275. u8 reg;
  276. u8 val;
  277. reg = lm3533_led_get_pattern_reg(led, base);
  278. ret = lm3533_read(led->lm3533, reg, &val);
  279. if (ret)
  280. return ret;
  281. return scnprintf(buf, PAGE_SIZE, "%x\n", val);
  282. }
  283. static ssize_t show_risetime(struct device *dev,
  284. struct device_attribute *attr, char *buf)
  285. {
  286. return show_risefalltime(dev, attr, buf,
  287. LM3533_REG_PATTERN_RISETIME_BASE);
  288. }
  289. static ssize_t show_falltime(struct device *dev,
  290. struct device_attribute *attr, char *buf)
  291. {
  292. return show_risefalltime(dev, attr, buf,
  293. LM3533_REG_PATTERN_FALLTIME_BASE);
  294. }
  295. static ssize_t store_risefalltime(struct device *dev,
  296. struct device_attribute *attr,
  297. const char *buf, size_t len, u8 base)
  298. {
  299. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  300. struct lm3533_led *led = to_lm3533_led(led_cdev);
  301. u8 val;
  302. u8 reg;
  303. int ret;
  304. if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX)
  305. return -EINVAL;
  306. reg = lm3533_led_get_pattern_reg(led, base);
  307. ret = lm3533_write(led->lm3533, reg, val);
  308. if (ret)
  309. return ret;
  310. return len;
  311. }
  312. static ssize_t store_risetime(struct device *dev,
  313. struct device_attribute *attr,
  314. const char *buf, size_t len)
  315. {
  316. return store_risefalltime(dev, attr, buf, len,
  317. LM3533_REG_PATTERN_RISETIME_BASE);
  318. }
  319. static ssize_t store_falltime(struct device *dev,
  320. struct device_attribute *attr,
  321. const char *buf, size_t len)
  322. {
  323. return store_risefalltime(dev, attr, buf, len,
  324. LM3533_REG_PATTERN_FALLTIME_BASE);
  325. }
  326. static ssize_t show_als_channel(struct device *dev,
  327. struct device_attribute *attr, char *buf)
  328. {
  329. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  330. struct lm3533_led *led = to_lm3533_led(led_cdev);
  331. unsigned channel;
  332. u8 reg;
  333. u8 val;
  334. int ret;
  335. reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
  336. ret = lm3533_read(led->lm3533, reg, &val);
  337. if (ret)
  338. return ret;
  339. channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
  340. return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
  341. }
  342. static ssize_t store_als_channel(struct device *dev,
  343. struct device_attribute *attr,
  344. const char *buf, size_t len)
  345. {
  346. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  347. struct lm3533_led *led = to_lm3533_led(led_cdev);
  348. unsigned channel;
  349. u8 reg;
  350. u8 val;
  351. u8 mask;
  352. int ret;
  353. if (kstrtouint(buf, 0, &channel))
  354. return -EINVAL;
  355. if (channel < LM3533_ALS_CHANNEL_LV_MIN ||
  356. channel > LM3533_ALS_CHANNEL_LV_MAX)
  357. return -EINVAL;
  358. reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
  359. mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK;
  360. val = channel - 1;
  361. ret = lm3533_update(led->lm3533, reg, val, mask);
  362. if (ret)
  363. return ret;
  364. return len;
  365. }
  366. static ssize_t show_als_en(struct device *dev,
  367. struct device_attribute *attr, char *buf)
  368. {
  369. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  370. struct lm3533_led *led = to_lm3533_led(led_cdev);
  371. bool enable;
  372. u8 reg;
  373. u8 val;
  374. int ret;
  375. reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
  376. ret = lm3533_read(led->lm3533, reg, &val);
  377. if (ret)
  378. return ret;
  379. enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
  380. return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
  381. }
  382. static ssize_t store_als_en(struct device *dev,
  383. struct device_attribute *attr,
  384. const char *buf, size_t len)
  385. {
  386. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  387. struct lm3533_led *led = to_lm3533_led(led_cdev);
  388. unsigned enable;
  389. u8 reg;
  390. u8 mask;
  391. u8 val;
  392. int ret;
  393. if (kstrtouint(buf, 0, &enable))
  394. return -EINVAL;
  395. reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
  396. mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
  397. if (enable)
  398. val = mask;
  399. else
  400. val = 0;
  401. ret = lm3533_update(led->lm3533, reg, val, mask);
  402. if (ret)
  403. return ret;
  404. return len;
  405. }
  406. static ssize_t show_linear(struct device *dev,
  407. struct device_attribute *attr, char *buf)
  408. {
  409. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  410. struct lm3533_led *led = to_lm3533_led(led_cdev);
  411. u8 reg;
  412. u8 val;
  413. int linear;
  414. int ret;
  415. reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
  416. ret = lm3533_read(led->lm3533, reg, &val);
  417. if (ret)
  418. return ret;
  419. if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK)
  420. linear = 1;
  421. else
  422. linear = 0;
  423. return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
  424. }
  425. static ssize_t store_linear(struct device *dev,
  426. struct device_attribute *attr,
  427. const char *buf, size_t len)
  428. {
  429. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  430. struct lm3533_led *led = to_lm3533_led(led_cdev);
  431. unsigned long linear;
  432. u8 reg;
  433. u8 mask;
  434. u8 val;
  435. int ret;
  436. if (kstrtoul(buf, 0, &linear))
  437. return -EINVAL;
  438. reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
  439. mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK;
  440. if (linear)
  441. val = mask;
  442. else
  443. val = 0;
  444. ret = lm3533_update(led->lm3533, reg, val, mask);
  445. if (ret)
  446. return ret;
  447. return len;
  448. }
  449. static ssize_t show_pwm(struct device *dev,
  450. struct device_attribute *attr,
  451. char *buf)
  452. {
  453. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  454. struct lm3533_led *led = to_lm3533_led(led_cdev);
  455. u8 val;
  456. int ret;
  457. ret = lm3533_ctrlbank_get_pwm(&led->cb, &val);
  458. if (ret)
  459. return ret;
  460. return scnprintf(buf, PAGE_SIZE, "%u\n", val);
  461. }
  462. static ssize_t store_pwm(struct device *dev,
  463. struct device_attribute *attr,
  464. const char *buf, size_t len)
  465. {
  466. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  467. struct lm3533_led *led = to_lm3533_led(led_cdev);
  468. u8 val;
  469. int ret;
  470. if (kstrtou8(buf, 0, &val))
  471. return -EINVAL;
  472. ret = lm3533_ctrlbank_set_pwm(&led->cb, val);
  473. if (ret)
  474. return ret;
  475. return len;
  476. }
  477. static LM3533_ATTR_RW(als_channel);
  478. static LM3533_ATTR_RW(als_en);
  479. static LM3533_ATTR_RW(falltime);
  480. static LM3533_ATTR_RO(id);
  481. static LM3533_ATTR_RW(linear);
  482. static LM3533_ATTR_RW(pwm);
  483. static LM3533_ATTR_RW(risetime);
  484. static struct attribute *lm3533_led_attributes[] = {
  485. &dev_attr_als_channel.attr,
  486. &dev_attr_als_en.attr,
  487. &dev_attr_falltime.attr,
  488. &dev_attr_id.attr,
  489. &dev_attr_linear.attr,
  490. &dev_attr_pwm.attr,
  491. &dev_attr_risetime.attr,
  492. NULL,
  493. };
  494. static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
  495. struct attribute *attr, int n)
  496. {
  497. struct device *dev = container_of(kobj, struct device, kobj);
  498. struct led_classdev *led_cdev = dev_get_drvdata(dev);
  499. struct lm3533_led *led = to_lm3533_led(led_cdev);
  500. umode_t mode = attr->mode;
  501. if (attr == &dev_attr_als_channel.attr ||
  502. attr == &dev_attr_als_en.attr) {
  503. if (!led->lm3533->have_als)
  504. mode = 0;
  505. }
  506. return mode;
  507. };
  508. static struct attribute_group lm3533_led_attribute_group = {
  509. .is_visible = lm3533_led_attr_is_visible,
  510. .attrs = lm3533_led_attributes
  511. };
  512. static const struct attribute_group *lm3533_led_attribute_groups[] = {
  513. &lm3533_led_attribute_group,
  514. NULL
  515. };
  516. static int lm3533_led_setup(struct lm3533_led *led,
  517. struct lm3533_led_platform_data *pdata)
  518. {
  519. int ret;
  520. ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
  521. if (ret)
  522. return ret;
  523. return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
  524. }
  525. static int lm3533_led_probe(struct platform_device *pdev)
  526. {
  527. struct lm3533 *lm3533;
  528. struct lm3533_led_platform_data *pdata;
  529. struct lm3533_led *led;
  530. int ret;
  531. dev_dbg(&pdev->dev, "%s\n", __func__);
  532. lm3533 = dev_get_drvdata(pdev->dev.parent);
  533. if (!lm3533)
  534. return -EINVAL;
  535. pdata = dev_get_platdata(&pdev->dev);
  536. if (!pdata) {
  537. dev_err(&pdev->dev, "no platform data\n");
  538. return -EINVAL;
  539. }
  540. if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
  541. dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
  542. return -EINVAL;
  543. }
  544. led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
  545. if (!led)
  546. return -ENOMEM;
  547. led->lm3533 = lm3533;
  548. led->cdev.name = pdata->name;
  549. led->cdev.default_trigger = pdata->default_trigger;
  550. led->cdev.brightness_set_blocking = lm3533_led_set;
  551. led->cdev.brightness_get = lm3533_led_get;
  552. led->cdev.blink_set = lm3533_led_blink_set;
  553. led->cdev.brightness = LED_OFF;
  554. led->cdev.groups = lm3533_led_attribute_groups,
  555. led->id = pdev->id;
  556. mutex_init(&led->mutex);
  557. /* The class framework makes a callback to get brightness during
  558. * registration so use parent device (for error reporting) until
  559. * registered.
  560. */
  561. led->cb.lm3533 = lm3533;
  562. led->cb.id = lm3533_led_get_ctrlbank_id(led);
  563. led->cb.dev = lm3533->dev;
  564. platform_set_drvdata(pdev, led);
  565. ret = devm_led_classdev_register(pdev->dev.parent, &led->cdev);
  566. if (ret) {
  567. dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
  568. return ret;
  569. }
  570. led->cb.dev = led->cdev.dev;
  571. ret = lm3533_led_setup(led, pdata);
  572. if (ret)
  573. return ret;
  574. ret = lm3533_ctrlbank_enable(&led->cb);
  575. if (ret)
  576. return ret;
  577. return 0;
  578. }
  579. static int lm3533_led_remove(struct platform_device *pdev)
  580. {
  581. struct lm3533_led *led = platform_get_drvdata(pdev);
  582. dev_dbg(&pdev->dev, "%s\n", __func__);
  583. lm3533_ctrlbank_disable(&led->cb);
  584. return 0;
  585. }
  586. static void lm3533_led_shutdown(struct platform_device *pdev)
  587. {
  588. struct lm3533_led *led = platform_get_drvdata(pdev);
  589. dev_dbg(&pdev->dev, "%s\n", __func__);
  590. lm3533_ctrlbank_disable(&led->cb);
  591. lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */
  592. }
  593. static struct platform_driver lm3533_led_driver = {
  594. .driver = {
  595. .name = "lm3533-leds",
  596. },
  597. .probe = lm3533_led_probe,
  598. .remove = lm3533_led_remove,
  599. .shutdown = lm3533_led_shutdown,
  600. };
  601. module_platform_driver(lm3533_led_driver);
  602. MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
  603. MODULE_DESCRIPTION("LM3533 LED driver");
  604. MODULE_LICENSE("GPL");
  605. MODULE_ALIAS("platform:lm3533-leds");