linux/drivers/leds/leds-lm3692x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// TI LM3692x LED chip family driver
   3// Copyright (C) 2017-18 Texas Instruments Incorporated - http://www.ti.com/
   4
   5#include <linux/gpio/consumer.h>
   6#include <linux/i2c.h>
   7#include <linux/init.h>
   8#include <linux/leds.h>
   9#include <linux/module.h>
  10#include <linux/mutex.h>
  11#include <linux/of.h>
  12#include <linux/of_gpio.h>
  13#include <linux/regmap.h>
  14#include <linux/regulator/consumer.h>
  15#include <linux/slab.h>
  16#include <uapi/linux/uleds.h>
  17
  18#define LM36922_MODEL   0
  19#define LM36923_MODEL   1
  20
  21#define LM3692X_REV             0x0
  22#define LM3692X_RESET           0x1
  23#define LM3692X_EN              0x10
  24#define LM3692X_BRT_CTRL        0x11
  25#define LM3692X_PWM_CTRL        0x12
  26#define LM3692X_BOOST_CTRL      0x13
  27#define LM3692X_AUTO_FREQ_HI    0x15
  28#define LM3692X_AUTO_FREQ_LO    0x16
  29#define LM3692X_BL_ADJ_THRESH   0x17
  30#define LM3692X_BRT_LSB         0x18
  31#define LM3692X_BRT_MSB         0x19
  32#define LM3692X_FAULT_CTRL      0x1e
  33#define LM3692X_FAULT_FLAGS     0x1f
  34
  35#define LM3692X_SW_RESET        BIT(0)
  36#define LM3692X_DEVICE_EN       BIT(0)
  37#define LM3692X_LED1_EN         BIT(1)
  38#define LM3692X_LED2_EN         BIT(2)
  39#define LM36923_LED3_EN         BIT(3)
  40#define LM3692X_ENABLE_MASK     (LM3692X_DEVICE_EN | LM3692X_LED1_EN | \
  41                                 LM3692X_LED2_EN | LM36923_LED3_EN)
  42
  43/* Brightness Control Bits */
  44#define LM3692X_BL_ADJ_POL      BIT(0)
  45#define LM3692X_RAMP_RATE_125us 0x00
  46#define LM3692X_RAMP_RATE_250us BIT(1)
  47#define LM3692X_RAMP_RATE_500us BIT(2)
  48#define LM3692X_RAMP_RATE_1ms   (BIT(1) | BIT(2))
  49#define LM3692X_RAMP_RATE_2ms   BIT(3)
  50#define LM3692X_RAMP_RATE_4ms   (BIT(3) | BIT(1))
  51#define LM3692X_RAMP_RATE_8ms   (BIT(2) | BIT(3))
  52#define LM3692X_RAMP_RATE_16ms  (BIT(1) | BIT(2) | BIT(3))
  53#define LM3692X_RAMP_EN         BIT(4)
  54#define LM3692X_BRHT_MODE_REG   0x00
  55#define LM3692X_BRHT_MODE_PWM   BIT(5)
  56#define LM3692X_BRHT_MODE_MULTI_RAMP BIT(6)
  57#define LM3692X_BRHT_MODE_RAMP_MULTI (BIT(5) | BIT(6))
  58#define LM3692X_MAP_MODE_EXP    BIT(7)
  59
  60/* PWM Register Bits */
  61#define LM3692X_PWM_FILTER_100  BIT(0)
  62#define LM3692X_PWM_FILTER_150  BIT(1)
  63#define LM3692X_PWM_FILTER_200  (BIT(0) | BIT(1))
  64#define LM3692X_PWM_HYSTER_1LSB BIT(2)
  65#define LM3692X_PWM_HYSTER_2LSB BIT(3)
  66#define LM3692X_PWM_HYSTER_3LSB (BIT(3) | BIT(2))
  67#define LM3692X_PWM_HYSTER_4LSB BIT(4)
  68#define LM3692X_PWM_HYSTER_5LSB (BIT(4) | BIT(2))
  69#define LM3692X_PWM_HYSTER_6LSB (BIT(4) | BIT(3))
  70#define LM3692X_PWM_POLARITY    BIT(5)
  71#define LM3692X_PWM_SAMP_4MHZ   BIT(6)
  72#define LM3692X_PWM_SAMP_24MHZ  BIT(7)
  73
  74/* Boost Control Bits */
  75#define LM3692X_OCP_PROT_1A     BIT(0)
  76#define LM3692X_OCP_PROT_1_25A  BIT(1)
  77#define LM3692X_OCP_PROT_1_5A   (BIT(0) | BIT(1))
  78#define LM3692X_OVP_21V         BIT(2)
  79#define LM3692X_OVP_25V         BIT(3)
  80#define LM3692X_OVP_29V         (BIT(2) | BIT(3))
  81#define LM3692X_MIN_IND_22UH    BIT(4)
  82#define LM3692X_BOOST_SW_1MHZ   BIT(5)
  83#define LM3692X_BOOST_SW_NO_SHIFT       BIT(6)
  84
  85/* Fault Control Bits */
  86#define LM3692X_FAULT_CTRL_OVP BIT(0)
  87#define LM3692X_FAULT_CTRL_OCP BIT(1)
  88#define LM3692X_FAULT_CTRL_TSD BIT(2)
  89#define LM3692X_FAULT_CTRL_OPEN BIT(3)
  90
  91/* Fault Flag Bits */
  92#define LM3692X_FAULT_FLAG_OVP BIT(0)
  93#define LM3692X_FAULT_FLAG_OCP BIT(1)
  94#define LM3692X_FAULT_FLAG_TSD BIT(2)
  95#define LM3692X_FAULT_FLAG_SHRT BIT(3)
  96#define LM3692X_FAULT_FLAG_OPEN BIT(4)
  97
  98/**
  99 * struct lm3692x_led -
 100 * @lock - Lock for reading/writing the device
 101 * @client - Pointer to the I2C client
 102 * @led_dev - LED class device pointer
 103 * @regmap - Devices register map
 104 * @enable_gpio - VDDIO/EN gpio to enable communication interface
 105 * @regulator - LED supply regulator pointer
 106 * @label - LED label
 107 * @led_enable - LED sync to be enabled
 108 * @model_id - Current device model ID enumerated
 109 */
 110struct lm3692x_led {
 111        struct mutex lock;
 112        struct i2c_client *client;
 113        struct led_classdev led_dev;
 114        struct regmap *regmap;
 115        struct gpio_desc *enable_gpio;
 116        struct regulator *regulator;
 117        char label[LED_MAX_NAME_SIZE];
 118        int led_enable;
 119        int model_id;
 120};
 121
 122static const struct reg_default lm3692x_reg_defs[] = {
 123        {LM3692X_EN, 0xf},
 124        {LM3692X_BRT_CTRL, 0x61},
 125        {LM3692X_PWM_CTRL, 0x73},
 126        {LM3692X_BOOST_CTRL, 0x6f},
 127        {LM3692X_AUTO_FREQ_HI, 0x0},
 128        {LM3692X_AUTO_FREQ_LO, 0x0},
 129        {LM3692X_BL_ADJ_THRESH, 0x0},
 130        {LM3692X_BRT_LSB, 0x7},
 131        {LM3692X_BRT_MSB, 0xff},
 132        {LM3692X_FAULT_CTRL, 0x7},
 133};
 134
 135static const struct regmap_config lm3692x_regmap_config = {
 136        .reg_bits = 8,
 137        .val_bits = 8,
 138
 139        .max_register = LM3692X_FAULT_FLAGS,
 140        .reg_defaults = lm3692x_reg_defs,
 141        .num_reg_defaults = ARRAY_SIZE(lm3692x_reg_defs),
 142        .cache_type = REGCACHE_RBTREE,
 143};
 144
 145static int lm3692x_fault_check(struct lm3692x_led *led)
 146{
 147        int ret;
 148        unsigned int read_buf;
 149
 150        ret = regmap_read(led->regmap, LM3692X_FAULT_FLAGS, &read_buf);
 151        if (ret)
 152                return ret;
 153
 154        if (read_buf)
 155                dev_err(&led->client->dev, "Detected a fault 0x%X\n", read_buf);
 156
 157        /* The first read may clear the fault.  Check again to see if the fault
 158         * still exits and return that value.
 159         */
 160        regmap_read(led->regmap, LM3692X_FAULT_FLAGS, &read_buf);
 161        if (read_buf)
 162                dev_err(&led->client->dev, "Second read of fault flags 0x%X\n",
 163                        read_buf);
 164
 165        return read_buf;
 166}
 167
 168static int lm3692x_brightness_set(struct led_classdev *led_cdev,
 169                                enum led_brightness brt_val)
 170{
 171        struct lm3692x_led *led =
 172                        container_of(led_cdev, struct lm3692x_led, led_dev);
 173        int ret;
 174        int led_brightness_lsb = (brt_val >> 5);
 175
 176        mutex_lock(&led->lock);
 177
 178        ret = lm3692x_fault_check(led);
 179        if (ret) {
 180                dev_err(&led->client->dev, "Cannot read/clear faults\n");
 181                goto out;
 182        }
 183
 184        ret = regmap_write(led->regmap, LM3692X_BRT_MSB, brt_val);
 185        if (ret) {
 186                dev_err(&led->client->dev, "Cannot write MSB\n");
 187                goto out;
 188        }
 189
 190        ret = regmap_write(led->regmap, LM3692X_BRT_LSB, led_brightness_lsb);
 191        if (ret) {
 192                dev_err(&led->client->dev, "Cannot write LSB\n");
 193                goto out;
 194        }
 195out:
 196        mutex_unlock(&led->lock);
 197        return ret;
 198}
 199
 200static int lm3692x_init(struct lm3692x_led *led)
 201{
 202        int enable_state;
 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 LEDx enable bits are 0 and the device enable
 230         * bit is set to 1.
 231         * per Section 7.5.14 of the data sheet
 232         */
 233        ret = regmap_write(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN);
 234        if (ret)
 235                goto out;
 236
 237        /* Set the brightness to 0 so when enabled the LEDs do not come
 238         * on with full brightness.
 239         */
 240        ret = regmap_write(led->regmap, LM3692X_BRT_MSB, 0);
 241        if (ret)
 242                goto out;
 243
 244        ret = regmap_write(led->regmap, LM3692X_BRT_LSB, 0);
 245        if (ret)
 246                goto out;
 247
 248        ret = regmap_write(led->regmap, LM3692X_PWM_CTRL,
 249                LM3692X_PWM_FILTER_100 | LM3692X_PWM_SAMP_24MHZ);
 250        if (ret)
 251                goto out;
 252
 253        ret = regmap_write(led->regmap, LM3692X_BOOST_CTRL,
 254                        LM3692X_BRHT_MODE_RAMP_MULTI |
 255                        LM3692X_BL_ADJ_POL |
 256                        LM3692X_RAMP_RATE_250us);
 257        if (ret)
 258                goto out;
 259
 260        ret = regmap_write(led->regmap, LM3692X_AUTO_FREQ_HI, 0x00);
 261        if (ret)
 262                goto out;
 263
 264        ret = regmap_write(led->regmap, LM3692X_AUTO_FREQ_LO, 0x00);
 265        if (ret)
 266                goto out;
 267
 268        ret = regmap_write(led->regmap, LM3692X_BL_ADJ_THRESH, 0x00);
 269        if (ret)
 270                goto out;
 271
 272        ret = regmap_write(led->regmap, LM3692X_BRT_CTRL,
 273                        LM3692X_BL_ADJ_POL | LM3692X_PWM_HYSTER_4LSB);
 274        if (ret)
 275                goto out;
 276
 277        switch (led->led_enable) {
 278        case 0:
 279        default:
 280                if (led->model_id == LM36923_MODEL)
 281                        enable_state = LM3692X_LED1_EN | LM3692X_LED2_EN |
 282                               LM36923_LED3_EN;
 283                else
 284                        enable_state = LM3692X_LED1_EN | LM3692X_LED2_EN;
 285
 286                break;
 287        case 1:
 288                enable_state = LM3692X_LED1_EN;
 289                break;
 290        case 2:
 291                enable_state = LM3692X_LED2_EN;
 292                break;
 293
 294        case 3:
 295                if (led->model_id == LM36923_MODEL) {
 296                        enable_state = LM36923_LED3_EN;
 297                        break;
 298                }
 299
 300                ret = -EINVAL;
 301                dev_err(&led->client->dev,
 302                        "LED3 sync not available on this device\n");
 303                goto out;
 304        }
 305
 306        ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_ENABLE_MASK,
 307                                 enable_state | LM3692X_DEVICE_EN);
 308
 309        return ret;
 310out:
 311        dev_err(&led->client->dev, "Fail writing initialization values\n");
 312
 313        if (led->enable_gpio)
 314                gpiod_direction_output(led->enable_gpio, 0);
 315
 316        if (led->regulator) {
 317                ret = regulator_disable(led->regulator);
 318                if (ret)
 319                        dev_err(&led->client->dev,
 320                                "Failed to disable regulator\n");
 321        }
 322
 323        return ret;
 324}
 325static int lm3692x_probe_dt(struct lm3692x_led *led)
 326{
 327        struct fwnode_handle *child = NULL;
 328        const char *name;
 329        int ret;
 330
 331        led->enable_gpio = devm_gpiod_get_optional(&led->client->dev,
 332                                                   "enable", GPIOD_OUT_LOW);
 333        if (IS_ERR(led->enable_gpio)) {
 334                ret = PTR_ERR(led->enable_gpio);
 335                dev_err(&led->client->dev, "Failed to get enable gpio: %d\n",
 336                        ret);
 337                return ret;
 338        }
 339
 340        led->regulator = devm_regulator_get(&led->client->dev, "vled");
 341        if (IS_ERR(led->regulator))
 342                led->regulator = NULL;
 343
 344        child = device_get_next_child_node(&led->client->dev, child);
 345        if (!child) {
 346                dev_err(&led->client->dev, "No LED Child node\n");
 347                return -ENODEV;
 348        }
 349
 350        fwnode_property_read_string(child, "linux,default-trigger",
 351                                    &led->led_dev.default_trigger);
 352
 353        ret = fwnode_property_read_string(child, "label", &name);
 354        if (ret)
 355                snprintf(led->label, sizeof(led->label),
 356                        "%s::", led->client->name);
 357        else
 358                snprintf(led->label, sizeof(led->label),
 359                         "%s:%s", led->client->name, name);
 360
 361        ret = fwnode_property_read_u32(child, "reg", &led->led_enable);
 362        if (ret) {
 363                dev_err(&led->client->dev, "reg DT property missing\n");
 364                return ret;
 365        }
 366
 367        led->led_dev.name = led->label;
 368
 369        ret = devm_led_classdev_register(&led->client->dev, &led->led_dev);
 370        if (ret) {
 371                dev_err(&led->client->dev, "led register err: %d\n", ret);
 372                return ret;
 373        }
 374
 375        led->led_dev.dev->of_node = to_of_node(child);
 376
 377        return 0;
 378}
 379
 380static int lm3692x_probe(struct i2c_client *client,
 381                        const struct i2c_device_id *id)
 382{
 383        struct lm3692x_led *led;
 384        int ret;
 385
 386        led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
 387        if (!led)
 388                return -ENOMEM;
 389
 390        mutex_init(&led->lock);
 391        led->client = client;
 392        led->led_dev.brightness_set_blocking = lm3692x_brightness_set;
 393        led->model_id = id->driver_data;
 394        i2c_set_clientdata(client, led);
 395
 396        led->regmap = devm_regmap_init_i2c(client, &lm3692x_regmap_config);
 397        if (IS_ERR(led->regmap)) {
 398                ret = PTR_ERR(led->regmap);
 399                dev_err(&client->dev, "Failed to allocate register map: %d\n",
 400                        ret);
 401                return ret;
 402        }
 403
 404        ret = lm3692x_probe_dt(led);
 405        if (ret)
 406                return ret;
 407
 408        ret = lm3692x_init(led);
 409        if (ret)
 410                return ret;
 411
 412        return 0;
 413}
 414
 415static int lm3692x_remove(struct i2c_client *client)
 416{
 417        struct lm3692x_led *led = i2c_get_clientdata(client);
 418        int ret;
 419
 420        ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0);
 421        if (ret) {
 422                dev_err(&led->client->dev, "Failed to disable regulator\n");
 423                return ret;
 424        }
 425
 426        if (led->enable_gpio)
 427                gpiod_direction_output(led->enable_gpio, 0);
 428
 429        if (led->regulator) {
 430                ret = regulator_disable(led->regulator);
 431                if (ret)
 432                        dev_err(&led->client->dev,
 433                                "Failed to disable regulator\n");
 434        }
 435
 436        mutex_destroy(&led->lock);
 437
 438        return 0;
 439}
 440
 441static const struct i2c_device_id lm3692x_id[] = {
 442        { "lm36922", LM36922_MODEL },
 443        { "lm36923", LM36923_MODEL },
 444        { }
 445};
 446MODULE_DEVICE_TABLE(i2c, lm3692x_id);
 447
 448static const struct of_device_id of_lm3692x_leds_match[] = {
 449        { .compatible = "ti,lm36922", },
 450        { .compatible = "ti,lm36923", },
 451        {},
 452};
 453MODULE_DEVICE_TABLE(of, of_lm3692x_leds_match);
 454
 455static struct i2c_driver lm3692x_driver = {
 456        .driver = {
 457                .name   = "lm3692x",
 458                .of_match_table = of_lm3692x_leds_match,
 459        },
 460        .probe          = lm3692x_probe,
 461        .remove         = lm3692x_remove,
 462        .id_table       = lm3692x_id,
 463};
 464module_i2c_driver(lm3692x_driver);
 465
 466MODULE_DESCRIPTION("Texas Instruments LM3692X LED driver");
 467MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
 468MODULE_LICENSE("GPL v2");
 469