linux/drivers/leds/leds-lp5523.c
<<
>>
Prefs
   1/*
   2 * lp5523.c - LP5523 LED Driver
   3 *
   4 * Copyright (C) 2010 Nokia Corporation
   5 * Copyright (C) 2012 Texas Instruments
   6 *
   7 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
   8 *          Milo(Woogyom) Kim <milo.kim@ti.com>
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License
  12 * version 2 as published by the Free Software Foundation.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  22 * 02110-1301 USA
  23 */
  24
  25#include <linux/delay.h>
  26#include <linux/firmware.h>
  27#include <linux/i2c.h>
  28#include <linux/init.h>
  29#include <linux/leds.h>
  30#include <linux/module.h>
  31#include <linux/mutex.h>
  32#include <linux/platform_data/leds-lp55xx.h>
  33#include <linux/slab.h>
  34
  35#include "leds-lp55xx-common.h"
  36
  37#define LP5523_PROGRAM_LENGTH           32
  38#define LP5523_MAX_LEDS                 9
  39
  40/* Registers */
  41#define LP5523_REG_ENABLE               0x00
  42#define LP5523_REG_OP_MODE              0x01
  43#define LP5523_REG_ENABLE_LEDS_MSB      0x04
  44#define LP5523_REG_ENABLE_LEDS_LSB      0x05
  45#define LP5523_REG_LED_PWM_BASE         0x16
  46#define LP5523_REG_LED_CURRENT_BASE     0x26
  47#define LP5523_REG_CONFIG               0x36
  48#define LP5523_REG_STATUS               0x3A
  49#define LP5523_REG_RESET                0x3D
  50#define LP5523_REG_LED_TEST_CTRL        0x41
  51#define LP5523_REG_LED_TEST_ADC         0x42
  52#define LP5523_REG_CH1_PROG_START       0x4C
  53#define LP5523_REG_CH2_PROG_START       0x4D
  54#define LP5523_REG_CH3_PROG_START       0x4E
  55#define LP5523_REG_PROG_PAGE_SEL        0x4F
  56#define LP5523_REG_PROG_MEM             0x50
  57
  58/* Bit description in registers */
  59#define LP5523_ENABLE                   0x40
  60#define LP5523_AUTO_INC                 0x40
  61#define LP5523_PWR_SAVE                 0x20
  62#define LP5523_PWM_PWR_SAVE             0x04
  63#define LP5523_CP_AUTO                  0x18
  64#define LP5523_AUTO_CLK                 0x02
  65
  66#define LP5523_EN_LEDTEST               0x80
  67#define LP5523_LEDTEST_DONE             0x80
  68#define LP5523_RESET                    0xFF
  69#define LP5523_ADC_SHORTCIRC_LIM        80
  70#define LP5523_EXT_CLK_USED             0x08
  71#define LP5523_ENG_STATUS_MASK          0x07
  72
  73/* Memory Page Selection */
  74#define LP5523_PAGE_ENG1                0
  75#define LP5523_PAGE_ENG2                1
  76#define LP5523_PAGE_ENG3                2
  77#define LP5523_PAGE_MUX1                3
  78#define LP5523_PAGE_MUX2                4
  79#define LP5523_PAGE_MUX3                5
  80
  81/* Program Memory Operations */
  82#define LP5523_MODE_ENG1_M              0x30    /* Operation Mode Register */
  83#define LP5523_MODE_ENG2_M              0x0C
  84#define LP5523_MODE_ENG3_M              0x03
  85#define LP5523_LOAD_ENG1                0x10
  86#define LP5523_LOAD_ENG2                0x04
  87#define LP5523_LOAD_ENG3                0x01
  88
  89#define LP5523_ENG1_IS_LOADING(mode)    \
  90        ((mode & LP5523_MODE_ENG1_M) == LP5523_LOAD_ENG1)
  91#define LP5523_ENG2_IS_LOADING(mode)    \
  92        ((mode & LP5523_MODE_ENG2_M) == LP5523_LOAD_ENG2)
  93#define LP5523_ENG3_IS_LOADING(mode)    \
  94        ((mode & LP5523_MODE_ENG3_M) == LP5523_LOAD_ENG3)
  95
  96#define LP5523_EXEC_ENG1_M              0x30    /* Enable Register */
  97#define LP5523_EXEC_ENG2_M              0x0C
  98#define LP5523_EXEC_ENG3_M              0x03
  99#define LP5523_EXEC_M                   0x3F
 100#define LP5523_RUN_ENG1                 0x20
 101#define LP5523_RUN_ENG2                 0x08
 102#define LP5523_RUN_ENG3                 0x02
 103
 104#define LED_ACTIVE(mux, led)            (!!(mux & (0x0001 << led)))
 105
 106enum lp5523_chip_id {
 107        LP5523,
 108        LP55231,
 109};
 110
 111static int lp5523_init_program_engine(struct lp55xx_chip *chip);
 112
 113static inline void lp5523_wait_opmode_done(void)
 114{
 115        usleep_range(1000, 2000);
 116}
 117
 118static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current)
 119{
 120        led->led_current = led_current;
 121        lp55xx_write(led->chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
 122                led_current);
 123}
 124
 125static int lp5523_post_init_device(struct lp55xx_chip *chip)
 126{
 127        int ret;
 128
 129        ret = lp55xx_write(chip, LP5523_REG_ENABLE, LP5523_ENABLE);
 130        if (ret)
 131                return ret;
 132
 133        /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
 134        usleep_range(1000, 2000);
 135
 136        ret = lp55xx_write(chip, LP5523_REG_CONFIG,
 137                            LP5523_AUTO_INC | LP5523_PWR_SAVE |
 138                            LP5523_CP_AUTO | LP5523_AUTO_CLK |
 139                            LP5523_PWM_PWR_SAVE);
 140        if (ret)
 141                return ret;
 142
 143        /* turn on all leds */
 144        ret = lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_MSB, 0x01);
 145        if (ret)
 146                return ret;
 147
 148        ret = lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_LSB, 0xff);
 149        if (ret)
 150                return ret;
 151
 152        return lp5523_init_program_engine(chip);
 153}
 154
 155static void lp5523_load_engine(struct lp55xx_chip *chip)
 156{
 157        enum lp55xx_engine_index idx = chip->engine_idx;
 158        u8 mask[] = {
 159                [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
 160                [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
 161                [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
 162        };
 163
 164        u8 val[] = {
 165                [LP55XX_ENGINE_1] = LP5523_LOAD_ENG1,
 166                [LP55XX_ENGINE_2] = LP5523_LOAD_ENG2,
 167                [LP55XX_ENGINE_3] = LP5523_LOAD_ENG3,
 168        };
 169
 170        lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], val[idx]);
 171
 172        lp5523_wait_opmode_done();
 173}
 174
 175static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip)
 176{
 177        enum lp55xx_engine_index idx = chip->engine_idx;
 178        u8 page_sel[] = {
 179                [LP55XX_ENGINE_1] = LP5523_PAGE_ENG1,
 180                [LP55XX_ENGINE_2] = LP5523_PAGE_ENG2,
 181                [LP55XX_ENGINE_3] = LP5523_PAGE_ENG3,
 182        };
 183
 184        lp5523_load_engine(chip);
 185
 186        lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]);
 187}
 188
 189static void lp5523_stop_engine(struct lp55xx_chip *chip)
 190{
 191        lp55xx_write(chip, LP5523_REG_OP_MODE, 0);
 192        lp5523_wait_opmode_done();
 193}
 194
 195static void lp5523_turn_off_channels(struct lp55xx_chip *chip)
 196{
 197        int i;
 198
 199        for (i = 0; i < LP5523_MAX_LEDS; i++)
 200                lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0);
 201}
 202
 203static void lp5523_run_engine(struct lp55xx_chip *chip, bool start)
 204{
 205        int ret;
 206        u8 mode;
 207        u8 exec;
 208
 209        /* stop engine */
 210        if (!start) {
 211                lp5523_stop_engine(chip);
 212                lp5523_turn_off_channels(chip);
 213                return;
 214        }
 215
 216        /*
 217         * To run the engine,
 218         * operation mode and enable register should updated at the same time
 219         */
 220
 221        ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode);
 222        if (ret)
 223                return;
 224
 225        ret = lp55xx_read(chip, LP5523_REG_ENABLE, &exec);
 226        if (ret)
 227                return;
 228
 229        /* change operation mode to RUN only when each engine is loading */
 230        if (LP5523_ENG1_IS_LOADING(mode)) {
 231                mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1;
 232                exec = (exec & ~LP5523_EXEC_ENG1_M) | LP5523_RUN_ENG1;
 233        }
 234
 235        if (LP5523_ENG2_IS_LOADING(mode)) {
 236                mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2;
 237                exec = (exec & ~LP5523_EXEC_ENG2_M) | LP5523_RUN_ENG2;
 238        }
 239
 240        if (LP5523_ENG3_IS_LOADING(mode)) {
 241                mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3;
 242                exec = (exec & ~LP5523_EXEC_ENG3_M) | LP5523_RUN_ENG3;
 243        }
 244
 245        lp55xx_write(chip, LP5523_REG_OP_MODE, mode);
 246        lp5523_wait_opmode_done();
 247
 248        lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec);
 249}
 250
 251static int lp5523_init_program_engine(struct lp55xx_chip *chip)
 252{
 253        int i;
 254        int j;
 255        int ret;
 256        u8 status;
 257        /* one pattern per engine setting LED MUX start and stop addresses */
 258        static const u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
 259                { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
 260                { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
 261                { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
 262        };
 263
 264        /* hardcode 32 bytes of memory for each engine from program memory */
 265        ret = lp55xx_write(chip, LP5523_REG_CH1_PROG_START, 0x00);
 266        if (ret)
 267                return ret;
 268
 269        ret = lp55xx_write(chip, LP5523_REG_CH2_PROG_START, 0x10);
 270        if (ret)
 271                return ret;
 272
 273        ret = lp55xx_write(chip, LP5523_REG_CH3_PROG_START, 0x20);
 274        if (ret)
 275                return ret;
 276
 277        /* write LED MUX address space for each engine */
 278        for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
 279                chip->engine_idx = i;
 280                lp5523_load_engine_and_select_page(chip);
 281
 282                for (j = 0; j < LP5523_PROGRAM_LENGTH; j++) {
 283                        ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + j,
 284                                        pattern[i - 1][j]);
 285                        if (ret)
 286                                goto out;
 287                }
 288        }
 289
 290        lp5523_run_engine(chip, true);
 291
 292        /* Let the programs run for couple of ms and check the engine status */
 293        usleep_range(3000, 6000);
 294        lp55xx_read(chip, LP5523_REG_STATUS, &status);
 295        status &= LP5523_ENG_STATUS_MASK;
 296
 297        if (status != LP5523_ENG_STATUS_MASK) {
 298                dev_err(&chip->cl->dev,
 299                        "cound not configure LED engine, status = 0x%.2x\n",
 300                        status);
 301                ret = -1;
 302        }
 303
 304out:
 305        lp5523_stop_engine(chip);
 306        return ret;
 307}
 308
 309static int lp5523_update_program_memory(struct lp55xx_chip *chip,
 310                                        const u8 *data, size_t size)
 311{
 312        u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
 313        unsigned cmd;
 314        char c[3];
 315        int nrchars;
 316        int ret;
 317        int offset = 0;
 318        int i = 0;
 319
 320        while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) {
 321                /* separate sscanfs because length is working only for %s */
 322                ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
 323                if (ret != 1)
 324                        goto err;
 325
 326                ret = sscanf(c, "%2x", &cmd);
 327                if (ret != 1)
 328                        goto err;
 329
 330                pattern[i] = (u8)cmd;
 331                offset += nrchars;
 332                i++;
 333        }
 334
 335        /* Each instruction is 16bit long. Check that length is even */
 336        if (i % 2)
 337                goto err;
 338
 339        mutex_lock(&chip->lock);
 340
 341        for (i = 0; i < LP5523_PROGRAM_LENGTH; i++) {
 342                ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
 343                if (ret) {
 344                        mutex_unlock(&chip->lock);
 345                        return -EINVAL;
 346                }
 347        }
 348
 349        mutex_unlock(&chip->lock);
 350
 351        return size;
 352
 353err:
 354        dev_err(&chip->cl->dev, "wrong pattern format\n");
 355        return -EINVAL;
 356}
 357
 358static void lp5523_firmware_loaded(struct lp55xx_chip *chip)
 359{
 360        const struct firmware *fw = chip->fw;
 361
 362        if (fw->size > LP5523_PROGRAM_LENGTH) {
 363                dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
 364                        fw->size);
 365                return;
 366        }
 367
 368        /*
 369         * Program momery sequence
 370         *  1) set engine mode to "LOAD"
 371         *  2) write firmware data into program memory
 372         */
 373
 374        lp5523_load_engine_and_select_page(chip);
 375        lp5523_update_program_memory(chip, fw->data, fw->size);
 376}
 377
 378static ssize_t show_engine_mode(struct device *dev,
 379                                struct device_attribute *attr,
 380                                char *buf, int nr)
 381{
 382        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 383        struct lp55xx_chip *chip = led->chip;
 384        enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode;
 385
 386        switch (mode) {
 387        case LP55XX_ENGINE_RUN:
 388                return sprintf(buf, "run\n");
 389        case LP55XX_ENGINE_LOAD:
 390                return sprintf(buf, "load\n");
 391        case LP55XX_ENGINE_DISABLED:
 392        default:
 393                return sprintf(buf, "disabled\n");
 394        }
 395}
 396show_mode(1)
 397show_mode(2)
 398show_mode(3)
 399
 400static ssize_t store_engine_mode(struct device *dev,
 401                                 struct device_attribute *attr,
 402                                 const char *buf, size_t len, int nr)
 403{
 404        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 405        struct lp55xx_chip *chip = led->chip;
 406        struct lp55xx_engine *engine = &chip->engines[nr - 1];
 407
 408        mutex_lock(&chip->lock);
 409
 410        chip->engine_idx = nr;
 411
 412        if (!strncmp(buf, "run", 3)) {
 413                lp5523_run_engine(chip, true);
 414                engine->mode = LP55XX_ENGINE_RUN;
 415        } else if (!strncmp(buf, "load", 4)) {
 416                lp5523_stop_engine(chip);
 417                lp5523_load_engine(chip);
 418                engine->mode = LP55XX_ENGINE_LOAD;
 419        } else if (!strncmp(buf, "disabled", 8)) {
 420                lp5523_stop_engine(chip);
 421                engine->mode = LP55XX_ENGINE_DISABLED;
 422        }
 423
 424        mutex_unlock(&chip->lock);
 425
 426        return len;
 427}
 428store_mode(1)
 429store_mode(2)
 430store_mode(3)
 431
 432static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
 433{
 434        u16 tmp_mux = 0;
 435        int i;
 436
 437        len = min_t(int, len, LP5523_MAX_LEDS);
 438
 439        for (i = 0; i < len; i++) {
 440                switch (buf[i]) {
 441                case '1':
 442                        tmp_mux |= (1 << i);
 443                        break;
 444                case '0':
 445                        break;
 446                case '\n':
 447                        i = len;
 448                        break;
 449                default:
 450                        return -1;
 451                }
 452        }
 453        *mux = tmp_mux;
 454
 455        return 0;
 456}
 457
 458static void lp5523_mux_to_array(u16 led_mux, char *array)
 459{
 460        int i, pos = 0;
 461        for (i = 0; i < LP5523_MAX_LEDS; i++)
 462                pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i));
 463
 464        array[pos] = '\0';
 465}
 466
 467static ssize_t show_engine_leds(struct device *dev,
 468                            struct device_attribute *attr,
 469                            char *buf, int nr)
 470{
 471        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 472        struct lp55xx_chip *chip = led->chip;
 473        char mux[LP5523_MAX_LEDS + 1];
 474
 475        lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux);
 476
 477        return sprintf(buf, "%s\n", mux);
 478}
 479show_leds(1)
 480show_leds(2)
 481show_leds(3)
 482
 483static int lp5523_load_mux(struct lp55xx_chip *chip, u16 mux, int nr)
 484{
 485        struct lp55xx_engine *engine = &chip->engines[nr - 1];
 486        int ret;
 487        u8 mux_page[] = {
 488                [LP55XX_ENGINE_1] = LP5523_PAGE_MUX1,
 489                [LP55XX_ENGINE_2] = LP5523_PAGE_MUX2,
 490                [LP55XX_ENGINE_3] = LP5523_PAGE_MUX3,
 491        };
 492
 493        lp5523_load_engine(chip);
 494
 495        ret = lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, mux_page[nr]);
 496        if (ret)
 497                return ret;
 498
 499        ret = lp55xx_write(chip, LP5523_REG_PROG_MEM , (u8)(mux >> 8));
 500        if (ret)
 501                return ret;
 502
 503        ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + 1, (u8)(mux));
 504        if (ret)
 505                return ret;
 506
 507        engine->led_mux = mux;
 508        return 0;
 509}
 510
 511static ssize_t store_engine_leds(struct device *dev,
 512                             struct device_attribute *attr,
 513                             const char *buf, size_t len, int nr)
 514{
 515        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 516        struct lp55xx_chip *chip = led->chip;
 517        struct lp55xx_engine *engine = &chip->engines[nr - 1];
 518        u16 mux = 0;
 519        ssize_t ret;
 520
 521        if (lp5523_mux_parse(buf, &mux, len))
 522                return -EINVAL;
 523
 524        mutex_lock(&chip->lock);
 525
 526        chip->engine_idx = nr;
 527        ret = -EINVAL;
 528
 529        if (engine->mode != LP55XX_ENGINE_LOAD)
 530                goto leave;
 531
 532        if (lp5523_load_mux(chip, mux, nr))
 533                goto leave;
 534
 535        ret = len;
 536leave:
 537        mutex_unlock(&chip->lock);
 538        return ret;
 539}
 540store_leds(1)
 541store_leds(2)
 542store_leds(3)
 543
 544static ssize_t store_engine_load(struct device *dev,
 545                             struct device_attribute *attr,
 546                             const char *buf, size_t len, int nr)
 547{
 548        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 549        struct lp55xx_chip *chip = led->chip;
 550
 551        mutex_lock(&chip->lock);
 552
 553        chip->engine_idx = nr;
 554        lp5523_load_engine_and_select_page(chip);
 555
 556        mutex_unlock(&chip->lock);
 557
 558        return lp5523_update_program_memory(chip, buf, len);
 559}
 560store_load(1)
 561store_load(2)
 562store_load(3)
 563
 564static ssize_t lp5523_selftest(struct device *dev,
 565                               struct device_attribute *attr,
 566                               char *buf)
 567{
 568        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 569        struct lp55xx_chip *chip = led->chip;
 570        struct lp55xx_platform_data *pdata = chip->pdata;
 571        int i, ret, pos = 0;
 572        u8 status, adc, vdd;
 573
 574        mutex_lock(&chip->lock);
 575
 576        ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
 577        if (ret < 0)
 578                goto fail;
 579
 580        /* Check that ext clock is really in use if requested */
 581        if (pdata->clock_mode == LP55XX_CLOCK_EXT) {
 582                if  ((status & LP5523_EXT_CLK_USED) == 0)
 583                        goto fail;
 584        }
 585
 586        /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
 587        lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL, LP5523_EN_LEDTEST | 16);
 588        usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
 589        ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
 590        if (ret < 0)
 591                goto fail;
 592
 593        if (!(status & LP5523_LEDTEST_DONE))
 594                usleep_range(3000, 6000); /* Was not ready. Wait little bit */
 595
 596        ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &vdd);
 597        if (ret < 0)
 598                goto fail;
 599
 600        vdd--;  /* There may be some fluctuation in measurement */
 601
 602        for (i = 0; i < LP5523_MAX_LEDS; i++) {
 603                /* Skip non-existing channels */
 604                if (pdata->led_config[i].led_current == 0)
 605                        continue;
 606
 607                /* Set default current */
 608                lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
 609                        pdata->led_config[i].led_current);
 610
 611                lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0xff);
 612                /* let current stabilize 2 - 4ms before measurements start */
 613                usleep_range(2000, 4000);
 614                lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL,
 615                             LP5523_EN_LEDTEST | i);
 616                /* ADC conversion time is 2.7 ms typically */
 617                usleep_range(3000, 6000);
 618                ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
 619                if (ret < 0)
 620                        goto fail;
 621
 622                if (!(status & LP5523_LEDTEST_DONE))
 623                        usleep_range(3000, 6000);/* Was not ready. Wait. */
 624
 625                ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc);
 626                if (ret < 0)
 627                        goto fail;
 628
 629                if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
 630                        pos += sprintf(buf + pos, "LED %d FAIL\n", i);
 631
 632                lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0x00);
 633
 634                /* Restore current */
 635                lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
 636                        led->led_current);
 637                led++;
 638        }
 639        if (pos == 0)
 640                pos = sprintf(buf, "OK\n");
 641        goto release_lock;
 642fail:
 643        pos = sprintf(buf, "FAIL\n");
 644
 645release_lock:
 646        mutex_unlock(&chip->lock);
 647
 648        return pos;
 649}
 650
 651static void lp5523_led_brightness_work(struct work_struct *work)
 652{
 653        struct lp55xx_led *led = container_of(work, struct lp55xx_led,
 654                                              brightness_work);
 655        struct lp55xx_chip *chip = led->chip;
 656
 657        mutex_lock(&chip->lock);
 658        lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
 659                     led->brightness);
 660        mutex_unlock(&chip->lock);
 661}
 662
 663static LP55XX_DEV_ATTR_RW(engine1_mode, show_engine1_mode, store_engine1_mode);
 664static LP55XX_DEV_ATTR_RW(engine2_mode, show_engine2_mode, store_engine2_mode);
 665static LP55XX_DEV_ATTR_RW(engine3_mode, show_engine3_mode, store_engine3_mode);
 666static LP55XX_DEV_ATTR_RW(engine1_leds, show_engine1_leds, store_engine1_leds);
 667static LP55XX_DEV_ATTR_RW(engine2_leds, show_engine2_leds, store_engine2_leds);
 668static LP55XX_DEV_ATTR_RW(engine3_leds, show_engine3_leds, store_engine3_leds);
 669static LP55XX_DEV_ATTR_WO(engine1_load, store_engine1_load);
 670static LP55XX_DEV_ATTR_WO(engine2_load, store_engine2_load);
 671static LP55XX_DEV_ATTR_WO(engine3_load, store_engine3_load);
 672static LP55XX_DEV_ATTR_RO(selftest, lp5523_selftest);
 673
 674static struct attribute *lp5523_attributes[] = {
 675        &dev_attr_engine1_mode.attr,
 676        &dev_attr_engine2_mode.attr,
 677        &dev_attr_engine3_mode.attr,
 678        &dev_attr_engine1_load.attr,
 679        &dev_attr_engine2_load.attr,
 680        &dev_attr_engine3_load.attr,
 681        &dev_attr_engine1_leds.attr,
 682        &dev_attr_engine2_leds.attr,
 683        &dev_attr_engine3_leds.attr,
 684        &dev_attr_selftest.attr,
 685        NULL,
 686};
 687
 688static const struct attribute_group lp5523_group = {
 689        .attrs = lp5523_attributes,
 690};
 691
 692/* Chip specific configurations */
 693static struct lp55xx_device_config lp5523_cfg = {
 694        .reset = {
 695                .addr = LP5523_REG_RESET,
 696                .val  = LP5523_RESET,
 697        },
 698        .enable = {
 699                .addr = LP5523_REG_ENABLE,
 700                .val  = LP5523_ENABLE,
 701        },
 702        .max_channel  = LP5523_MAX_LEDS,
 703        .post_init_device   = lp5523_post_init_device,
 704        .brightness_work_fn = lp5523_led_brightness_work,
 705        .set_led_current    = lp5523_set_led_current,
 706        .firmware_cb        = lp5523_firmware_loaded,
 707        .run_engine         = lp5523_run_engine,
 708        .dev_attr_group     = &lp5523_group,
 709};
 710
 711static int lp5523_probe(struct i2c_client *client,
 712                        const struct i2c_device_id *id)
 713{
 714        int ret;
 715        struct lp55xx_chip *chip;
 716        struct lp55xx_led *led;
 717        struct lp55xx_platform_data *pdata;
 718        struct device_node *np = client->dev.of_node;
 719
 720        if (!dev_get_platdata(&client->dev)) {
 721                if (np) {
 722                        ret = lp55xx_of_populate_pdata(&client->dev, np);
 723                        if (ret < 0)
 724                                return ret;
 725                } else {
 726                        dev_err(&client->dev, "no platform data\n");
 727                        return -EINVAL;
 728                }
 729        }
 730        pdata = dev_get_platdata(&client->dev);
 731
 732        chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 733        if (!chip)
 734                return -ENOMEM;
 735
 736        led = devm_kzalloc(&client->dev,
 737                        sizeof(*led) * pdata->num_channels, GFP_KERNEL);
 738        if (!led)
 739                return -ENOMEM;
 740
 741        chip->cl = client;
 742        chip->pdata = pdata;
 743        chip->cfg = &lp5523_cfg;
 744
 745        mutex_init(&chip->lock);
 746
 747        i2c_set_clientdata(client, led);
 748
 749        ret = lp55xx_init_device(chip);
 750        if (ret)
 751                goto err_init;
 752
 753        dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
 754
 755        ret = lp55xx_register_leds(led, chip);
 756        if (ret)
 757                goto err_register_leds;
 758
 759        ret = lp55xx_register_sysfs(chip);
 760        if (ret) {
 761                dev_err(&client->dev, "registering sysfs failed\n");
 762                goto err_register_sysfs;
 763        }
 764
 765        return 0;
 766
 767err_register_sysfs:
 768        lp55xx_unregister_leds(led, chip);
 769err_register_leds:
 770        lp55xx_deinit_device(chip);
 771err_init:
 772        return ret;
 773}
 774
 775static int lp5523_remove(struct i2c_client *client)
 776{
 777        struct lp55xx_led *led = i2c_get_clientdata(client);
 778        struct lp55xx_chip *chip = led->chip;
 779
 780        lp5523_stop_engine(chip);
 781        lp55xx_unregister_sysfs(chip);
 782        lp55xx_unregister_leds(led, chip);
 783        lp55xx_deinit_device(chip);
 784
 785        return 0;
 786}
 787
 788static const struct i2c_device_id lp5523_id[] = {
 789        { "lp5523",  LP5523 },
 790        { "lp55231", LP55231 },
 791        { }
 792};
 793
 794MODULE_DEVICE_TABLE(i2c, lp5523_id);
 795
 796#ifdef CONFIG_OF
 797static const struct of_device_id of_lp5523_leds_match[] = {
 798        { .compatible = "national,lp5523", },
 799        {},
 800};
 801
 802MODULE_DEVICE_TABLE(of, of_lp5523_leds_match);
 803#endif
 804
 805static struct i2c_driver lp5523_driver = {
 806        .driver = {
 807                .name   = "lp5523x",
 808                .of_match_table = of_match_ptr(of_lp5523_leds_match),
 809        },
 810        .probe          = lp5523_probe,
 811        .remove         = lp5523_remove,
 812        .id_table       = lp5523_id,
 813};
 814
 815module_i2c_driver(lp5523_driver);
 816
 817MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
 818MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
 819MODULE_DESCRIPTION("LP5523 LED engine");
 820MODULE_LICENSE("GPL");
 821
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.