leds-tps6105x.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2019 Sven Van Asbroeck
  4. */
  5. #include <linux/leds.h>
  6. #include <linux/module.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/mfd/tps6105x.h>
  9. #include <linux/regmap.h>
  10. struct tps6105x_priv {
  11. struct regmap *regmap;
  12. struct led_classdev cdev;
  13. struct fwnode_handle *fwnode;
  14. };
  15. static void tps6105x_handle_put(void *data)
  16. {
  17. struct tps6105x_priv *priv = data;
  18. fwnode_handle_put(priv->fwnode);
  19. }
  20. static int tps6105x_brightness_set(struct led_classdev *cdev,
  21. enum led_brightness brightness)
  22. {
  23. struct tps6105x_priv *priv = container_of(cdev, struct tps6105x_priv,
  24. cdev);
  25. return regmap_update_bits(priv->regmap, TPS6105X_REG_0,
  26. TPS6105X_REG0_TORCHC_MASK,
  27. brightness << TPS6105X_REG0_TORCHC_SHIFT);
  28. }
  29. static int tps6105x_led_probe(struct platform_device *pdev)
  30. {
  31. struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
  32. struct tps6105x_platform_data *pdata = tps6105x->pdata;
  33. struct led_init_data init_data = { };
  34. struct tps6105x_priv *priv;
  35. int ret;
  36. /* This instance is not set for torch mode so bail out */
  37. if (pdata->mode != TPS6105X_MODE_TORCH) {
  38. dev_info(&pdev->dev,
  39. "chip not in torch mode, exit probe");
  40. return -EINVAL;
  41. }
  42. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  43. if (!priv)
  44. return -ENOMEM;
  45. /* fwnode/devicetree is optional. NULL is allowed for priv->fwnode */
  46. priv->fwnode = device_get_next_child_node(pdev->dev.parent, NULL);
  47. ret = devm_add_action_or_reset(&pdev->dev, tps6105x_handle_put, priv);
  48. if (ret)
  49. return ret;
  50. priv->regmap = tps6105x->regmap;
  51. priv->cdev.brightness_set_blocking = tps6105x_brightness_set;
  52. priv->cdev.max_brightness = 7;
  53. init_data.devicename = "tps6105x";
  54. init_data.default_label = ":torch";
  55. init_data.fwnode = priv->fwnode;
  56. ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0,
  57. TPS6105X_REG0_MODE_MASK |
  58. TPS6105X_REG0_TORCHC_MASK,
  59. TPS6105X_REG0_MODE_TORCH <<
  60. TPS6105X_REG0_MODE_SHIFT);
  61. if (ret)
  62. return ret;
  63. return devm_led_classdev_register_ext(&pdev->dev, &priv->cdev,
  64. &init_data);
  65. }
  66. static struct platform_driver led_driver = {
  67. .probe = tps6105x_led_probe,
  68. .driver = {
  69. .name = "tps6105x-leds",
  70. },
  71. };
  72. module_platform_driver(led_driver);
  73. MODULE_DESCRIPTION("TPS6105x LED driver");
  74. MODULE_AUTHOR("Sven Van Asbroeck <TheSven73@gmail.com>");
  75. MODULE_LICENSE("GPL v2");