brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · e009b6d Raw
173 lines · c
1// SPDX-License-Identifier: GPL-2.02// TI LM36274 LED chip family driver3// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/4 5#include <linux/bitops.h>6#include <linux/device.h>7#include <linux/err.h>8#include <linux/leds.h>9#include <linux/leds-ti-lmu-common.h>10#include <linux/mod_devicetable.h>11#include <linux/module.h>12#include <linux/platform_device.h>13#include <linux/property.h>14 15#include <linux/mfd/ti-lmu.h>16#include <linux/mfd/ti-lmu-register.h>17 18#include <uapi/linux/uleds.h>19 20#define LM36274_MAX_STRINGS	421#define LM36274_BL_EN		BIT(4)22 23/**24 * struct lm3627425 * @pdev: platform device26 * @led_dev: led class device27 * @lmu_data: Register and setting values for common code28 * @regmap: Devices register map29 * @dev: Pointer to the devices device struct30 * @led_sources: The LED strings supported in this array31 * @num_leds: Number of LED strings are supported in this array32 */33struct lm36274 {34	struct platform_device *pdev;35	struct led_classdev led_dev;36	struct ti_lmu_bank lmu_data;37	struct regmap *regmap;38	struct device *dev;39 40	u32 led_sources[LM36274_MAX_STRINGS];41	int num_leds;42};43 44static int lm36274_brightness_set(struct led_classdev *led_cdev,45				  enum led_brightness brt_val)46{47	struct lm36274 *chip = container_of(led_cdev, struct lm36274, led_dev);48 49	return ti_lmu_common_set_brightness(&chip->lmu_data, brt_val);50}51 52static int lm36274_init(struct lm36274 *chip)53{54	int enable_val = 0;55	int i;56 57	for (i = 0; i < chip->num_leds; i++)58		enable_val |= (1 << chip->led_sources[i]);59 60	if (!enable_val) {61		dev_err(chip->dev, "No LEDs were enabled\n");62		return -EINVAL;63	}64 65	enable_val |= LM36274_BL_EN;66 67	return regmap_write(chip->regmap, LM36274_REG_BL_EN, enable_val);68}69 70static int lm36274_parse_dt(struct lm36274 *chip,71			    struct led_init_data *init_data)72{73	struct device *dev = chip->dev;74	struct fwnode_handle *child;75	int ret;76 77	/* There should only be 1 node */78	if (device_get_child_node_count(dev) != 1)79		return -EINVAL;80 81	child = device_get_next_child_node(dev, NULL);82 83	init_data->fwnode = child;84	init_data->devicename = chip->pdev->name;85	/* for backwards compatibility when `label` property is not present */86	init_data->default_label = ":";87 88	chip->num_leds = fwnode_property_count_u32(child, "led-sources");89	if (chip->num_leds <= 0) {90		ret = -ENODEV;91		goto err;92	}93 94	ret = fwnode_property_read_u32_array(child, "led-sources",95					     chip->led_sources, chip->num_leds);96	if (ret) {97		dev_err(dev, "led-sources property missing\n");98		goto err;99	}100 101	return 0;102err:103	fwnode_handle_put(child);104	return ret;105}106 107static int lm36274_probe(struct platform_device *pdev)108{109	struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent);110	struct led_init_data init_data = {};111	struct lm36274 *chip;112	int ret;113 114	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);115	if (!chip)116		return -ENOMEM;117 118	chip->pdev = pdev;119	chip->dev = &pdev->dev;120	chip->regmap = lmu->regmap;121	platform_set_drvdata(pdev, chip);122 123	ret = lm36274_parse_dt(chip, &init_data);124	if (ret) {125		dev_err(chip->dev, "Failed to parse DT node\n");126		return ret;127	}128 129	ret = lm36274_init(chip);130	if (ret) {131		fwnode_handle_put(init_data.fwnode);132		dev_err(chip->dev, "Failed to init the device\n");133		return ret;134	}135 136	chip->lmu_data.regmap = chip->regmap;137	chip->lmu_data.max_brightness = MAX_BRIGHTNESS_11BIT;138	chip->lmu_data.msb_brightness_reg = LM36274_REG_BRT_MSB;139	chip->lmu_data.lsb_brightness_reg = LM36274_REG_BRT_LSB;140 141	chip->led_dev.max_brightness = MAX_BRIGHTNESS_11BIT;142	chip->led_dev.brightness_set_blocking = lm36274_brightness_set;143 144	ret = devm_led_classdev_register_ext(chip->dev, &chip->led_dev,145					     &init_data);146	if (ret)147		dev_err(chip->dev, "Failed to register LED for node %pfw\n",148			init_data.fwnode);149 150	fwnode_handle_put(init_data.fwnode);151 152	return ret;153}154 155static const struct of_device_id of_lm36274_leds_match[] = {156	{ .compatible = "ti,lm36274-backlight", },157	{},158};159MODULE_DEVICE_TABLE(of, of_lm36274_leds_match);160 161static struct platform_driver lm36274_driver = {162	.probe  = lm36274_probe,163	.driver = {164		.name = "lm36274-leds",165		.of_match_table = of_lm36274_leds_match,166	},167};168module_platform_driver(lm36274_driver)169 170MODULE_DESCRIPTION("Texas Instruments LM36274 LED driver");171MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");172MODULE_LICENSE("GPL v2");173