leds-lm3533.c 18 KB

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