linux/drivers/leds/leds-lm3692x.c
<<
>>
Prefs
   1/*
   2 * TI lm3692x LED Driver
   3 *
   4 * Copyright (C) 2017 Texas Instruments
   5 *
   6 * Author: Dan Murphy <dmurphy@ti.com>
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * version 2 as published by the Free Software Foundation.
  11 *
  12 * Data sheet is located
  13 * http://www.ti.com/lit/ds/snvsa29/snvsa29.pdf
  14 */
  15
  16#include <linux/gpio/consumer.h>
  17#include <linux/i2c.h>
  18#include <linux/init.h>
  19#include <linux/leds.h>
  20#include <linux/module.h>
  21#include <linux/mutex.h>
  22#include <linux/of.h>
  23#include <linux/of_gpio.h>
  24#include <linux/regmap.h>
  25#include <linux/regulator/consumer.h>
  26#include <linux/slab.h>
  27#include <uapi/linux/uleds.h>
  28
  29#define LM3692X_REV             0x0
  30#define LM3692X_RESET           0x1
  31#define LM3692X_EN              0x10
  32#define LM3692X_BRT_CTRL        0x11
  33#define LM3692X_PWM_CTRL        0x12
  34#define LM3692X_BOOST_CTRL      0x13
  35#define LM3692X_AUTO_FREQ_HI    0x15
  36#define LM3692X_AUTO_FREQ_LO    0x16
  37#define LM3692X_BL_ADJ_THRESH   0x17
  38#define LM3692X_BRT_LSB         0x18
  39#define LM3692X_BRT_MSB         0x19
  40#define LM3692X_FAULT_CTRL      0x1e
  41#define LM3692X_FAULT_FLAGS     0x1f
  42
  43#define LM3692X_SW_RESET        BIT(0)
  44#define LM3692X_DEVICE_EN       BIT(0)
  45#define LM3692X_LED1_EN         BIT(1)
  46#define LM3692X_LED2_EN         BIT(2)
  47
  48/* Brightness Control Bits */
  49#define LM3692X_BL_ADJ_POL      BIT(0)
  50#define LM3692X_RAMP_RATE_125us 0x00
  51#define LM3692X_RAMP_RATE_250us BIT(1)
  52#define LM3692X_RAMP_RATE_500us BIT(2)
  53#define LM3692X_RAMP_RATE_1ms   (BIT(1) | BIT(2))
  54#define LM3692X_RAMP_RATE_2ms   BIT(3)
  55#define LM3692X_RAMP_RATE_4ms   (BIT(3) | BIT(1))
  56#define LM3692X_RAMP_RATE_8ms   (BIT(2) | BIT(3))
  57#define LM3692X_RAMP_RATE_16ms  (BIT(1) | BIT(2) | BIT(3))
  58#define LM3692X_RAMP_EN         BIT(4)
  59#define LM3692X_BRHT_MODE_REG   0x00
  60#define LM3692X_BRHT_MODE_PWM   BIT(5)
  61#define LM3692X_BRHT_MODE_MULTI_RAMP BIT(6)
  62#define LM3692X_BRHT_MODE_RAMP_MULTI (BIT(5) | BIT(6))
  63#define LM3692X_MAP_MODE_EXP    BIT(7)
  64
  65/* PWM Register Bits */
  66#define LM3692X_PWM_FILTER_100  BIT(0)
  67#define LM3692X_PWM_FILTER_150  BIT(1)
  68#define LM3692X_PWM_FILTER_200  (BIT(0) | BIT(1))
  69#define LM3692X_PWM_HYSTER_1LSB BIT(2)
  70#define LM3692X_PWM_HYSTER_2LSB BIT(3)
  71#define LM3692X_PWM_HYSTER_3LSB (BIT(3) | BIT(2))
  72#define LM3692X_PWM_HYSTER_4LSB BIT(4)
  73#define LM3692X_PWM_HYSTER_5LSB (BIT(4) | BIT(2))
  74#define LM3692X_PWM_HYSTER_6LSB (BIT(4) | BIT(3))
  75#define LM3692X_PWM_POLARITY    BIT(5)
  76#define LM3692X_PWM_SAMP_4MHZ   BIT(6)
  77#define LM3692X_PWM_SAMP_24MHZ  BIT(7)
  78
  79/* Boost Control Bits */
  80#define LM3692X_OCP_PROT_1A     BIT(0)
  81#define LM3692X_OCP_PROT_1_25A  BIT(1)
  82#define LM3692X_OCP_PROT_1_5A   (BIT(0) | BIT(1))
  83#define LM3692X_OVP_21V         BIT(2)
  84#define LM3692X_OVP_25V         BIT(3)
  85#define LM3692X_OVP_29V         (BIT(2) | BIT(3))
  86#define LM3692X_MIN_IND_22UH    BIT(4)
  87#define LM3692X_BOOST_SW_1MHZ   BIT(5)
  88#define LM3692X_BOOST_SW_NO_SHIFT       BIT(6)
  89
  90/* Fault Control Bits */
  91#define LM3692X_FAULT_CTRL_OVP BIT(0)
  92#define LM3692X_FAULT_CTRL_OCP BIT(1)
  93#define LM3692X_FAULT_CTRL_TSD BIT(2)
  94#define LM3692X_FAULT_CTRL_OPEN BIT(3)
  95
  96/* Fault Flag Bits */
  97#define LM3692X_FAULT_FLAG_OVP BIT(0)
  98#define LM3692X_FAULT_FLAG_OCP BIT(1)
  99#define LM3692X_FAULT_FLAG_TSD BIT(2)
 100#define LM3692X_FAULT_FLAG_SHRT BIT(3)
 101#define LM3692X_FAULT_FLAG_OPEN BIT(4)
 102
 103/**
 104 * struct lm3692x_led -
 105 * @lock - Lock for reading/writing the device
 106 * @client - Pointer to the I2C client
 107 * @led_dev - LED class device pointer
 108 * @regmap - Devices register map
 109 * @enable_gpio - VDDIO/EN gpio to enable communication interface
 110 * @regulator - LED supply regulator pointer
 111 * @label - LED label
 112 */
 113struct lm3692x_led {
 114        struct mutex lock;
 115        struct i2c_client *client;
 116        struct led_classdev led_dev;
 117        struct regmap *regmap;
 118        struct gpio_desc *enable_gpio;
 119        struct regulator *regulator;
 120        char label[LED_MAX_NAME_SIZE];
 121};
 122
 123static const struct reg_default lm3692x_reg_defs[] = {
 124        {LM3692X_EN, 0xf},
 125        {LM3692X_BRT_CTRL, 0x61},
 126        {LM3692X_PWM_CTRL, 0x73},
 127        {LM3692X_BOOST_CTRL, 0x6f},
 128        {LM3692X_AUTO_FREQ_HI, 0x0},
 129        {LM3692X_AUTO_FREQ_LO, 0x0},
 130        {LM3692X_BL_ADJ_THRESH, 0x0},
 131        {LM3692X_BRT_LSB, 0x7},
 132        {LM3692X_BRT_MSB, 0xff},
 133        {LM3692X_FAULT_CTRL, 0x7},
 134};
 135
 136static const struct regmap_config lm3692x_regmap_config = {
 137        .reg_bits = 8,
 138        .val_bits = 8,
 139
 140        .max_register = LM3692X_FAULT_FLAGS,
 141        .reg_defaults = lm3692x_reg_defs,
 142        .num_reg_defaults = ARRAY_SIZE(lm3692x_reg_defs),
 143        .cache_type = REGCACHE_RBTREE,
 144};
 145
 146static int lm3692x_fault_check(struct lm3692x_led *led)
 147{
 148        int ret;
 149        unsigned int read_buf;
 150
 151        ret = regmap_read(led->regmap, LM3692X_FAULT_FLAGS, &read_buf);
 152        if (ret)
 153                return ret;
 154
 155        if (read_buf)
 156                dev_err(&led->client->dev, "Detected a fault 0x%X\n", read_buf);
 157
 158        /* The first read may clear the fault.  Check again to see if the fault
 159         * still exits and return that value.
 160         */
 161        regmap_read(led->regmap, LM3692X_FAULT_FLAGS, &read_buf);
 162        if (read_buf)
 163                dev_err(&led->client->dev, "Second read of fault flags 0x%X\n",
 164                        read_buf);
 165
 166        return read_buf;
 167}
 168
 169static int lm3692x_brightness_set(struct led_classdev *led_cdev,
 170                                enum led_brightness brt_val)
 171{
 172        struct lm3692x_led *led =
 173                        container_of(led_cdev, struct lm3692x_led, led_dev);
 174        int ret;
 175        int led_brightness_lsb = (brt_val >> 5);
 176
 177        mutex_lock(&led->lock);
 178
 179        ret = lm3692x_fault_check(led);
 180        if (ret) {
 181                dev_err(&led->client->dev, "Cannot read/clear faults\n");
 182                goto out;
 183        }
 184
 185        ret = regmap_write(led->regmap, LM3692X_BRT_MSB, brt_val);
 186        if (ret) {
 187                dev_err(&led->client->dev, "Cannot write MSB\n");
 188                goto out;
 189        }
 190
 191        ret = regmap_write(led->regmap, LM3692X_BRT_LSB, led_brightness_lsb);
 192        if (ret) {
 193                dev_err(&led->client->dev, "Cannot write LSB\n");
 194                goto out;
 195        }
 196out:
 197        mutex_unlock(&led->lock);
 198        return ret;
 199}
 200
 201static int lm3692x_init(struct lm3692x_led *led)
 202{
 203        int ret;
 204
 205        if (led->regulator) {
 206                ret = regulator_enable(led->regulator);
 207                if (ret) {
 208                        dev_err(&led->client->dev,
 209                                "Failed to enable regulator\n");
 210                        return ret;
 211                }
 212        }
 213
 214        if (led->enable_gpio)
 215                gpiod_direction_output(led->enable_gpio, 1);
 216
 217        ret = lm3692x_fault_check(led);
 218        if (ret) {
 219                dev_err(&led->client->dev, "Cannot read/clear faults\n");
 220                goto out;
 221        }
 222
 223        ret = regmap_write(led->regmap, LM3692X_BRT_CTRL, 0x00);
 224        if (ret)
 225                goto out;
 226
 227        /*
 228         * For glitch free operation, the following data should
 229         * only be written while device enable bit is 0
 230         * per Section 7.5.14 of the data sheet
 231         */
 232        ret = regmap_write(led->regmap, LM3692X_PWM_CTRL,
 233                LM3692X_PWM_FILTER_100 | LM3692X_PWM_SAMP_24MHZ);
 234        if (ret)
 235                goto out;
 236
 237        ret = regmap_write(led->regmap, LM3692X_BOOST_CTRL,
 238                        LM3692X_BRHT_MODE_RAMP_MULTI |
 239                        LM3692X_BL_ADJ_POL |
 240                        LM3692X_RAMP_RATE_250us);
 241        if (ret)
 242                goto out;
 243
 244        ret = regmap_write(led->regmap, LM3692X_AUTO_FREQ_HI, 0x00);
 245        if (ret)
 246                goto out;
 247
 248        ret = regmap_write(led->regmap, LM3692X_AUTO_FREQ_LO, 0x00);
 249        if (ret)
 250                goto out;
 251
 252        ret = regmap_write(led->regmap, LM3692X_BL_ADJ_THRESH, 0x00);
 253        if (ret)
 254                goto out;
 255
 256        ret = regmap_write(led->regmap, LM3692X_BRT_CTRL,
 257                        LM3692X_BL_ADJ_POL | LM3692X_PWM_HYSTER_4LSB);
 258        if (ret)
 259                goto out;
 260
 261        return ret;
 262out:
 263        dev_err(&led->client->dev, "Fail writing initialization values\n");
 264
 265        if (led->enable_gpio)
 266                gpiod_direction_output(led->enable_gpio, 0);
 267
 268        if (led->regulator) {
 269                ret = regulator_disable(led->regulator);
 270                if (ret)
 271                        dev_err(&led->client->dev,
 272                                "Failed to disable regulator\n");
 273        }
 274
 275        return ret;
 276}
 277
 278static int lm3692x_probe(struct i2c_client *client,
 279                        const struct i2c_device_id *id)
 280{
 281        int ret;
 282        struct lm3692x_led *led;
 283        struct device_node *np = client->dev.of_node;
 284        struct device_node *child_node;
 285        const char *name;
 286
 287        led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
 288        if (!led)
 289                return -ENOMEM;
 290
 291        for_each_available_child_of_node(np, child_node) {
 292                led->led_dev.default_trigger = of_get_property(child_node,
 293                                                    "linux,default-trigger",
 294                                                    NULL);
 295
 296                ret = of_property_read_string(child_node, "label", &name);
 297                if (!ret)
 298                        snprintf(led->label, sizeof(led->label),
 299                                 "%s:%s", id->name, name);
 300                else
 301                        snprintf(led->label, sizeof(led->label),
 302                                 "%s::backlight_cluster", id->name);
 303        };
 304
 305        led->enable_gpio = devm_gpiod_get_optional(&client->dev,
 306                                                   "enable", GPIOD_OUT_LOW);
 307        if (IS_ERR(led->enable_gpio)) {
 308                ret = PTR_ERR(led->enable_gpio);
 309                dev_err(&client->dev, "Failed to get enable gpio: %d\n", ret);
 310                return ret;
 311        }
 312
 313        led->regulator = devm_regulator_get(&client->dev, "vled");
 314        if (IS_ERR(led->regulator))
 315                led->regulator = NULL;
 316
 317        led->client = client;
 318        led->led_dev.name = led->label;
 319        led->led_dev.brightness_set_blocking = lm3692x_brightness_set;
 320
 321        mutex_init(&led->lock);
 322
 323        i2c_set_clientdata(client, led);
 324
 325        led->regmap = devm_regmap_init_i2c(client, &lm3692x_regmap_config);
 326        if (IS_ERR(led->regmap)) {
 327                ret = PTR_ERR(led->regmap);
 328                dev_err(&client->dev, "Failed to allocate register map: %d\n",
 329                        ret);
 330                return ret;
 331        }
 332
 333        ret = lm3692x_init(led);
 334        if (ret)
 335                return ret;
 336
 337        ret = devm_led_classdev_register(&client->dev, &led->led_dev);
 338        if (ret) {
 339                dev_err(&client->dev, "led register err: %d\n", ret);
 340                return ret;
 341        }
 342
 343        return 0;
 344}
 345
 346static int lm3692x_remove(struct i2c_client *client)
 347{
 348        struct lm3692x_led *led = i2c_get_clientdata(client);
 349        int ret;
 350
 351        if (led->enable_gpio)
 352                gpiod_direction_output(led->enable_gpio, 0);
 353
 354        if (led->regulator) {
 355                ret = regulator_disable(led->regulator);
 356                if (ret)
 357                        dev_err(&led->client->dev,
 358                                "Failed to disable regulator\n");
 359        }
 360
 361        mutex_destroy(&led->lock);
 362
 363        return 0;
 364}
 365
 366static const struct i2c_device_id lm3692x_id[] = {
 367        { "lm36922", 0 },
 368        { "lm36923", 1 },
 369        { }
 370};
 371MODULE_DEVICE_TABLE(i2c, lm3692x_id);
 372
 373static const struct of_device_id of_lm3692x_leds_match[] = {
 374        { .compatible = "ti,lm36922", },
 375        { .compatible = "ti,lm36923", },
 376        {},
 377};
 378MODULE_DEVICE_TABLE(of, of_lm3692x_leds_match);
 379
 380static struct i2c_driver lm3692x_driver = {
 381        .driver = {
 382                .name   = "lm3692x",
 383                .of_match_table = of_lm3692x_leds_match,
 384        },
 385        .probe          = lm3692x_probe,
 386        .remove         = lm3692x_remove,
 387        .id_table       = lm3692x_id,
 388};
 389module_i2c_driver(lm3692x_driver);
 390
 391MODULE_DESCRIPTION("Texas Instruments LM3692X LED driver");
 392MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
 393MODULE_LICENSE("GPL v2");
 394