leds-pca9633.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright 2011 bct electronic GmbH
  3. *
  4. * Author: Peter Meerwald <p.meerwald@bct-electronic.com>
  5. *
  6. * Based on leds-pca955x.c
  7. *
  8. * This file is subject to the terms and conditions of version 2 of
  9. * the GNU General Public License. See the file COPYING in the main
  10. * directory of this archive for more details.
  11. *
  12. * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
  13. *
  14. */
  15. #include <linux/module.h>
  16. #include <linux/delay.h>
  17. #include <linux/string.h>
  18. #include <linux/ctype.h>
  19. #include <linux/leds.h>
  20. #include <linux/err.h>
  21. #include <linux/i2c.h>
  22. #include <linux/workqueue.h>
  23. #include <linux/slab.h>
  24. /* LED select registers determine the source that drives LED outputs */
  25. #define PCA9633_LED_OFF 0x0 /* LED driver off */
  26. #define PCA9633_LED_ON 0x1 /* LED driver on */
  27. #define PCA9633_LED_PWM 0x2 /* Controlled through PWM */
  28. #define PCA9633_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */
  29. #define PCA9633_MODE1 0x00
  30. #define PCA9633_MODE2 0x01
  31. #define PCA9633_PWM_BASE 0x02
  32. #define PCA9633_LEDOUT 0x08
  33. static const struct i2c_device_id pca9633_id[] = {
  34. { "pca9633", 0 },
  35. { }
  36. };
  37. MODULE_DEVICE_TABLE(i2c, pca9633_id);
  38. struct pca9633_led {
  39. struct i2c_client *client;
  40. struct work_struct work;
  41. enum led_brightness brightness;
  42. struct led_classdev led_cdev;
  43. int led_num; /* 0 .. 3 potentially */
  44. char name[32];
  45. };
  46. static void pca9633_led_work(struct work_struct *work)
  47. {
  48. struct pca9633_led *pca9633 = container_of(work,
  49. struct pca9633_led, work);
  50. u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
  51. int shift = 2 * pca9633->led_num;
  52. u8 mask = 0x3 << shift;
  53. switch (pca9633->brightness) {
  54. case LED_FULL:
  55. i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
  56. (ledout & ~mask) | (PCA9633_LED_ON << shift));
  57. break;
  58. case LED_OFF:
  59. i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
  60. ledout & ~mask);
  61. break;
  62. default:
  63. i2c_smbus_write_byte_data(pca9633->client,
  64. PCA9633_PWM_BASE + pca9633->led_num,
  65. pca9633->brightness);
  66. i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
  67. (ledout & ~mask) | (PCA9633_LED_PWM << shift));
  68. break;
  69. }
  70. }
  71. static void pca9633_led_set(struct led_classdev *led_cdev,
  72. enum led_brightness value)
  73. {
  74. struct pca9633_led *pca9633;
  75. pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
  76. pca9633->brightness = value;
  77. /*
  78. * Must use workqueue for the actual I/O since I2C operations
  79. * can sleep.
  80. */
  81. schedule_work(&pca9633->work);
  82. }
  83. static int __devinit pca9633_probe(struct i2c_client *client,
  84. const struct i2c_device_id *id)
  85. {
  86. struct pca9633_led *pca9633;
  87. struct led_platform_data *pdata;
  88. int i, err;
  89. pdata = client->dev.platform_data;
  90. if (pdata) {
  91. if (pdata->num_leds <= 0 || pdata->num_leds > 4) {
  92. dev_err(&client->dev, "board info must claim at most 4 LEDs");
  93. return -EINVAL;
  94. }
  95. }
  96. pca9633 = kcalloc(4, sizeof(*pca9633), GFP_KERNEL);
  97. if (!pca9633)
  98. return -ENOMEM;
  99. i2c_set_clientdata(client, pca9633);
  100. for (i = 0; i < 4; i++) {
  101. pca9633[i].client = client;
  102. pca9633[i].led_num = i;
  103. /* Platform data can specify LED names and default triggers */
  104. if (pdata && i < pdata->num_leds) {
  105. if (pdata->leds[i].name)
  106. snprintf(pca9633[i].name,
  107. sizeof(pca9633[i].name), "pca9633:%s",
  108. pdata->leds[i].name);
  109. if (pdata->leds[i].default_trigger)
  110. pca9633[i].led_cdev.default_trigger =
  111. pdata->leds[i].default_trigger;
  112. } else {
  113. snprintf(pca9633[i].name, sizeof(pca9633[i].name),
  114. "pca9633:%d", i);
  115. }
  116. pca9633[i].led_cdev.name = pca9633[i].name;
  117. pca9633[i].led_cdev.brightness_set = pca9633_led_set;
  118. INIT_WORK(&pca9633[i].work, pca9633_led_work);
  119. err = led_classdev_register(&client->dev, &pca9633[i].led_cdev);
  120. if (err < 0)
  121. goto exit;
  122. }
  123. /* Disable LED all-call address and set normal mode */
  124. i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
  125. /* Turn off LEDs */
  126. i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
  127. return 0;
  128. exit:
  129. while (i--) {
  130. led_classdev_unregister(&pca9633[i].led_cdev);
  131. cancel_work_sync(&pca9633[i].work);
  132. }
  133. kfree(pca9633);
  134. return err;
  135. }
  136. static int __devexit pca9633_remove(struct i2c_client *client)
  137. {
  138. struct pca9633_led *pca9633 = i2c_get_clientdata(client);
  139. int i;
  140. for (i = 0; i < 4; i++) {
  141. led_classdev_unregister(&pca9633[i].led_cdev);
  142. cancel_work_sync(&pca9633[i].work);
  143. }
  144. kfree(pca9633);
  145. return 0;
  146. }
  147. static struct i2c_driver pca9633_driver = {
  148. .driver = {
  149. .name = "leds-pca9633",
  150. .owner = THIS_MODULE,
  151. },
  152. .probe = pca9633_probe,
  153. .remove = __devexit_p(pca9633_remove),
  154. .id_table = pca9633_id,
  155. };
  156. module_i2c_driver(pca9633_driver);
  157. MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
  158. MODULE_DESCRIPTION("PCA9633 LED driver");
  159. MODULE_LICENSE("GPL v2");