388 lines · c
1// SPDX-License-Identifier: GPL-2.02// TI LM3697 LED chip family driver3// Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/4 5#include <linux/bits.h>6#include <linux/gpio/consumer.h>7#include <linux/i2c.h>8#include <linux/mod_devicetable.h>9#include <linux/module.h>10#include <linux/property.h>11#include <linux/regmap.h>12#include <linux/regulator/consumer.h>13#include <linux/types.h>14 15#include <linux/leds-ti-lmu-common.h>16 17#define LM3697_REV 0x018#define LM3697_RESET 0x119#define LM3697_OUTPUT_CONFIG 0x1020#define LM3697_CTRL_A_RAMP 0x1121#define LM3697_CTRL_B_RAMP 0x1222#define LM3697_CTRL_A_B_RT_RAMP 0x1323#define LM3697_CTRL_A_B_RAMP_CFG 0x1424#define LM3697_CTRL_A_B_BRT_CFG 0x1625#define LM3697_CTRL_A_FS_CURR_CFG 0x1726#define LM3697_CTRL_B_FS_CURR_CFG 0x1827#define LM3697_PWM_CFG 0x1c28#define LM3697_CTRL_A_BRT_LSB 0x2029#define LM3697_CTRL_A_BRT_MSB 0x2130#define LM3697_CTRL_B_BRT_LSB 0x2231#define LM3697_CTRL_B_BRT_MSB 0x2332#define LM3697_CTRL_ENABLE 0x2433 34#define LM3697_SW_RESET BIT(0)35 36#define LM3697_CTRL_A_EN BIT(0)37#define LM3697_CTRL_B_EN BIT(1)38#define LM3697_CTRL_A_B_EN (LM3697_CTRL_A_EN | LM3697_CTRL_B_EN)39 40#define LM3697_MAX_LED_STRINGS 341 42#define LM3697_CONTROL_A 043#define LM3697_CONTROL_B 144#define LM3697_MAX_CONTROL_BANKS 245 46/**47 * struct lm3697_led -48 * @hvled_strings: Array of LED strings associated with a control bank49 * @label: LED label50 * @led_dev: LED class device51 * @priv: Pointer to the device struct52 * @lmu_data: Register and setting values for common code53 * @control_bank: Control bank the LED is associated to. 0 is control bank A54 * 1 is control bank B55 * @enabled: LED brightness level (or LED_OFF)56 * @num_leds: Number of LEDs available57 */58struct lm3697_led {59 u32 hvled_strings[LM3697_MAX_LED_STRINGS];60 char label[LED_MAX_NAME_SIZE];61 struct led_classdev led_dev;62 struct lm3697 *priv;63 struct ti_lmu_bank lmu_data;64 int control_bank;65 int enabled;66 int num_leds;67};68 69/**70 * struct lm3697 -71 * @enable_gpio: Hardware enable gpio72 * @regulator: LED supply regulator pointer73 * @client: Pointer to the I2C client74 * @regmap: Devices register map75 * @dev: Pointer to the devices device struct76 * @lock: Lock for reading/writing the device77 * @leds: Array of LED strings78 * @bank_cfg: OUTPUT_CONFIG register values79 * @num_banks: Number of control banks80 */81struct lm3697 {82 struct gpio_desc *enable_gpio;83 struct regulator *regulator;84 struct i2c_client *client;85 struct regmap *regmap;86 struct device *dev;87 struct mutex lock;88 89 int bank_cfg;90 int num_banks;91 92 struct lm3697_led leds[] __counted_by(num_banks);93};94 95static const struct reg_default lm3697_reg_defs[] = {96 {LM3697_OUTPUT_CONFIG, 0x6},97 {LM3697_CTRL_A_RAMP, 0x0},98 {LM3697_CTRL_B_RAMP, 0x0},99 {LM3697_CTRL_A_B_RT_RAMP, 0x0},100 {LM3697_CTRL_A_B_RAMP_CFG, 0x0},101 {LM3697_CTRL_A_B_BRT_CFG, 0x0},102 {LM3697_CTRL_A_FS_CURR_CFG, 0x13},103 {LM3697_CTRL_B_FS_CURR_CFG, 0x13},104 {LM3697_PWM_CFG, 0xc},105 {LM3697_CTRL_A_BRT_LSB, 0x0},106 {LM3697_CTRL_A_BRT_MSB, 0x0},107 {LM3697_CTRL_B_BRT_LSB, 0x0},108 {LM3697_CTRL_B_BRT_MSB, 0x0},109 {LM3697_CTRL_ENABLE, 0x0},110};111 112static const struct regmap_config lm3697_regmap_config = {113 .reg_bits = 8,114 .val_bits = 8,115 116 .max_register = LM3697_CTRL_ENABLE,117 .reg_defaults = lm3697_reg_defs,118 .num_reg_defaults = ARRAY_SIZE(lm3697_reg_defs),119 .cache_type = REGCACHE_FLAT,120};121 122static int lm3697_brightness_set(struct led_classdev *led_cdev,123 enum led_brightness brt_val)124{125 struct lm3697_led *led = container_of(led_cdev, struct lm3697_led,126 led_dev);127 int ctrl_en_val = (1 << led->control_bank);128 struct device *dev = led->priv->dev;129 int ret;130 131 mutex_lock(&led->priv->lock);132 133 if (brt_val == LED_OFF) {134 ret = regmap_update_bits(led->priv->regmap, LM3697_CTRL_ENABLE,135 ctrl_en_val, ~ctrl_en_val);136 if (ret) {137 dev_err(dev, "Cannot write ctrl register\n");138 goto brightness_out;139 }140 141 led->enabled = LED_OFF;142 } else {143 ret = ti_lmu_common_set_brightness(&led->lmu_data, brt_val);144 if (ret) {145 dev_err(dev, "Cannot write brightness\n");146 goto brightness_out;147 }148 149 if (!led->enabled) {150 ret = regmap_update_bits(led->priv->regmap,151 LM3697_CTRL_ENABLE,152 ctrl_en_val, ctrl_en_val);153 if (ret) {154 dev_err(dev, "Cannot enable the device\n");155 goto brightness_out;156 }157 158 led->enabled = brt_val;159 }160 }161 162brightness_out:163 mutex_unlock(&led->priv->lock);164 return ret;165}166 167static int lm3697_init(struct lm3697 *priv)168{169 struct device *dev = priv->dev;170 struct lm3697_led *led;171 int i, ret;172 173 if (priv->enable_gpio) {174 gpiod_direction_output(priv->enable_gpio, 1);175 } else {176 ret = regmap_write(priv->regmap, LM3697_RESET, LM3697_SW_RESET);177 if (ret) {178 dev_err(dev, "Cannot reset the device\n");179 goto out;180 }181 }182 183 ret = regmap_write(priv->regmap, LM3697_CTRL_ENABLE, 0x0);184 if (ret) {185 dev_err(dev, "Cannot write ctrl enable\n");186 goto out;187 }188 189 ret = regmap_write(priv->regmap, LM3697_OUTPUT_CONFIG, priv->bank_cfg);190 if (ret)191 dev_err(dev, "Cannot write OUTPUT config\n");192 193 for (i = 0; i < priv->num_banks; i++) {194 led = &priv->leds[i];195 ret = ti_lmu_common_set_ramp(&led->lmu_data);196 if (ret)197 dev_err(dev, "Setting the ramp rate failed\n");198 }199out:200 return ret;201}202 203static int lm3697_probe_dt(struct lm3697 *priv)204{205 struct fwnode_handle *child = NULL;206 struct device *dev = priv->dev;207 struct lm3697_led *led;208 int ret = -EINVAL;209 int control_bank;210 size_t i = 0;211 int j;212 213 priv->enable_gpio = devm_gpiod_get_optional(dev, "enable",214 GPIOD_OUT_LOW);215 if (IS_ERR(priv->enable_gpio))216 return dev_err_probe(dev, PTR_ERR(priv->enable_gpio),217 "Failed to get enable GPIO\n");218 219 priv->regulator = devm_regulator_get(dev, "vled");220 if (IS_ERR(priv->regulator))221 priv->regulator = NULL;222 223 device_for_each_child_node(dev, child) {224 struct led_init_data init_data = {};225 226 ret = fwnode_property_read_u32(child, "reg", &control_bank);227 if (ret) {228 dev_err(dev, "reg property missing\n");229 goto child_out;230 }231 232 if (control_bank > LM3697_CONTROL_B) {233 dev_err(dev, "reg property is invalid\n");234 ret = -EINVAL;235 goto child_out;236 }237 238 led = &priv->leds[i];239 240 ret = ti_lmu_common_get_brt_res(dev, child, &led->lmu_data);241 if (ret)242 dev_warn(dev,243 "brightness resolution property missing\n");244 245 led->control_bank = control_bank;246 led->lmu_data.regmap = priv->regmap;247 led->lmu_data.runtime_ramp_reg = LM3697_CTRL_A_RAMP +248 control_bank;249 led->lmu_data.msb_brightness_reg = LM3697_CTRL_A_BRT_MSB +250 led->control_bank * 2;251 led->lmu_data.lsb_brightness_reg = LM3697_CTRL_A_BRT_LSB +252 led->control_bank * 2;253 254 led->num_leds = fwnode_property_count_u32(child, "led-sources");255 if (led->num_leds > LM3697_MAX_LED_STRINGS) {256 dev_err(dev, "Too many LED strings defined\n");257 continue;258 }259 260 ret = fwnode_property_read_u32_array(child, "led-sources",261 led->hvled_strings,262 led->num_leds);263 if (ret) {264 dev_err(dev, "led-sources property missing\n");265 goto child_out;266 }267 268 for (j = 0; j < led->num_leds; j++)269 priv->bank_cfg |=270 (led->control_bank << led->hvled_strings[j]);271 272 ret = ti_lmu_common_get_ramp_params(dev, child, &led->lmu_data);273 if (ret)274 dev_warn(dev, "runtime-ramp properties missing\n");275 276 init_data.fwnode = child;277 init_data.devicename = priv->client->name;278 /* for backwards compatibility if `label` is not present */279 init_data.default_label = ":";280 281 led->priv = priv;282 led->led_dev.max_brightness = led->lmu_data.max_brightness;283 led->led_dev.brightness_set_blocking = lm3697_brightness_set;284 285 ret = devm_led_classdev_register_ext(dev, &led->led_dev,286 &init_data);287 if (ret) {288 dev_err(dev, "led register err: %d\n", ret);289 goto child_out;290 }291 292 i++;293 }294 295 return ret;296 297child_out:298 fwnode_handle_put(child);299 return ret;300}301 302static int lm3697_probe(struct i2c_client *client)303{304 struct device *dev = &client->dev;305 struct lm3697 *led;306 int count;307 int ret;308 309 count = device_get_child_node_count(dev);310 if (!count || count > LM3697_MAX_CONTROL_BANKS) {311 dev_err(dev, "Strange device tree!");312 return -ENODEV;313 }314 315 led = devm_kzalloc(dev, struct_size(led, leds, count), GFP_KERNEL);316 if (!led)317 return -ENOMEM;318 319 mutex_init(&led->lock);320 i2c_set_clientdata(client, led);321 322 led->client = client;323 led->dev = dev;324 led->num_banks = count;325 led->regmap = devm_regmap_init_i2c(client, &lm3697_regmap_config);326 if (IS_ERR(led->regmap)) {327 ret = PTR_ERR(led->regmap);328 dev_err(dev, "Failed to allocate register map: %d\n", ret);329 return ret;330 }331 332 ret = lm3697_probe_dt(led);333 if (ret)334 return ret;335 336 return lm3697_init(led);337}338 339static void lm3697_remove(struct i2c_client *client)340{341 struct lm3697 *led = i2c_get_clientdata(client);342 struct device *dev = &led->client->dev;343 int ret;344 345 ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE,346 LM3697_CTRL_A_B_EN, 0);347 if (ret)348 dev_err(dev, "Failed to disable the device\n");349 350 if (led->enable_gpio)351 gpiod_direction_output(led->enable_gpio, 0);352 353 if (led->regulator) {354 ret = regulator_disable(led->regulator);355 if (ret)356 dev_err(dev, "Failed to disable regulator\n");357 }358 359 mutex_destroy(&led->lock);360}361 362static const struct i2c_device_id lm3697_id[] = {363 { "lm3697" },364 { }365};366MODULE_DEVICE_TABLE(i2c, lm3697_id);367 368static const struct of_device_id of_lm3697_leds_match[] = {369 { .compatible = "ti,lm3697", },370 {},371};372MODULE_DEVICE_TABLE(of, of_lm3697_leds_match);373 374static struct i2c_driver lm3697_driver = {375 .driver = {376 .name = "lm3697",377 .of_match_table = of_lm3697_leds_match,378 },379 .probe = lm3697_probe,380 .remove = lm3697_remove,381 .id_table = lm3697_id,382};383module_i2c_driver(lm3697_driver);384 385MODULE_DESCRIPTION("Texas Instruments LM3697 LED driver");386MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");387MODULE_LICENSE("GPL v2");388