leds-lp55xx-common.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * LP5521/LP5523/LP55231/LP5562 Common Driver
  4. *
  5. * Copyright 2012 Texas Instruments
  6. *
  7. * Author: Milo(Woogyom) Kim <[email protected]>
  8. *
  9. * Derived from leds-lp5521.c, leds-lp5523.c
  10. */
  11. #include <linux/clk.h>
  12. #include <linux/delay.h>
  13. #include <linux/firmware.h>
  14. #include <linux/i2c.h>
  15. #include <linux/leds.h>
  16. #include <linux/module.h>
  17. #include <linux/platform_data/leds-lp55xx.h>
  18. #include <linux/slab.h>
  19. #include <linux/gpio/consumer.h>
  20. #include "leds-lp55xx-common.h"
  21. /* External clock rate */
  22. #define LP55XX_CLK_32K 32768
  23. static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)
  24. {
  25. return container_of(cdev, struct lp55xx_led, cdev);
  26. }
  27. static struct lp55xx_led *dev_to_lp55xx_led(struct device *dev)
  28. {
  29. return cdev_to_lp55xx_led(dev_get_drvdata(dev));
  30. }
  31. static struct lp55xx_led *mcled_cdev_to_led(struct led_classdev_mc *mc_cdev)
  32. {
  33. return container_of(mc_cdev, struct lp55xx_led, mc_cdev);
  34. }
  35. static void lp55xx_reset_device(struct lp55xx_chip *chip)
  36. {
  37. struct lp55xx_device_config *cfg = chip->cfg;
  38. u8 addr = cfg->reset.addr;
  39. u8 val = cfg->reset.val;
  40. /* no error checking here because no ACK from the device after reset */
  41. lp55xx_write(chip, addr, val);
  42. }
  43. static int lp55xx_detect_device(struct lp55xx_chip *chip)
  44. {
  45. struct lp55xx_device_config *cfg = chip->cfg;
  46. u8 addr = cfg->enable.addr;
  47. u8 val = cfg->enable.val;
  48. int ret;
  49. ret = lp55xx_write(chip, addr, val);
  50. if (ret)
  51. return ret;
  52. usleep_range(1000, 2000);
  53. ret = lp55xx_read(chip, addr, &val);
  54. if (ret)
  55. return ret;
  56. if (val != cfg->enable.val)
  57. return -ENODEV;
  58. return 0;
  59. }
  60. static int lp55xx_post_init_device(struct lp55xx_chip *chip)
  61. {
  62. struct lp55xx_device_config *cfg = chip->cfg;
  63. if (!cfg->post_init_device)
  64. return 0;
  65. return cfg->post_init_device(chip);
  66. }
  67. static ssize_t led_current_show(struct device *dev,
  68. struct device_attribute *attr,
  69. char *buf)
  70. {
  71. struct lp55xx_led *led = dev_to_lp55xx_led(dev);
  72. return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
  73. }
  74. static ssize_t led_current_store(struct device *dev,
  75. struct device_attribute *attr,
  76. const char *buf, size_t len)
  77. {
  78. struct lp55xx_led *led = dev_to_lp55xx_led(dev);
  79. struct lp55xx_chip *chip = led->chip;
  80. unsigned long curr;
  81. if (kstrtoul(buf, 0, &curr))
  82. return -EINVAL;
  83. if (curr > led->max_current)
  84. return -EINVAL;
  85. if (!chip->cfg->set_led_current)
  86. return len;
  87. mutex_lock(&chip->lock);
  88. chip->cfg->set_led_current(led, (u8)curr);
  89. mutex_unlock(&chip->lock);
  90. return len;
  91. }
  92. static ssize_t max_current_show(struct device *dev,
  93. struct device_attribute *attr,
  94. char *buf)
  95. {
  96. struct lp55xx_led *led = dev_to_lp55xx_led(dev);
  97. return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
  98. }
  99. static DEVICE_ATTR_RW(led_current);
  100. static DEVICE_ATTR_RO(max_current);
  101. static struct attribute *lp55xx_led_attrs[] = {
  102. &dev_attr_led_current.attr,
  103. &dev_attr_max_current.attr,
  104. NULL,
  105. };
  106. ATTRIBUTE_GROUPS(lp55xx_led);
  107. static int lp55xx_set_mc_brightness(struct led_classdev *cdev,
  108. enum led_brightness brightness)
  109. {
  110. struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev);
  111. struct lp55xx_led *led = mcled_cdev_to_led(mc_dev);
  112. struct lp55xx_device_config *cfg = led->chip->cfg;
  113. led_mc_calc_color_components(&led->mc_cdev, brightness);
  114. return cfg->multicolor_brightness_fn(led);
  115. }
  116. static int lp55xx_set_brightness(struct led_classdev *cdev,
  117. enum led_brightness brightness)
  118. {
  119. struct lp55xx_led *led = cdev_to_lp55xx_led(cdev);
  120. struct lp55xx_device_config *cfg = led->chip->cfg;
  121. led->brightness = (u8)brightness;
  122. return cfg->brightness_fn(led);
  123. }
  124. static int lp55xx_init_led(struct lp55xx_led *led,
  125. struct lp55xx_chip *chip, int chan)
  126. {
  127. struct lp55xx_platform_data *pdata = chip->pdata;
  128. struct lp55xx_device_config *cfg = chip->cfg;
  129. struct device *dev = &chip->cl->dev;
  130. int max_channel = cfg->max_channel;
  131. struct mc_subled *mc_led_info;
  132. struct led_classdev *led_cdev;
  133. char name[32];
  134. int i, j = 0;
  135. int ret;
  136. if (chan >= max_channel) {
  137. dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel);
  138. return -EINVAL;
  139. }
  140. if (pdata->led_config[chan].led_current == 0)
  141. return 0;
  142. if (pdata->led_config[chan].name) {
  143. led->cdev.name = pdata->led_config[chan].name;
  144. } else {
  145. snprintf(name, sizeof(name), "%s:channel%d",
  146. pdata->label ? : chip->cl->name, chan);
  147. led->cdev.name = name;
  148. }
  149. if (pdata->led_config[chan].num_colors > 1) {
  150. mc_led_info = devm_kcalloc(dev,
  151. pdata->led_config[chan].num_colors,
  152. sizeof(*mc_led_info), GFP_KERNEL);
  153. if (!mc_led_info)
  154. return -ENOMEM;
  155. led_cdev = &led->mc_cdev.led_cdev;
  156. led_cdev->name = led->cdev.name;
  157. led_cdev->brightness_set_blocking = lp55xx_set_mc_brightness;
  158. led->mc_cdev.num_colors = pdata->led_config[chan].num_colors;
  159. for (i = 0; i < led->mc_cdev.num_colors; i++) {
  160. mc_led_info[i].color_index =
  161. pdata->led_config[chan].color_id[i];
  162. mc_led_info[i].channel =
  163. pdata->led_config[chan].output_num[i];
  164. j++;
  165. }
  166. led->mc_cdev.subled_info = mc_led_info;
  167. } else {
  168. led->cdev.brightness_set_blocking = lp55xx_set_brightness;
  169. }
  170. led->cdev.groups = lp55xx_led_groups;
  171. led->cdev.default_trigger = pdata->led_config[chan].default_trigger;
  172. led->led_current = pdata->led_config[chan].led_current;
  173. led->max_current = pdata->led_config[chan].max_current;
  174. led->chan_nr = pdata->led_config[chan].chan_nr;
  175. if (led->chan_nr >= max_channel) {
  176. dev_err(dev, "Use channel numbers between 0 and %d\n",
  177. max_channel - 1);
  178. return -EINVAL;
  179. }
  180. if (pdata->led_config[chan].num_colors > 1)
  181. ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev);
  182. else
  183. ret = devm_led_classdev_register(dev, &led->cdev);
  184. if (ret) {
  185. dev_err(dev, "led register err: %d\n", ret);
  186. return ret;
  187. }
  188. return 0;
  189. }
  190. static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
  191. {
  192. struct lp55xx_chip *chip = context;
  193. struct device *dev = &chip->cl->dev;
  194. enum lp55xx_engine_index idx = chip->engine_idx;
  195. if (!fw) {
  196. dev_err(dev, "firmware request failed\n");
  197. return;
  198. }
  199. /* handling firmware data is chip dependent */
  200. mutex_lock(&chip->lock);
  201. chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD;
  202. chip->fw = fw;
  203. if (chip->cfg->firmware_cb)
  204. chip->cfg->firmware_cb(chip);
  205. mutex_unlock(&chip->lock);
  206. /* firmware should be released for other channel use */
  207. release_firmware(chip->fw);
  208. chip->fw = NULL;
  209. }
  210. static int lp55xx_request_firmware(struct lp55xx_chip *chip)
  211. {
  212. const char *name = chip->cl->name;
  213. struct device *dev = &chip->cl->dev;
  214. return request_firmware_nowait(THIS_MODULE, false, name, dev,
  215. GFP_KERNEL, chip, lp55xx_firmware_loaded);
  216. }
  217. static ssize_t select_engine_show(struct device *dev,
  218. struct device_attribute *attr,
  219. char *buf)
  220. {
  221. struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
  222. struct lp55xx_chip *chip = led->chip;
  223. return sprintf(buf, "%d\n", chip->engine_idx);
  224. }
  225. static ssize_t select_engine_store(struct device *dev,
  226. struct device_attribute *attr,
  227. const char *buf, size_t len)
  228. {
  229. struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
  230. struct lp55xx_chip *chip = led->chip;
  231. unsigned long val;
  232. int ret;
  233. if (kstrtoul(buf, 0, &val))
  234. return -EINVAL;
  235. /* select the engine to be run */
  236. switch (val) {
  237. case LP55XX_ENGINE_1:
  238. case LP55XX_ENGINE_2:
  239. case LP55XX_ENGINE_3:
  240. mutex_lock(&chip->lock);
  241. chip->engine_idx = val;
  242. ret = lp55xx_request_firmware(chip);
  243. mutex_unlock(&chip->lock);
  244. break;
  245. default:
  246. dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val);
  247. return -EINVAL;
  248. }
  249. if (ret) {
  250. dev_err(dev, "request firmware err: %d\n", ret);
  251. return ret;
  252. }
  253. return len;
  254. }
  255. static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start)
  256. {
  257. if (chip->cfg->run_engine)
  258. chip->cfg->run_engine(chip, start);
  259. }
  260. static ssize_t run_engine_store(struct device *dev,
  261. struct device_attribute *attr,
  262. const char *buf, size_t len)
  263. {
  264. struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
  265. struct lp55xx_chip *chip = led->chip;
  266. unsigned long val;
  267. if (kstrtoul(buf, 0, &val))
  268. return -EINVAL;
  269. /* run or stop the selected engine */
  270. if (val <= 0) {
  271. lp55xx_run_engine(chip, false);
  272. return len;
  273. }
  274. mutex_lock(&chip->lock);
  275. lp55xx_run_engine(chip, true);
  276. mutex_unlock(&chip->lock);
  277. return len;
  278. }
  279. static DEVICE_ATTR_RW(select_engine);
  280. static DEVICE_ATTR_WO(run_engine);
  281. static struct attribute *lp55xx_engine_attributes[] = {
  282. &dev_attr_select_engine.attr,
  283. &dev_attr_run_engine.attr,
  284. NULL,
  285. };
  286. static const struct attribute_group lp55xx_engine_attr_group = {
  287. .attrs = lp55xx_engine_attributes,
  288. };
  289. int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)
  290. {
  291. return i2c_smbus_write_byte_data(chip->cl, reg, val);
  292. }
  293. EXPORT_SYMBOL_GPL(lp55xx_write);
  294. int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val)
  295. {
  296. s32 ret;
  297. ret = i2c_smbus_read_byte_data(chip->cl, reg);
  298. if (ret < 0)
  299. return ret;
  300. *val = ret;
  301. return 0;
  302. }
  303. EXPORT_SYMBOL_GPL(lp55xx_read);
  304. int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)
  305. {
  306. int ret;
  307. u8 tmp;
  308. ret = lp55xx_read(chip, reg, &tmp);
  309. if (ret)
  310. return ret;
  311. tmp &= ~mask;
  312. tmp |= val & mask;
  313. return lp55xx_write(chip, reg, tmp);
  314. }
  315. EXPORT_SYMBOL_GPL(lp55xx_update_bits);
  316. bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)
  317. {
  318. struct clk *clk;
  319. int err;
  320. clk = devm_clk_get(&chip->cl->dev, "32k_clk");
  321. if (IS_ERR(clk))
  322. goto use_internal_clk;
  323. err = clk_prepare_enable(clk);
  324. if (err)
  325. goto use_internal_clk;
  326. if (clk_get_rate(clk) != LP55XX_CLK_32K) {
  327. clk_disable_unprepare(clk);
  328. goto use_internal_clk;
  329. }
  330. dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K);
  331. chip->clk = clk;
  332. return true;
  333. use_internal_clk:
  334. dev_info(&chip->cl->dev, "internal clock used\n");
  335. return false;
  336. }
  337. EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
  338. int lp55xx_init_device(struct lp55xx_chip *chip)
  339. {
  340. struct lp55xx_platform_data *pdata;
  341. struct lp55xx_device_config *cfg;
  342. struct device *dev = &chip->cl->dev;
  343. int ret = 0;
  344. WARN_ON(!chip);
  345. pdata = chip->pdata;
  346. cfg = chip->cfg;
  347. if (!pdata || !cfg)
  348. return -EINVAL;
  349. if (pdata->enable_gpiod) {
  350. gpiod_direction_output(pdata->enable_gpiod, 0);
  351. gpiod_set_consumer_name(pdata->enable_gpiod, "LP55xx enable");
  352. gpiod_set_value(pdata->enable_gpiod, 0);
  353. usleep_range(1000, 2000); /* Keep enable down at least 1ms */
  354. gpiod_set_value(pdata->enable_gpiod, 1);
  355. usleep_range(1000, 2000); /* 500us abs min. */
  356. }
  357. lp55xx_reset_device(chip);
  358. /*
  359. * Exact value is not available. 10 - 20ms
  360. * appears to be enough for reset.
  361. */
  362. usleep_range(10000, 20000);
  363. ret = lp55xx_detect_device(chip);
  364. if (ret) {
  365. dev_err(dev, "device detection err: %d\n", ret);
  366. goto err;
  367. }
  368. /* chip specific initialization */
  369. ret = lp55xx_post_init_device(chip);
  370. if (ret) {
  371. dev_err(dev, "post init device err: %d\n", ret);
  372. goto err_post_init;
  373. }
  374. return 0;
  375. err_post_init:
  376. lp55xx_deinit_device(chip);
  377. err:
  378. return ret;
  379. }
  380. EXPORT_SYMBOL_GPL(lp55xx_init_device);
  381. void lp55xx_deinit_device(struct lp55xx_chip *chip)
  382. {
  383. struct lp55xx_platform_data *pdata = chip->pdata;
  384. if (chip->clk)
  385. clk_disable_unprepare(chip->clk);
  386. if (pdata->enable_gpiod)
  387. gpiod_set_value(pdata->enable_gpiod, 0);
  388. }
  389. EXPORT_SYMBOL_GPL(lp55xx_deinit_device);
  390. int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)
  391. {
  392. struct lp55xx_platform_data *pdata = chip->pdata;
  393. struct lp55xx_device_config *cfg = chip->cfg;
  394. int num_channels = pdata->num_channels;
  395. struct lp55xx_led *each;
  396. u8 led_current;
  397. int ret;
  398. int i;
  399. if (!cfg->brightness_fn) {
  400. dev_err(&chip->cl->dev, "empty brightness configuration\n");
  401. return -EINVAL;
  402. }
  403. for (i = 0; i < num_channels; i++) {
  404. /* do not initialize channels that are not connected */
  405. if (pdata->led_config[i].led_current == 0)
  406. continue;
  407. led_current = pdata->led_config[i].led_current;
  408. each = led + i;
  409. ret = lp55xx_init_led(each, chip, i);
  410. if (ret)
  411. goto err_init_led;
  412. chip->num_leds++;
  413. each->chip = chip;
  414. /* setting led current at each channel */
  415. if (cfg->set_led_current)
  416. cfg->set_led_current(each, led_current);
  417. }
  418. return 0;
  419. err_init_led:
  420. return ret;
  421. }
  422. EXPORT_SYMBOL_GPL(lp55xx_register_leds);
  423. int lp55xx_register_sysfs(struct lp55xx_chip *chip)
  424. {
  425. struct device *dev = &chip->cl->dev;
  426. struct lp55xx_device_config *cfg = chip->cfg;
  427. int ret;
  428. if (!cfg->run_engine || !cfg->firmware_cb)
  429. goto dev_specific_attrs;
  430. ret = sysfs_create_group(&dev->kobj, &lp55xx_engine_attr_group);
  431. if (ret)
  432. return ret;
  433. dev_specific_attrs:
  434. return cfg->dev_attr_group ?
  435. sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0;
  436. }
  437. EXPORT_SYMBOL_GPL(lp55xx_register_sysfs);
  438. void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)
  439. {
  440. struct device *dev = &chip->cl->dev;
  441. struct lp55xx_device_config *cfg = chip->cfg;
  442. if (cfg->dev_attr_group)
  443. sysfs_remove_group(&dev->kobj, cfg->dev_attr_group);
  444. sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group);
  445. }
  446. EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
  447. static int lp55xx_parse_common_child(struct device_node *np,
  448. struct lp55xx_led_config *cfg,
  449. int led_number, int *chan_nr)
  450. {
  451. int ret;
  452. of_property_read_string(np, "chan-name",
  453. &cfg[led_number].name);
  454. of_property_read_u8(np, "led-cur",
  455. &cfg[led_number].led_current);
  456. of_property_read_u8(np, "max-cur",
  457. &cfg[led_number].max_current);
  458. ret = of_property_read_u32(np, "reg", chan_nr);
  459. if (ret)
  460. return ret;
  461. if (*chan_nr < 0 || *chan_nr > cfg->max_channel)
  462. return -EINVAL;
  463. return 0;
  464. }
  465. static int lp55xx_parse_multi_led_child(struct device_node *child,
  466. struct lp55xx_led_config *cfg,
  467. int child_number, int color_number)
  468. {
  469. int chan_nr, color_id, ret;
  470. ret = lp55xx_parse_common_child(child, cfg, child_number, &chan_nr);
  471. if (ret)
  472. return ret;
  473. ret = of_property_read_u32(child, "color", &color_id);
  474. if (ret)
  475. return ret;
  476. cfg[child_number].color_id[color_number] = color_id;
  477. cfg[child_number].output_num[color_number] = chan_nr;
  478. return 0;
  479. }
  480. static int lp55xx_parse_multi_led(struct device_node *np,
  481. struct lp55xx_led_config *cfg,
  482. int child_number)
  483. {
  484. struct device_node *child;
  485. int num_colors = 0, ret;
  486. for_each_available_child_of_node(np, child) {
  487. ret = lp55xx_parse_multi_led_child(child, cfg, child_number,
  488. num_colors);
  489. if (ret) {
  490. of_node_put(child);
  491. return ret;
  492. }
  493. num_colors++;
  494. }
  495. cfg[child_number].num_colors = num_colors;
  496. return 0;
  497. }
  498. static int lp55xx_parse_logical_led(struct device_node *np,
  499. struct lp55xx_led_config *cfg,
  500. int child_number)
  501. {
  502. int led_color, ret;
  503. int chan_nr = 0;
  504. cfg[child_number].default_trigger =
  505. of_get_property(np, "linux,default-trigger", NULL);
  506. ret = of_property_read_u32(np, "color", &led_color);
  507. if (ret)
  508. return ret;
  509. if (led_color == LED_COLOR_ID_RGB)
  510. return lp55xx_parse_multi_led(np, cfg, child_number);
  511. ret = lp55xx_parse_common_child(np, cfg, child_number, &chan_nr);
  512. if (ret < 0)
  513. return ret;
  514. cfg[child_number].chan_nr = chan_nr;
  515. return ret;
  516. }
  517. struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
  518. struct device_node *np,
  519. struct lp55xx_chip *chip)
  520. {
  521. struct device_node *child;
  522. struct lp55xx_platform_data *pdata;
  523. struct lp55xx_led_config *cfg;
  524. int num_channels;
  525. int i = 0;
  526. int ret;
  527. pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  528. if (!pdata)
  529. return ERR_PTR(-ENOMEM);
  530. num_channels = of_get_available_child_count(np);
  531. if (num_channels == 0) {
  532. dev_err(dev, "no LED channels\n");
  533. return ERR_PTR(-EINVAL);
  534. }
  535. cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL);
  536. if (!cfg)
  537. return ERR_PTR(-ENOMEM);
  538. pdata->led_config = &cfg[0];
  539. pdata->num_channels = num_channels;
  540. cfg->max_channel = chip->cfg->max_channel;
  541. for_each_available_child_of_node(np, child) {
  542. ret = lp55xx_parse_logical_led(child, cfg, i);
  543. if (ret) {
  544. of_node_put(child);
  545. return ERR_PTR(-EINVAL);
  546. }
  547. i++;
  548. }
  549. of_property_read_string(np, "label", &pdata->label);
  550. of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
  551. pdata->enable_gpiod = devm_gpiod_get_optional(dev, "enable",
  552. GPIOD_ASIS);
  553. if (IS_ERR(pdata->enable_gpiod))
  554. return ERR_CAST(pdata->enable_gpiod);
  555. /* LP8501 specific */
  556. of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);
  557. return pdata;
  558. }
  559. EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
  560. MODULE_AUTHOR("Milo Kim <[email protected]>");
  561. MODULE_DESCRIPTION("LP55xx Common Driver");
  562. MODULE_LICENSE("GPL");