leds-max77650.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Copyright (C) 2018 BayLibre SAS
  4. // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
  5. //
  6. // LED driver for MAXIM 77650/77651 charger/power-supply.
  7. #include <linux/i2c.h>
  8. #include <linux/leds.h>
  9. #include <linux/mfd/max77650.h>
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/regmap.h>
  13. #define MAX77650_LED_NUM_LEDS 3
  14. #define MAX77650_LED_A_BASE 0x40
  15. #define MAX77650_LED_B_BASE 0x43
  16. #define MAX77650_LED_BR_MASK GENMASK(4, 0)
  17. #define MAX77650_LED_EN_MASK GENMASK(7, 6)
  18. #define MAX77650_LED_MAX_BRIGHTNESS MAX77650_LED_BR_MASK
  19. /* Enable EN_LED_MSTR. */
  20. #define MAX77650_LED_TOP_DEFAULT BIT(0)
  21. #define MAX77650_LED_ENABLE GENMASK(7, 6)
  22. #define MAX77650_LED_DISABLE 0x00
  23. #define MAX77650_LED_A_DEFAULT MAX77650_LED_DISABLE
  24. /* 100% on duty */
  25. #define MAX77650_LED_B_DEFAULT GENMASK(3, 0)
  26. struct max77650_led {
  27. struct led_classdev cdev;
  28. struct regmap *map;
  29. unsigned int regA;
  30. unsigned int regB;
  31. };
  32. static struct max77650_led *max77650_to_led(struct led_classdev *cdev)
  33. {
  34. return container_of(cdev, struct max77650_led, cdev);
  35. }
  36. static int max77650_led_brightness_set(struct led_classdev *cdev,
  37. enum led_brightness brightness)
  38. {
  39. struct max77650_led *led = max77650_to_led(cdev);
  40. int val, mask;
  41. mask = MAX77650_LED_BR_MASK | MAX77650_LED_EN_MASK;
  42. if (brightness == LED_OFF)
  43. val = MAX77650_LED_DISABLE;
  44. else
  45. val = MAX77650_LED_ENABLE | brightness;
  46. return regmap_update_bits(led->map, led->regA, mask, val);
  47. }
  48. static int max77650_led_probe(struct platform_device *pdev)
  49. {
  50. struct fwnode_handle *child;
  51. struct max77650_led *leds, *led;
  52. struct device *dev;
  53. struct regmap *map;
  54. int rv, num_leds;
  55. u32 reg;
  56. dev = &pdev->dev;
  57. leds = devm_kcalloc(dev, sizeof(*leds),
  58. MAX77650_LED_NUM_LEDS, GFP_KERNEL);
  59. if (!leds)
  60. return -ENOMEM;
  61. map = dev_get_regmap(dev->parent, NULL);
  62. if (!map)
  63. return -ENODEV;
  64. num_leds = device_get_child_node_count(dev);
  65. if (!num_leds || num_leds > MAX77650_LED_NUM_LEDS)
  66. return -ENODEV;
  67. device_for_each_child_node(dev, child) {
  68. struct led_init_data init_data = {};
  69. rv = fwnode_property_read_u32(child, "reg", &reg);
  70. if (rv || reg >= MAX77650_LED_NUM_LEDS) {
  71. rv = -EINVAL;
  72. goto err_node_put;
  73. }
  74. led = &leds[reg];
  75. led->map = map;
  76. led->regA = MAX77650_LED_A_BASE + reg;
  77. led->regB = MAX77650_LED_B_BASE + reg;
  78. led->cdev.brightness_set_blocking = max77650_led_brightness_set;
  79. led->cdev.max_brightness = MAX77650_LED_MAX_BRIGHTNESS;
  80. init_data.fwnode = child;
  81. init_data.devicename = "max77650";
  82. /* for backwards compatibility if `label` is not present */
  83. init_data.default_label = ":";
  84. rv = devm_led_classdev_register_ext(dev, &led->cdev,
  85. &init_data);
  86. if (rv)
  87. goto err_node_put;
  88. rv = regmap_write(map, led->regA, MAX77650_LED_A_DEFAULT);
  89. if (rv)
  90. goto err_node_put;
  91. rv = regmap_write(map, led->regB, MAX77650_LED_B_DEFAULT);
  92. if (rv)
  93. goto err_node_put;
  94. }
  95. return regmap_write(map,
  96. MAX77650_REG_CNFG_LED_TOP,
  97. MAX77650_LED_TOP_DEFAULT);
  98. err_node_put:
  99. fwnode_handle_put(child);
  100. return rv;
  101. }
  102. static const struct of_device_id max77650_led_of_match[] = {
  103. { .compatible = "maxim,max77650-led" },
  104. { }
  105. };
  106. MODULE_DEVICE_TABLE(of, max77650_led_of_match);
  107. static struct platform_driver max77650_led_driver = {
  108. .driver = {
  109. .name = "max77650-led",
  110. .of_match_table = max77650_led_of_match,
  111. },
  112. .probe = max77650_led_probe,
  113. };
  114. module_platform_driver(max77650_led_driver);
  115. MODULE_DESCRIPTION("MAXIM 77650/77651 LED driver");
  116. MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
  117. MODULE_LICENSE("GPL v2");
  118. MODULE_ALIAS("platform:max77650-led");