leds-smartrg-system.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/delay.h>
  3. #include <linux/i2c.h>
  4. #include <linux/init.h>
  5. #include <linux/leds.h>
  6. #include <linux/module.h>
  7. #include <linux/mutex.h>
  8. #include <linux/of.h>
  9. /**
  10. * Driver for SmartRG RGBW LED microcontroller.
  11. * RGBW LED is connected to a Holtek HT45F0062 that is on the I2C bus.
  12. *
  13. */
  14. struct srg_led_ctrl;
  15. struct srg_led {
  16. u8 index;
  17. struct led_classdev led;
  18. struct srg_led_ctrl *ctrl;
  19. };
  20. struct srg_led_ctrl {
  21. struct mutex lock;
  22. struct i2c_client *client;
  23. struct srg_led channel[4];
  24. u8 control[5];
  25. };
  26. static int
  27. srg_led_i2c_write(struct srg_led_ctrl *sysled_ctrl, u8 reg, u8 value)
  28. {
  29. return i2c_smbus_write_byte_data(sysled_ctrl->client, reg, value);
  30. }
  31. /*
  32. * MC LED Command: 0 = OFF, 1 = ON, 2 = Flash, 3 = Pulse, 4 = Blink
  33. * */
  34. static int
  35. srg_led_control_sync(struct srg_led_ctrl *sysled_ctrl)
  36. {
  37. int i, ret;
  38. for (i = 1; i < 5; i++) {
  39. ret = srg_led_i2c_write(sysled_ctrl, i, sysled_ctrl->control[i]);
  40. if (ret)
  41. break;
  42. }
  43. return ret;
  44. }
  45. /*
  46. * This function overrides the led driver timer trigger to offload
  47. * flashing to the micro-controller. The negative effect of this
  48. * is the inability to configure the delay_on and delay_off periods.
  49. *
  50. * */
  51. static int
  52. srg_led_set_pulse(struct led_classdev *led_cdev,
  53. unsigned long *delay_on,
  54. unsigned long *delay_off)
  55. {
  56. struct srg_led *sysled = container_of(led_cdev, struct srg_led, led);
  57. struct srg_led_ctrl *sysled_ctrl = sysled->ctrl;
  58. bool blinking = false, pulsing = false;
  59. u8 cbyte;
  60. int ret;
  61. if (delay_on && delay_off && (*delay_on > 100) && (*delay_on <= 500)) {
  62. pulsing = true;
  63. *delay_on = 500;
  64. *delay_off = 500;
  65. } else if (delay_on && delay_off && (*delay_on >= 50) && (*delay_on <= 100)) {
  66. blinking = true;
  67. *delay_on = 50;
  68. *delay_off = 50;
  69. }
  70. cbyte = pulsing ? 3 : blinking ? 2 : 0;
  71. mutex_lock(&sysled_ctrl->lock);
  72. ret = srg_led_i2c_write(sysled_ctrl, sysled->index + 4,
  73. (blinking || pulsing) ? 255 : 0);
  74. if (!ret) {
  75. sysled_ctrl->control[sysled->index] = cbyte;
  76. ret = srg_led_control_sync(sysled_ctrl);
  77. }
  78. mutex_unlock(&sysled_ctrl->lock);
  79. return !cbyte;
  80. }
  81. static int
  82. srg_led_set_brightness(struct led_classdev *led_cdev,
  83. enum led_brightness value)
  84. {
  85. struct srg_led *sysled = container_of(led_cdev, struct srg_led, led);
  86. struct srg_led_ctrl *sysled_ctrl = sysled->ctrl;
  87. int ret;
  88. mutex_lock(&sysled_ctrl->lock);
  89. ret = srg_led_i2c_write(sysled_ctrl, sysled->index + 4, value);
  90. if (!ret) {
  91. sysled_ctrl->control[sysled->index] = !!value;
  92. ret = srg_led_control_sync(sysled_ctrl);
  93. }
  94. mutex_unlock(&sysled_ctrl->lock);
  95. return ret;
  96. }
  97. static int
  98. srg_led_init_led(struct srg_led_ctrl *sysled_ctrl, struct device_node *np)
  99. {
  100. struct led_init_data init_data = {};
  101. struct led_classdev *led_cdev;
  102. struct srg_led *sysled;
  103. int index, ret;
  104. if (!np)
  105. return -ENOENT;
  106. ret = of_property_read_u32(np, "reg", &index);
  107. if (ret) {
  108. dev_err(&sysled_ctrl->client->dev,
  109. "srg_led_init_led: no reg defined in np!\n");
  110. return ret;
  111. }
  112. if (index < 1 || index > 4)
  113. return -EINVAL;
  114. sysled = &sysled_ctrl->channel[index - 1];
  115. led_cdev = &sysled->led;
  116. sysled->index = index;
  117. sysled->ctrl = sysled_ctrl;
  118. init_data.fwnode = of_fwnode_handle(np);
  119. led_cdev->name = of_get_property(np, "label", NULL) ? : np->name;
  120. led_cdev->brightness = LED_OFF;
  121. led_cdev->max_brightness = LED_FULL;
  122. led_cdev->brightness_set_blocking = srg_led_set_brightness;
  123. led_cdev->blink_set = srg_led_set_pulse;
  124. srg_led_i2c_write(sysled_ctrl, index + 4, 0);
  125. ret = devm_led_classdev_register_ext(&sysled_ctrl->client->dev,
  126. led_cdev, &init_data);
  127. if (ret) {
  128. dev_err(&sysled_ctrl->client->dev,
  129. "srg_led_init_led: led register %s error ret %d!n",
  130. led_cdev->name, ret);
  131. return ret;
  132. }
  133. return 0;
  134. }
  135. static int
  136. srg_led_probe(struct i2c_client *client)
  137. {
  138. struct device_node *np = client->dev.of_node, *child;
  139. struct srg_led_ctrl *sysled_ctrl;
  140. int err;
  141. sysled_ctrl = devm_kzalloc(&client->dev, sizeof(*sysled_ctrl), GFP_KERNEL);
  142. if (!sysled_ctrl)
  143. return -ENOMEM;
  144. sysled_ctrl->client = client;
  145. err = devm_mutex_init(&client->dev, &sysled_ctrl->lock);
  146. if (err)
  147. return err;
  148. i2c_set_clientdata(client, sysled_ctrl);
  149. for_each_available_child_of_node(np, child) {
  150. if (srg_led_init_led(sysled_ctrl, child))
  151. continue;
  152. msleep(5);
  153. }
  154. return srg_led_control_sync(sysled_ctrl);;
  155. }
  156. static void srg_led_disable(struct i2c_client *client)
  157. {
  158. struct srg_led_ctrl *sysled_ctrl = i2c_get_clientdata(client);
  159. int i;
  160. for (i = 1; i < 10; i++)
  161. srg_led_i2c_write(sysled_ctrl, i, 0);
  162. }
  163. static const struct i2c_device_id srg_led_id[] = {
  164. { "srg-sysled", 0 },
  165. { }
  166. };
  167. MODULE_DEVICE_TABLE(i2c, srg_led_id);
  168. static const struct of_device_id of_srg_led_match[] = {
  169. { .compatible = "srg,sysled", },
  170. {},
  171. };
  172. MODULE_DEVICE_TABLE(of, of_srg_led_match);
  173. static struct i2c_driver srg_sysled_driver = {
  174. .driver = {
  175. .name = "srg-sysled",
  176. .of_match_table = of_srg_led_match,
  177. },
  178. .probe = srg_led_probe,
  179. .remove = srg_led_disable,
  180. .id_table = srg_led_id,
  181. };
  182. module_i2c_driver(srg_sysled_driver);
  183. MODULE_DESCRIPTION("SmartRG system LED driver");
  184. MODULE_AUTHOR("Shen Loh <[email protected]>");
  185. MODULE_AUTHOR("Daniel Golle <[email protected]>");
  186. MODULE_LICENSE("GPL v2");