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