Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // TI LM3697 LED chip family driver
0003 // Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
0004 
0005 #include <linux/bits.h>
0006 #include <linux/gpio/consumer.h>
0007 #include <linux/i2c.h>
0008 #include <linux/mod_devicetable.h>
0009 #include <linux/module.h>
0010 #include <linux/property.h>
0011 #include <linux/regmap.h>
0012 #include <linux/regulator/consumer.h>
0013 #include <linux/types.h>
0014 
0015 #include <linux/leds-ti-lmu-common.h>
0016 
0017 #define LM3697_REV          0x0
0018 #define LM3697_RESET            0x1
0019 #define LM3697_OUTPUT_CONFIG        0x10
0020 #define LM3697_CTRL_A_RAMP      0x11
0021 #define LM3697_CTRL_B_RAMP      0x12
0022 #define LM3697_CTRL_A_B_RT_RAMP     0x13
0023 #define LM3697_CTRL_A_B_RAMP_CFG    0x14
0024 #define LM3697_CTRL_A_B_BRT_CFG     0x16
0025 #define LM3697_CTRL_A_FS_CURR_CFG   0x17
0026 #define LM3697_CTRL_B_FS_CURR_CFG   0x18
0027 #define LM3697_PWM_CFG          0x1c
0028 #define LM3697_CTRL_A_BRT_LSB       0x20
0029 #define LM3697_CTRL_A_BRT_MSB       0x21
0030 #define LM3697_CTRL_B_BRT_LSB       0x22
0031 #define LM3697_CTRL_B_BRT_MSB       0x23
0032 #define LM3697_CTRL_ENABLE      0x24
0033 
0034 #define LM3697_SW_RESET     BIT(0)
0035 
0036 #define LM3697_CTRL_A_EN    BIT(0)
0037 #define LM3697_CTRL_B_EN    BIT(1)
0038 #define LM3697_CTRL_A_B_EN  (LM3697_CTRL_A_EN | LM3697_CTRL_B_EN)
0039 
0040 #define LM3697_MAX_LED_STRINGS  3
0041 
0042 #define LM3697_CONTROL_A    0
0043 #define LM3697_CONTROL_B    1
0044 #define LM3697_MAX_CONTROL_BANKS 2
0045 
0046 /**
0047  * struct lm3697_led -
0048  * @hvled_strings: Array of LED strings associated with a control bank
0049  * @label: LED label
0050  * @led_dev: LED class device
0051  * @priv: Pointer to the device struct
0052  * @lmu_data: Register and setting values for common code
0053  * @control_bank: Control bank the LED is associated to. 0 is control bank A
0054  *         1 is control bank B
0055  * @enabled: LED brightness level (or LED_OFF)
0056  * @num_leds: Number of LEDs available
0057  */
0058 struct lm3697_led {
0059     u32 hvled_strings[LM3697_MAX_LED_STRINGS];
0060     char label[LED_MAX_NAME_SIZE];
0061     struct led_classdev led_dev;
0062     struct lm3697 *priv;
0063     struct ti_lmu_bank lmu_data;
0064     int control_bank;
0065     int enabled;
0066     int num_leds;
0067 };
0068 
0069 /**
0070  * struct lm3697 -
0071  * @enable_gpio: Hardware enable gpio
0072  * @regulator: LED supply regulator pointer
0073  * @client: Pointer to the I2C client
0074  * @regmap: Devices register map
0075  * @dev: Pointer to the devices device struct
0076  * @lock: Lock for reading/writing the device
0077  * @leds: Array of LED strings
0078  * @bank_cfg: OUTPUT_CONFIG register values
0079  * @num_banks: Number of control banks
0080  */
0081 struct lm3697 {
0082     struct gpio_desc *enable_gpio;
0083     struct regulator *regulator;
0084     struct i2c_client *client;
0085     struct regmap *regmap;
0086     struct device *dev;
0087     struct mutex lock;
0088 
0089     int bank_cfg;
0090     int num_banks;
0091 
0092     struct lm3697_led leds[];
0093 };
0094 
0095 static const struct reg_default lm3697_reg_defs[] = {
0096     {LM3697_OUTPUT_CONFIG, 0x6},
0097     {LM3697_CTRL_A_RAMP, 0x0},
0098     {LM3697_CTRL_B_RAMP, 0x0},
0099     {LM3697_CTRL_A_B_RT_RAMP, 0x0},
0100     {LM3697_CTRL_A_B_RAMP_CFG, 0x0},
0101     {LM3697_CTRL_A_B_BRT_CFG, 0x0},
0102     {LM3697_CTRL_A_FS_CURR_CFG, 0x13},
0103     {LM3697_CTRL_B_FS_CURR_CFG, 0x13},
0104     {LM3697_PWM_CFG, 0xc},
0105     {LM3697_CTRL_A_BRT_LSB, 0x0},
0106     {LM3697_CTRL_A_BRT_MSB, 0x0},
0107     {LM3697_CTRL_B_BRT_LSB, 0x0},
0108     {LM3697_CTRL_B_BRT_MSB, 0x0},
0109     {LM3697_CTRL_ENABLE, 0x0},
0110 };
0111 
0112 static const struct regmap_config lm3697_regmap_config = {
0113     .reg_bits = 8,
0114     .val_bits = 8,
0115 
0116     .max_register = LM3697_CTRL_ENABLE,
0117     .reg_defaults = lm3697_reg_defs,
0118     .num_reg_defaults = ARRAY_SIZE(lm3697_reg_defs),
0119     .cache_type = REGCACHE_FLAT,
0120 };
0121 
0122 static int lm3697_brightness_set(struct led_classdev *led_cdev,
0123                 enum led_brightness brt_val)
0124 {
0125     struct lm3697_led *led = container_of(led_cdev, struct lm3697_led,
0126                           led_dev);
0127     int ctrl_en_val = (1 << led->control_bank);
0128     struct device *dev = led->priv->dev;
0129     int ret;
0130 
0131     mutex_lock(&led->priv->lock);
0132 
0133     if (brt_val == LED_OFF) {
0134         ret = regmap_update_bits(led->priv->regmap, LM3697_CTRL_ENABLE,
0135                      ctrl_en_val, ~ctrl_en_val);
0136         if (ret) {
0137             dev_err(dev, "Cannot write ctrl register\n");
0138             goto brightness_out;
0139         }
0140 
0141         led->enabled = LED_OFF;
0142     } else {
0143         ret = ti_lmu_common_set_brightness(&led->lmu_data, brt_val);
0144         if (ret) {
0145             dev_err(dev, "Cannot write brightness\n");
0146             goto brightness_out;
0147         }
0148 
0149         if (!led->enabled) {
0150             ret = regmap_update_bits(led->priv->regmap,
0151                          LM3697_CTRL_ENABLE,
0152                          ctrl_en_val, ctrl_en_val);
0153             if (ret) {
0154                 dev_err(dev, "Cannot enable the device\n");
0155                 goto brightness_out;
0156             }
0157 
0158             led->enabled = brt_val;
0159         }
0160     }
0161 
0162 brightness_out:
0163     mutex_unlock(&led->priv->lock);
0164     return ret;
0165 }
0166 
0167 static int lm3697_init(struct lm3697 *priv)
0168 {
0169     struct device *dev = priv->dev;
0170     struct lm3697_led *led;
0171     int i, ret;
0172 
0173     if (priv->enable_gpio) {
0174         gpiod_direction_output(priv->enable_gpio, 1);
0175     } else {
0176         ret = regmap_write(priv->regmap, LM3697_RESET, LM3697_SW_RESET);
0177         if (ret) {
0178             dev_err(dev, "Cannot reset the device\n");
0179             goto out;
0180         }
0181     }
0182 
0183     ret = regmap_write(priv->regmap, LM3697_CTRL_ENABLE, 0x0);
0184     if (ret) {
0185         dev_err(dev, "Cannot write ctrl enable\n");
0186         goto out;
0187     }
0188 
0189     ret = regmap_write(priv->regmap, LM3697_OUTPUT_CONFIG, priv->bank_cfg);
0190     if (ret)
0191         dev_err(dev, "Cannot write OUTPUT config\n");
0192 
0193     for (i = 0; i < priv->num_banks; i++) {
0194         led = &priv->leds[i];
0195         ret = ti_lmu_common_set_ramp(&led->lmu_data);
0196         if (ret)
0197             dev_err(dev, "Setting the ramp rate failed\n");
0198     }
0199 out:
0200     return ret;
0201 }
0202 
0203 static int lm3697_probe_dt(struct lm3697 *priv)
0204 {
0205     struct fwnode_handle *child = NULL;
0206     struct device *dev = priv->dev;
0207     struct lm3697_led *led;
0208     int ret = -EINVAL;
0209     int control_bank;
0210     size_t i = 0;
0211     int j;
0212 
0213     priv->enable_gpio = devm_gpiod_get_optional(dev, "enable",
0214                             GPIOD_OUT_LOW);
0215     if (IS_ERR(priv->enable_gpio))
0216         return dev_err_probe(dev, PTR_ERR(priv->enable_gpio),
0217                       "Failed to get enable GPIO\n");
0218 
0219     priv->regulator = devm_regulator_get(dev, "vled");
0220     if (IS_ERR(priv->regulator))
0221         priv->regulator = NULL;
0222 
0223     device_for_each_child_node(dev, child) {
0224         struct led_init_data init_data = {};
0225 
0226         ret = fwnode_property_read_u32(child, "reg", &control_bank);
0227         if (ret) {
0228             dev_err(dev, "reg property missing\n");
0229             goto child_out;
0230         }
0231 
0232         if (control_bank > LM3697_CONTROL_B) {
0233             dev_err(dev, "reg property is invalid\n");
0234             ret = -EINVAL;
0235             goto child_out;
0236         }
0237 
0238         led = &priv->leds[i];
0239 
0240         ret = ti_lmu_common_get_brt_res(dev, child, &led->lmu_data);
0241         if (ret)
0242             dev_warn(dev,
0243                  "brightness resolution property missing\n");
0244 
0245         led->control_bank = control_bank;
0246         led->lmu_data.regmap = priv->regmap;
0247         led->lmu_data.runtime_ramp_reg = LM3697_CTRL_A_RAMP +
0248                          control_bank;
0249         led->lmu_data.msb_brightness_reg = LM3697_CTRL_A_BRT_MSB +
0250                            led->control_bank * 2;
0251         led->lmu_data.lsb_brightness_reg = LM3697_CTRL_A_BRT_LSB +
0252                            led->control_bank * 2;
0253 
0254         led->num_leds = fwnode_property_count_u32(child, "led-sources");
0255         if (led->num_leds > LM3697_MAX_LED_STRINGS) {
0256             dev_err(dev, "Too many LED strings defined\n");
0257             continue;
0258         }
0259 
0260         ret = fwnode_property_read_u32_array(child, "led-sources",
0261                             led->hvled_strings,
0262                             led->num_leds);
0263         if (ret) {
0264             dev_err(dev, "led-sources property missing\n");
0265             goto child_out;
0266         }
0267 
0268         for (j = 0; j < led->num_leds; j++)
0269             priv->bank_cfg |=
0270                 (led->control_bank << led->hvled_strings[j]);
0271 
0272         ret = ti_lmu_common_get_ramp_params(dev, child, &led->lmu_data);
0273         if (ret)
0274             dev_warn(dev, "runtime-ramp properties missing\n");
0275 
0276         init_data.fwnode = child;
0277         init_data.devicename = priv->client->name;
0278         /* for backwards compatibility if `label` is not present */
0279         init_data.default_label = ":";
0280 
0281         led->priv = priv;
0282         led->led_dev.max_brightness = led->lmu_data.max_brightness;
0283         led->led_dev.brightness_set_blocking = lm3697_brightness_set;
0284 
0285         ret = devm_led_classdev_register_ext(dev, &led->led_dev,
0286                              &init_data);
0287         if (ret) {
0288             dev_err(dev, "led register err: %d\n", ret);
0289             goto child_out;
0290         }
0291 
0292         i++;
0293     }
0294 
0295     return ret;
0296 
0297 child_out:
0298     fwnode_handle_put(child);
0299     return ret;
0300 }
0301 
0302 static int lm3697_probe(struct i2c_client *client,
0303             const struct i2c_device_id *id)
0304 {
0305     struct device *dev = &client->dev;
0306     struct lm3697 *led;
0307     int count;
0308     int ret;
0309 
0310     count = device_get_child_node_count(dev);
0311     if (!count || count > LM3697_MAX_CONTROL_BANKS) {
0312         dev_err(dev, "Strange device tree!");
0313         return -ENODEV;
0314     }
0315 
0316     led = devm_kzalloc(dev, struct_size(led, leds, count), GFP_KERNEL);
0317     if (!led)
0318         return -ENOMEM;
0319 
0320     mutex_init(&led->lock);
0321     i2c_set_clientdata(client, led);
0322 
0323     led->client = client;
0324     led->dev = dev;
0325     led->num_banks = count;
0326     led->regmap = devm_regmap_init_i2c(client, &lm3697_regmap_config);
0327     if (IS_ERR(led->regmap)) {
0328         ret = PTR_ERR(led->regmap);
0329         dev_err(dev, "Failed to allocate register map: %d\n", ret);
0330         return ret;
0331     }
0332 
0333     ret = lm3697_probe_dt(led);
0334     if (ret)
0335         return ret;
0336 
0337     return lm3697_init(led);
0338 }
0339 
0340 static int lm3697_remove(struct i2c_client *client)
0341 {
0342     struct lm3697 *led = i2c_get_clientdata(client);
0343     struct device *dev = &led->client->dev;
0344     int ret;
0345 
0346     ret = regmap_update_bits(led->regmap, LM3697_CTRL_ENABLE,
0347                  LM3697_CTRL_A_B_EN, 0);
0348     if (ret) {
0349         dev_err(dev, "Failed to disable the device\n");
0350         return ret;
0351     }
0352 
0353     if (led->enable_gpio)
0354         gpiod_direction_output(led->enable_gpio, 0);
0355 
0356     if (led->regulator) {
0357         ret = regulator_disable(led->regulator);
0358         if (ret)
0359             dev_err(dev, "Failed to disable regulator\n");
0360     }
0361 
0362     mutex_destroy(&led->lock);
0363 
0364     return 0;
0365 }
0366 
0367 static const struct i2c_device_id lm3697_id[] = {
0368     { "lm3697", 0 },
0369     { }
0370 };
0371 MODULE_DEVICE_TABLE(i2c, lm3697_id);
0372 
0373 static const struct of_device_id of_lm3697_leds_match[] = {
0374     { .compatible = "ti,lm3697", },
0375     {},
0376 };
0377 MODULE_DEVICE_TABLE(of, of_lm3697_leds_match);
0378 
0379 static struct i2c_driver lm3697_driver = {
0380     .driver = {
0381         .name   = "lm3697",
0382         .of_match_table = of_lm3697_leds_match,
0383     },
0384     .probe      = lm3697_probe,
0385     .remove     = lm3697_remove,
0386     .id_table   = lm3697_id,
0387 };
0388 module_i2c_driver(lm3697_driver);
0389 
0390 MODULE_DESCRIPTION("Texas Instruments LM3697 LED driver");
0391 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
0392 MODULE_LICENSE("GPL v2");