leds-msm-gpio-flash.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* Copyright (c) 2013, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/leds.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/of_gpio.h>
  18. #include <linux/gpio.h>
  19. #include <linux/of.h>
  20. #include <linux/printk.h>
  21. #define LED_GPIO_FLASH_DRIVER_NAME "qcom,leds-gpio-flash"
  22. #define LED_TRIGGER_DEFAULT "none"
  23. struct led_gpio_flash_data {
  24. int flash_en;
  25. int flash_now;
  26. int brightness;
  27. struct led_classdev cdev;
  28. };
  29. static struct of_device_id led_gpio_flash_of_match[] = {
  30. {.compatible = LED_GPIO_FLASH_DRIVER_NAME,},
  31. {},
  32. };
  33. static void led_gpio_brightness_set(struct led_classdev *led_cdev,
  34. enum led_brightness value)
  35. {
  36. int rc = 0;
  37. struct led_gpio_flash_data *flash_led =
  38. container_of(led_cdev, struct led_gpio_flash_data, cdev);
  39. int brightness = value;
  40. int flash_en = 0, flash_now = 0;
  41. if (brightness > LED_HALF) {
  42. flash_en = 0;
  43. flash_now = 1;
  44. } else if (brightness > LED_OFF) {
  45. flash_en = 1;
  46. flash_now = 0;
  47. } else {
  48. flash_en = 0;
  49. flash_now = 0;
  50. }
  51. rc = gpio_direction_output(flash_led->flash_en, flash_en);
  52. if (rc) {
  53. pr_err("%s: Failed to set gpio %d\n", __func__,
  54. flash_led->flash_en);
  55. goto err;
  56. }
  57. rc = gpio_direction_output(flash_led->flash_now, flash_now);
  58. if (rc) {
  59. pr_err("%s: Failed to set gpio %d\n", __func__,
  60. flash_led->flash_now);
  61. goto err;
  62. }
  63. flash_led->brightness = brightness;
  64. err:
  65. return;
  66. }
  67. static enum led_brightness led_gpio_brightness_get(struct led_classdev
  68. *led_cdev)
  69. {
  70. struct led_gpio_flash_data *flash_led =
  71. container_of(led_cdev, struct led_gpio_flash_data, cdev);
  72. return flash_led->brightness;
  73. }
  74. int __devinit led_gpio_flash_probe(struct platform_device *pdev)
  75. {
  76. int rc = 0;
  77. const char *temp_str;
  78. struct led_gpio_flash_data *flash_led = NULL;
  79. struct device_node *node = pdev->dev.of_node;
  80. flash_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_flash_data),
  81. GFP_KERNEL);
  82. if (flash_led == NULL) {
  83. dev_err(&pdev->dev, "%s:%d Unable to allocate memory\n",
  84. __func__, __LINE__);
  85. return -ENOMEM;
  86. }
  87. flash_led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
  88. rc = of_property_read_string(node, "linux,default-trigger", &temp_str);
  89. if (!rc)
  90. flash_led->cdev.default_trigger = temp_str;
  91. flash_led->flash_en = of_get_named_gpio(node, "qcom,flash-en", 0);
  92. if (flash_led->flash_en < 0) {
  93. dev_err(&pdev->dev,
  94. "Looking up %s property in node %s failed. rc = %d\n",
  95. "flash-en", node->full_name, flash_led->flash_en);
  96. goto error;
  97. } else {
  98. rc = gpio_request(flash_led->flash_en, "FLASH_EN");
  99. if (rc) {
  100. dev_err(&pdev->dev,
  101. "%s: Failed to request gpio %d,rc = %d\n",
  102. __func__, flash_led->flash_en, rc);
  103. goto error;
  104. }
  105. }
  106. flash_led->flash_now = of_get_named_gpio(node, "qcom,flash-now", 0);
  107. if (flash_led->flash_now < 0) {
  108. dev_err(&pdev->dev,
  109. "Looking up %s property in node %s failed. rc = %d\n",
  110. "flash-now", node->full_name, flash_led->flash_now);
  111. goto error;
  112. } else {
  113. rc = gpio_request(flash_led->flash_now, "FLASH_NOW");
  114. if (rc) {
  115. dev_err(&pdev->dev,
  116. "%s: Failed to request gpio %d,rc = %d\n",
  117. __func__, flash_led->flash_now, rc);
  118. goto error;
  119. }
  120. }
  121. gpio_tlmm_config(GPIO_CFG(flash_led->flash_en, 0,
  122. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
  123. GPIO_CFG_2MA), GPIO_CFG_ENABLE);
  124. gpio_tlmm_config(GPIO_CFG(flash_led->flash_now, 0,
  125. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
  126. GPIO_CFG_2MA), GPIO_CFG_ENABLE);
  127. rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
  128. if (rc) {
  129. dev_err(&pdev->dev, "%s: Failed to read linux name. rc = %d\n",
  130. __func__, rc);
  131. goto error;
  132. }
  133. platform_set_drvdata(pdev, flash_led);
  134. flash_led->cdev.max_brightness = LED_FULL;
  135. flash_led->cdev.brightness_set = led_gpio_brightness_set;
  136. flash_led->cdev.brightness_get = led_gpio_brightness_get;
  137. rc = led_classdev_register(&pdev->dev, &flash_led->cdev);
  138. if (rc) {
  139. dev_err(&pdev->dev, "%s: Failed to register led dev. rc = %d\n",
  140. __func__, rc);
  141. goto error;
  142. }
  143. return 0;
  144. error:
  145. devm_kfree(&pdev->dev, flash_led);
  146. return rc;
  147. }
  148. int __devexit led_gpio_flash_remove(struct platform_device *pdev)
  149. {
  150. struct led_gpio_flash_data *flash_led =
  151. (struct led_gpio_flash_data *)platform_get_drvdata(pdev);
  152. led_classdev_unregister(&flash_led->cdev);
  153. devm_kfree(&pdev->dev, flash_led);
  154. return 0;
  155. }
  156. static struct platform_driver led_gpio_flash_driver = {
  157. .probe = led_gpio_flash_probe,
  158. .remove = __devexit_p(led_gpio_flash_remove),
  159. .driver = {
  160. .name = LED_GPIO_FLASH_DRIVER_NAME,
  161. .owner = THIS_MODULE,
  162. .of_match_table = led_gpio_flash_of_match,
  163. }
  164. };
  165. static int __init led_gpio_flash_init(void)
  166. {
  167. return platform_driver_register(&led_gpio_flash_driver);
  168. }
  169. static void __exit led_gpio_flash_exit(void)
  170. {
  171. return platform_driver_unregister(&led_gpio_flash_driver);
  172. }
  173. late_initcall(led_gpio_flash_init);
  174. module_exit(led_gpio_flash_exit);
  175. MODULE_DESCRIPTION("QCOM GPIO LEDs driver");
  176. MODULE_LICENSE("GPL v2");
  177. MODULE_ALIAS("leds:leds-msm-gpio-flash");