linux/drivers/leds/leds-lp5523.c
<<
>>
Prefs
   1/*
   2 * lp5523.c - LP5523 LED Driver
   3 *
   4 * Copyright (C) 2010 Nokia Corporation
   5 *
   6 * Contact: Samu Onkalo <samu.p.onkalo@nokia.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 * This program is distributed in the hope that it will be useful, but
  13 * WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 * 02110-1301 USA
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/init.h>
  25#include <linux/i2c.h>
  26#include <linux/mutex.h>
  27#include <linux/gpio.h>
  28#include <linux/interrupt.h>
  29#include <linux/delay.h>
  30#include <linux/ctype.h>
  31#include <linux/spinlock.h>
  32#include <linux/wait.h>
  33#include <linux/leds.h>
  34#include <linux/leds-lp5523.h>
  35#include <linux/workqueue.h>
  36#include <linux/slab.h>
  37
  38#define LP5523_REG_ENABLE               0x00
  39#define LP5523_REG_OP_MODE              0x01
  40#define LP5523_REG_RATIOMETRIC_MSB      0x02
  41#define LP5523_REG_RATIOMETRIC_LSB      0x03
  42#define LP5523_REG_ENABLE_LEDS_MSB      0x04
  43#define LP5523_REG_ENABLE_LEDS_LSB      0x05
  44#define LP5523_REG_LED_CNTRL_BASE       0x06
  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_CHANNEL1_PC          0x37
  49#define LP5523_REG_CHANNEL2_PC          0x38
  50#define LP5523_REG_CHANNEL3_PC          0x39
  51#define LP5523_REG_STATUS               0x3a
  52#define LP5523_REG_GPO                  0x3b
  53#define LP5523_REG_VARIABLE             0x3c
  54#define LP5523_REG_RESET                0x3d
  55#define LP5523_REG_TEMP_CTRL            0x3e
  56#define LP5523_REG_TEMP_READ            0x3f
  57#define LP5523_REG_TEMP_WRITE           0x40
  58#define LP5523_REG_LED_TEST_CTRL        0x41
  59#define LP5523_REG_LED_TEST_ADC         0x42
  60#define LP5523_REG_ENG1_VARIABLE        0x45
  61#define LP5523_REG_ENG2_VARIABLE        0x46
  62#define LP5523_REG_ENG3_VARIABLE        0x47
  63#define LP5523_REG_MASTER_FADER1        0x48
  64#define LP5523_REG_MASTER_FADER2        0x49
  65#define LP5523_REG_MASTER_FADER3        0x4a
  66#define LP5523_REG_CH1_PROG_START       0x4c
  67#define LP5523_REG_CH2_PROG_START       0x4d
  68#define LP5523_REG_CH3_PROG_START       0x4e
  69#define LP5523_REG_PROG_PAGE_SEL        0x4f
  70#define LP5523_REG_PROG_MEM             0x50
  71
  72#define LP5523_CMD_LOAD                 0x15 /* 00010101 */
  73#define LP5523_CMD_RUN                  0x2a /* 00101010 */
  74#define LP5523_CMD_DISABLED             0x00 /* 00000000 */
  75
  76#define LP5523_ENABLE                   0x40
  77#define LP5523_AUTO_INC                 0x40
  78#define LP5523_PWR_SAVE                 0x20
  79#define LP5523_PWM_PWR_SAVE             0x04
  80#define LP5523_CP_1                     0x08
  81#define LP5523_CP_1_5                   0x10
  82#define LP5523_CP_AUTO                  0x18
  83#define LP5523_INT_CLK                  0x01
  84#define LP5523_AUTO_CLK                 0x02
  85#define LP5523_EN_LEDTEST               0x80
  86#define LP5523_LEDTEST_DONE             0x80
  87
  88#define LP5523_DEFAULT_CURRENT          50 /* microAmps */
  89#define LP5523_PROGRAM_LENGTH           32 /* in bytes */
  90#define LP5523_PROGRAM_PAGES            6
  91#define LP5523_ADC_SHORTCIRC_LIM        80
  92
  93#define LP5523_LEDS                     9
  94#define LP5523_ENGINES                  3
  95
  96#define LP5523_ENG_MASK_BASE            0x30 /* 00110000 */
  97
  98#define LP5523_ENG_STATUS_MASK          0x07 /* 00000111 */
  99
 100#define LP5523_IRQ_FLAGS                IRQF_TRIGGER_FALLING
 101
 102#define LP5523_EXT_CLK_USED             0x08
 103
 104#define LED_ACTIVE(mux, led)            (!!(mux & (0x0001 << led)))
 105#define SHIFT_MASK(id)                  (((id) - 1) * 2)
 106
 107struct lp5523_engine {
 108        int             id;
 109        u8              mode;
 110        u8              prog_page;
 111        u8              mux_page;
 112        u16             led_mux;
 113        u8              engine_mask;
 114};
 115
 116struct lp5523_led {
 117        int                     id;
 118        u8                      chan_nr;
 119        u8                      led_current;
 120        u8                      max_current;
 121        struct led_classdev     cdev;
 122        struct work_struct      brightness_work;
 123        u8                      brightness;
 124};
 125
 126struct lp5523_chip {
 127        struct mutex            lock; /* Serialize control */
 128        struct i2c_client       *client;
 129        struct lp5523_engine    engines[LP5523_ENGINES];
 130        struct lp5523_led       leds[LP5523_LEDS];
 131        struct lp5523_platform_data *pdata;
 132        u8                      num_channels;
 133        u8                      num_leds;
 134};
 135
 136static inline struct lp5523_led *cdev_to_led(struct led_classdev *cdev)
 137{
 138        return container_of(cdev, struct lp5523_led, cdev);
 139}
 140
 141static inline struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
 142{
 143        return container_of(engine, struct lp5523_chip,
 144                            engines[engine->id - 1]);
 145}
 146
 147static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
 148{
 149        return container_of(led, struct lp5523_chip,
 150                            leds[led->id]);
 151}
 152
 153static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
 154static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
 155static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern);
 156
 157static void lp5523_led_brightness_work(struct work_struct *work);
 158
 159static int lp5523_write(struct i2c_client *client, u8 reg, u8 value)
 160{
 161        return i2c_smbus_write_byte_data(client, reg, value);
 162}
 163
 164static int lp5523_read(struct i2c_client *client, u8 reg, u8 *buf)
 165{
 166        s32 ret = i2c_smbus_read_byte_data(client, reg);
 167
 168        if (ret < 0)
 169                return -EIO;
 170
 171        *buf = ret;
 172        return 0;
 173}
 174
 175static int lp5523_detect(struct i2c_client *client)
 176{
 177        int ret;
 178        u8 buf;
 179
 180        ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40);
 181        if (ret)
 182                return ret;
 183        ret = lp5523_read(client, LP5523_REG_ENABLE, &buf);
 184        if (ret)
 185                return ret;
 186        if (buf == 0x40)
 187                return 0;
 188        else
 189                return -ENODEV;
 190}
 191
 192static int lp5523_configure(struct i2c_client *client)
 193{
 194        struct lp5523_chip *chip = i2c_get_clientdata(client);
 195        int ret = 0;
 196        u8 status;
 197
 198        /* one pattern per engine setting led mux start and stop addresses */
 199        static const u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
 200                { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
 201                { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
 202                { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
 203        };
 204
 205        ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
 206        /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
 207        usleep_range(1000, 2000);
 208
 209        ret |= lp5523_write(client, LP5523_REG_CONFIG,
 210                            LP5523_AUTO_INC | LP5523_PWR_SAVE |
 211                            LP5523_CP_AUTO | LP5523_AUTO_CLK |
 212                            LP5523_PWM_PWR_SAVE);
 213
 214        /* turn on all leds */
 215        ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_MSB, 0x01);
 216        ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_LSB, 0xff);
 217
 218        /* hardcode 32 bytes of memory for each engine from program memory */
 219        ret |= lp5523_write(client, LP5523_REG_CH1_PROG_START, 0x00);
 220        ret |= lp5523_write(client, LP5523_REG_CH2_PROG_START, 0x10);
 221        ret |= lp5523_write(client, LP5523_REG_CH3_PROG_START, 0x20);
 222
 223        /* write led mux address space for each channel */
 224        ret |= lp5523_load_program(&chip->engines[0], pattern[0]);
 225        ret |= lp5523_load_program(&chip->engines[1], pattern[1]);
 226        ret |= lp5523_load_program(&chip->engines[2], pattern[2]);
 227
 228        if (ret) {
 229                dev_err(&client->dev, "could not load mux programs\n");
 230                return -1;
 231        }
 232
 233        /* set all engines exec state and mode to run 00101010 */
 234        ret |= lp5523_write(client, LP5523_REG_ENABLE,
 235                            (LP5523_CMD_RUN | LP5523_ENABLE));
 236
 237        ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_RUN);
 238
 239        if (ret) {
 240                dev_err(&client->dev, "could not start mux programs\n");
 241                return -1;
 242        }
 243
 244        /* Let the programs run for couple of ms and check the engine status */
 245        usleep_range(3000, 6000);
 246        lp5523_read(client, LP5523_REG_STATUS, &status);
 247        status &= LP5523_ENG_STATUS_MASK;
 248
 249        if (status == LP5523_ENG_STATUS_MASK) {
 250                dev_dbg(&client->dev, "all engines configured\n");
 251        } else {
 252                dev_info(&client->dev, "status == %x\n", status);
 253                dev_err(&client->dev, "cound not configure LED engine\n");
 254                return -1;
 255        }
 256
 257        dev_info(&client->dev, "disabling engines\n");
 258
 259        ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED);
 260
 261        return ret;
 262}
 263
 264static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode)
 265{
 266        struct lp5523_chip *chip = engine_to_lp5523(engine);
 267        struct i2c_client *client = chip->client;
 268        int ret;
 269        u8 engine_state;
 270
 271        ret = lp5523_read(client, LP5523_REG_OP_MODE, &engine_state);
 272        if (ret)
 273                goto fail;
 274
 275        engine_state &= ~(engine->engine_mask);
 276
 277        /* set mode only for this engine */
 278        mode &= engine->engine_mask;
 279
 280        engine_state |= mode;
 281
 282        ret |= lp5523_write(client, LP5523_REG_OP_MODE, engine_state);
 283fail:
 284        return ret;
 285}
 286
 287static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux)
 288{
 289        struct lp5523_chip *chip = engine_to_lp5523(engine);
 290        struct i2c_client *client = chip->client;
 291        int ret = 0;
 292
 293        ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
 294
 295        ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, engine->mux_page);
 296        ret |= lp5523_write(client, LP5523_REG_PROG_MEM,
 297                            (u8)(mux >> 8));
 298        ret |= lp5523_write(client, LP5523_REG_PROG_MEM + 1, (u8)(mux));
 299        engine->led_mux = mux;
 300
 301        return ret;
 302}
 303
 304static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern)
 305{
 306        struct lp5523_chip *chip = engine_to_lp5523(engine);
 307        struct i2c_client *client = chip->client;
 308
 309        int ret = 0;
 310
 311        ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
 312
 313        ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL,
 314                            engine->prog_page);
 315        ret |= i2c_smbus_write_i2c_block_data(client, LP5523_REG_PROG_MEM,
 316                                              LP5523_PROGRAM_LENGTH, pattern);
 317
 318        return ret;
 319}
 320
 321static int lp5523_run_program(struct lp5523_engine *engine)
 322{
 323        struct lp5523_chip *chip = engine_to_lp5523(engine);
 324        struct i2c_client *client = chip->client;
 325        int ret;
 326
 327        ret = lp5523_write(client, LP5523_REG_ENABLE,
 328                                        LP5523_CMD_RUN | LP5523_ENABLE);
 329        if (ret)
 330                goto fail;
 331
 332        ret = lp5523_set_engine_mode(engine, LP5523_CMD_RUN);
 333fail:
 334        return ret;
 335}
 336
 337static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
 338{
 339        int i;
 340        u16 tmp_mux = 0;
 341        len = len < LP5523_LEDS ? len : LP5523_LEDS;
 342        for (i = 0; i < len; i++) {
 343                switch (buf[i]) {
 344                case '1':
 345                        tmp_mux |= (1 << i);
 346                        break;
 347                case '0':
 348                        break;
 349                case '\n':
 350                        i = len;
 351                        break;
 352                default:
 353                        return -1;
 354                }
 355        }
 356        *mux = tmp_mux;
 357
 358        return 0;
 359}
 360
 361static void lp5523_mux_to_array(u16 led_mux, char *array)
 362{
 363        int i, pos = 0;
 364        for (i = 0; i < LP5523_LEDS; i++)
 365                pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i));
 366
 367        array[pos] = '\0';
 368}
 369
 370/*--------------------------------------------------------------*/
 371/*                      Sysfs interface                         */
 372/*--------------------------------------------------------------*/
 373
 374static ssize_t show_engine_leds(struct device *dev,
 375                            struct device_attribute *attr,
 376                            char *buf, int nr)
 377{
 378        struct i2c_client *client = to_i2c_client(dev);
 379        struct lp5523_chip *chip = i2c_get_clientdata(client);
 380        char mux[LP5523_LEDS + 1];
 381
 382        lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux);
 383
 384        return sprintf(buf, "%s\n", mux);
 385}
 386
 387#define show_leds(nr)                                                   \
 388static ssize_t show_engine##nr##_leds(struct device *dev,               \
 389                            struct device_attribute *attr,              \
 390                            char *buf)                                  \
 391{                                                                       \
 392        return show_engine_leds(dev, attr, buf, nr);                    \
 393}
 394show_leds(1)
 395show_leds(2)
 396show_leds(3)
 397
 398static ssize_t store_engine_leds(struct device *dev,
 399                             struct device_attribute *attr,
 400                             const char *buf, size_t len, int nr)
 401{
 402        struct i2c_client *client = to_i2c_client(dev);
 403        struct lp5523_chip *chip = i2c_get_clientdata(client);
 404        u16 mux = 0;
 405        ssize_t ret;
 406
 407        if (lp5523_mux_parse(buf, &mux, len))
 408                return -EINVAL;
 409
 410        mutex_lock(&chip->lock);
 411        ret = -EINVAL;
 412        if (chip->engines[nr - 1].mode != LP5523_CMD_LOAD)
 413                goto leave;
 414
 415        if (lp5523_load_mux(&chip->engines[nr - 1], mux))
 416                goto leave;
 417
 418        ret = len;
 419leave:
 420        mutex_unlock(&chip->lock);
 421        return ret;
 422}
 423
 424#define store_leds(nr)                                          \
 425static ssize_t store_engine##nr##_leds(struct device *dev,      \
 426                             struct device_attribute *attr,     \
 427                             const char *buf, size_t len)       \
 428{                                                               \
 429        return store_engine_leds(dev, attr, buf, len, nr);      \
 430}
 431store_leds(1)
 432store_leds(2)
 433store_leds(3)
 434
 435static ssize_t lp5523_selftest(struct device *dev,
 436                               struct device_attribute *attr,
 437                               char *buf)
 438{
 439        struct i2c_client *client = to_i2c_client(dev);
 440        struct lp5523_chip *chip = i2c_get_clientdata(client);
 441        int i, ret, pos = 0;
 442        int led = 0;
 443        u8 status, adc, vdd;
 444
 445        mutex_lock(&chip->lock);
 446
 447        ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
 448        if (ret < 0)
 449                goto fail;
 450
 451        /* Check that ext clock is really in use if requested */
 452        if ((chip->pdata) && (chip->pdata->clock_mode == LP5523_CLOCK_EXT))
 453                if  ((status & LP5523_EXT_CLK_USED) == 0)
 454                        goto fail;
 455
 456        /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
 457        lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL,
 458                                    LP5523_EN_LEDTEST | 16);
 459        usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
 460        ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
 461        if (!(status & LP5523_LEDTEST_DONE))
 462                usleep_range(3000, 6000); /* Was not ready. Wait little bit */
 463
 464        ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd);
 465        vdd--;  /* There may be some fluctuation in measurement */
 466
 467        for (i = 0; i < LP5523_LEDS; i++) {
 468                /* Skip non-existing channels */
 469                if (chip->pdata->led_config[i].led_current == 0)
 470                        continue;
 471
 472                /* Set default current */
 473                lp5523_write(chip->client,
 474                        LP5523_REG_LED_CURRENT_BASE + i,
 475                        chip->pdata->led_config[i].led_current);
 476
 477                lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff);
 478                /* let current stabilize 2 - 4ms before measurements start */
 479                usleep_range(2000, 4000);
 480                lp5523_write(chip->client,
 481                             LP5523_REG_LED_TEST_CTRL,
 482                             LP5523_EN_LEDTEST | i);
 483                /* ADC conversion time is 2.7 ms typically */
 484                usleep_range(3000, 6000);
 485                ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
 486                if (!(status & LP5523_LEDTEST_DONE))
 487                        usleep_range(3000, 6000);/* Was not ready. Wait. */
 488                ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc);
 489
 490                if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
 491                        pos += sprintf(buf + pos, "LED %d FAIL\n", i);
 492
 493                lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0x00);
 494
 495                /* Restore current */
 496                lp5523_write(chip->client,
 497                        LP5523_REG_LED_CURRENT_BASE + i,
 498                        chip->leds[led].led_current);
 499                led++;
 500        }
 501        if (pos == 0)
 502                pos = sprintf(buf, "OK\n");
 503        goto release_lock;
 504fail:
 505        pos = sprintf(buf, "FAIL\n");
 506
 507release_lock:
 508        mutex_unlock(&chip->lock);
 509
 510        return pos;
 511}
 512
 513static void lp5523_set_brightness(struct led_classdev *cdev,
 514                             enum led_brightness brightness)
 515{
 516        struct lp5523_led *led = cdev_to_led(cdev);
 517
 518        led->brightness = (u8)brightness;
 519
 520        schedule_work(&led->brightness_work);
 521}
 522
 523static void lp5523_led_brightness_work(struct work_struct *work)
 524{
 525        struct lp5523_led *led = container_of(work,
 526                                              struct lp5523_led,
 527                                              brightness_work);
 528        struct lp5523_chip *chip = led_to_lp5523(led);
 529        struct i2c_client *client = chip->client;
 530
 531        mutex_lock(&chip->lock);
 532
 533        lp5523_write(client, LP5523_REG_LED_PWM_BASE + led->chan_nr,
 534                     led->brightness);
 535
 536        mutex_unlock(&chip->lock);
 537}
 538
 539static int lp5523_do_store_load(struct lp5523_engine *engine,
 540                                const char *buf, size_t len)
 541{
 542        struct lp5523_chip *chip = engine_to_lp5523(engine);
 543        struct i2c_client *client = chip->client;
 544        int  ret, nrchars, offset = 0, i = 0;
 545        char c[3];
 546        unsigned cmd;
 547        u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
 548
 549        while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) {
 550                /* separate sscanfs because length is working only for %s */
 551                ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
 552                ret = sscanf(c, "%2x", &cmd);
 553                if (ret != 1)
 554                        goto fail;
 555                pattern[i] = (u8)cmd;
 556
 557                offset += nrchars;
 558                i++;
 559        }
 560
 561        /* Each instruction is 16bit long. Check that length is even */
 562        if (i % 2)
 563                goto fail;
 564
 565        mutex_lock(&chip->lock);
 566
 567        if (engine->mode == LP5523_CMD_LOAD)
 568                ret = lp5523_load_program(engine, pattern);
 569        else
 570                ret = -EINVAL;
 571
 572        mutex_unlock(&chip->lock);
 573
 574        if (ret) {
 575                dev_err(&client->dev, "failed loading pattern\n");
 576                return ret;
 577        }
 578
 579        return len;
 580fail:
 581        dev_err(&client->dev, "wrong pattern format\n");
 582        return -EINVAL;
 583}
 584
 585static ssize_t store_engine_load(struct device *dev,
 586                                     struct device_attribute *attr,
 587                                     const char *buf, size_t len, int nr)
 588{
 589        struct i2c_client *client = to_i2c_client(dev);
 590        struct lp5523_chip *chip = i2c_get_clientdata(client);
 591        return lp5523_do_store_load(&chip->engines[nr - 1], buf, len);
 592}
 593
 594#define store_load(nr)                                                  \
 595static ssize_t store_engine##nr##_load(struct device *dev,              \
 596                                     struct device_attribute *attr,     \
 597                                     const char *buf, size_t len)       \
 598{                                                                       \
 599        return store_engine_load(dev, attr, buf, len, nr);              \
 600}
 601store_load(1)
 602store_load(2)
 603store_load(3)
 604
 605static ssize_t show_engine_mode(struct device *dev,
 606                                struct device_attribute *attr,
 607                                char *buf, int nr)
 608{
 609        struct i2c_client *client = to_i2c_client(dev);
 610        struct lp5523_chip *chip = i2c_get_clientdata(client);
 611        switch (chip->engines[nr - 1].mode) {
 612        case LP5523_CMD_RUN:
 613                return sprintf(buf, "run\n");
 614        case LP5523_CMD_LOAD:
 615                return sprintf(buf, "load\n");
 616        case LP5523_CMD_DISABLED:
 617                return sprintf(buf, "disabled\n");
 618        default:
 619                return sprintf(buf, "disabled\n");
 620        }
 621}
 622
 623#define show_mode(nr)                                                   \
 624static ssize_t show_engine##nr##_mode(struct device *dev,               \
 625                                    struct device_attribute *attr,      \
 626                                    char *buf)                          \
 627{                                                                       \
 628        return show_engine_mode(dev, attr, buf, nr);                    \
 629}
 630show_mode(1)
 631show_mode(2)
 632show_mode(3)
 633
 634static ssize_t store_engine_mode(struct device *dev,
 635                                 struct device_attribute *attr,
 636                                 const char *buf, size_t len, int nr)
 637{
 638        struct i2c_client *client = to_i2c_client(dev);
 639        struct lp5523_chip *chip = i2c_get_clientdata(client);
 640        struct lp5523_engine *engine = &chip->engines[nr - 1];
 641        mutex_lock(&chip->lock);
 642
 643        if (!strncmp(buf, "run", 3))
 644                lp5523_set_mode(engine, LP5523_CMD_RUN);
 645        else if (!strncmp(buf, "load", 4))
 646                lp5523_set_mode(engine, LP5523_CMD_LOAD);
 647        else if (!strncmp(buf, "disabled", 8))
 648                lp5523_set_mode(engine, LP5523_CMD_DISABLED);
 649
 650        mutex_unlock(&chip->lock);
 651        return len;
 652}
 653
 654#define store_mode(nr)                                                  \
 655static ssize_t store_engine##nr##_mode(struct device *dev,              \
 656                                     struct device_attribute *attr,     \
 657                                     const char *buf, size_t len)       \
 658{                                                                       \
 659        return store_engine_mode(dev, attr, buf, len, nr);              \
 660}
 661store_mode(1)
 662store_mode(2)
 663store_mode(3)
 664
 665static ssize_t show_max_current(struct device *dev,
 666                            struct device_attribute *attr,
 667                            char *buf)
 668{
 669        struct led_classdev *led_cdev = dev_get_drvdata(dev);
 670        struct lp5523_led *led = cdev_to_led(led_cdev);
 671
 672        return sprintf(buf, "%d\n", led->max_current);
 673}
 674
 675static ssize_t show_current(struct device *dev,
 676                            struct device_attribute *attr,
 677                            char *buf)
 678{
 679        struct led_classdev *led_cdev = dev_get_drvdata(dev);
 680        struct lp5523_led *led = cdev_to_led(led_cdev);
 681
 682        return sprintf(buf, "%d\n", led->led_current);
 683}
 684
 685static ssize_t store_current(struct device *dev,
 686                             struct device_attribute *attr,
 687                             const char *buf, size_t len)
 688{
 689        struct led_classdev *led_cdev = dev_get_drvdata(dev);
 690        struct lp5523_led *led = cdev_to_led(led_cdev);
 691        struct lp5523_chip *chip = led_to_lp5523(led);
 692        ssize_t ret;
 693        unsigned long curr;
 694
 695        if (strict_strtoul(buf, 0, &curr))
 696                return -EINVAL;
 697
 698        if (curr > led->max_current)
 699                return -EINVAL;
 700
 701        mutex_lock(&chip->lock);
 702        ret = lp5523_write(chip->client,
 703                        LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
 704                        (u8)curr);
 705        mutex_unlock(&chip->lock);
 706
 707        if (ret < 0)
 708                return ret;
 709
 710        led->led_current = (u8)curr;
 711
 712        return len;
 713}
 714
 715/* led class device attributes */
 716static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
 717static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
 718
 719static struct attribute *lp5523_led_attributes[] = {
 720        &dev_attr_led_current.attr,
 721        &dev_attr_max_current.attr,
 722        NULL,
 723};
 724
 725static struct attribute_group lp5523_led_attribute_group = {
 726        .attrs = lp5523_led_attributes
 727};
 728
 729/* device attributes */
 730static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR,
 731                   show_engine1_mode, store_engine1_mode);
 732static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR,
 733                   show_engine2_mode, store_engine2_mode);
 734static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR,
 735                   show_engine3_mode, store_engine3_mode);
 736static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUSR,
 737                   show_engine1_leds, store_engine1_leds);
 738static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUSR,
 739                   show_engine2_leds, store_engine2_leds);
 740static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUSR,
 741                   show_engine3_leds, store_engine3_leds);
 742static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
 743static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
 744static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
 745static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL);
 746
 747static struct attribute *lp5523_attributes[] = {
 748        &dev_attr_engine1_mode.attr,
 749        &dev_attr_engine2_mode.attr,
 750        &dev_attr_engine3_mode.attr,
 751        &dev_attr_selftest.attr,
 752        &dev_attr_engine1_load.attr,
 753        &dev_attr_engine1_leds.attr,
 754        &dev_attr_engine2_load.attr,
 755        &dev_attr_engine2_leds.attr,
 756        &dev_attr_engine3_load.attr,
 757        &dev_attr_engine3_leds.attr,
 758};
 759
 760static const struct attribute_group lp5523_group = {
 761        .attrs = lp5523_attributes,
 762};
 763
 764static int lp5523_register_sysfs(struct i2c_client *client)
 765{
 766        struct device *dev = &client->dev;
 767        int ret;
 768
 769        ret = sysfs_create_group(&dev->kobj, &lp5523_group);
 770        if (ret < 0)
 771                return ret;
 772
 773        return 0;
 774}
 775
 776static void lp5523_unregister_sysfs(struct i2c_client *client)
 777{
 778        struct lp5523_chip *chip = i2c_get_clientdata(client);
 779        struct device *dev = &client->dev;
 780        int i;
 781
 782        sysfs_remove_group(&dev->kobj, &lp5523_group);
 783
 784        for (i = 0; i < chip->num_leds; i++)
 785                sysfs_remove_group(&chip->leds[i].cdev.dev->kobj,
 786                                &lp5523_led_attribute_group);
 787}
 788
 789/*--------------------------------------------------------------*/
 790/*                      Set chip operating mode                 */
 791/*--------------------------------------------------------------*/
 792static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
 793{
 794        int ret = 0;
 795
 796        /* if in that mode already do nothing, except for run */
 797        if (mode == engine->mode && mode != LP5523_CMD_RUN)
 798                return 0;
 799
 800        if (mode == LP5523_CMD_RUN) {
 801                ret = lp5523_run_program(engine);
 802        } else if (mode == LP5523_CMD_LOAD) {
 803                lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
 804                lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
 805        } else if (mode == LP5523_CMD_DISABLED) {
 806                lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
 807        }
 808
 809        engine->mode = mode;
 810
 811        return ret;
 812}
 813
 814/*--------------------------------------------------------------*/
 815/*                      Probe, Attach, Remove                   */
 816/*--------------------------------------------------------------*/
 817static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
 818{
 819        if (id < 1 || id > LP5523_ENGINES)
 820                return -1;
 821        engine->id = id;
 822        engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id);
 823        engine->prog_page = id - 1;
 824        engine->mux_page = id + 2;
 825
 826        return 0;
 827}
 828
 829static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
 830                           int chan, struct lp5523_platform_data *pdata)
 831{
 832        char name[32];
 833        int res;
 834
 835        if (chan >= LP5523_LEDS)
 836                return -EINVAL;
 837
 838        if (pdata->led_config[chan].led_current) {
 839                led->led_current = pdata->led_config[chan].led_current;
 840                led->max_current = pdata->led_config[chan].max_current;
 841                led->chan_nr = pdata->led_config[chan].chan_nr;
 842
 843                if (led->chan_nr >= LP5523_LEDS) {
 844                        dev_err(dev, "Use channel numbers between 0 and %d\n",
 845                                LP5523_LEDS - 1);
 846                        return -EINVAL;
 847                }
 848
 849                snprintf(name, sizeof(name), "%s:channel%d",
 850                        pdata->label ?: "lp5523", chan);
 851
 852                led->cdev.name = name;
 853                led->cdev.brightness_set = lp5523_set_brightness;
 854                res = led_classdev_register(dev, &led->cdev);
 855                if (res < 0) {
 856                        dev_err(dev, "couldn't register led on channel %d\n",
 857                                chan);
 858                        return res;
 859                }
 860                res = sysfs_create_group(&led->cdev.dev->kobj,
 861                                &lp5523_led_attribute_group);
 862                if (res < 0) {
 863                        dev_err(dev, "couldn't register current attribute\n");
 864                        led_classdev_unregister(&led->cdev);
 865                        return res;
 866                }
 867        } else {
 868                led->led_current = 0;
 869        }
 870        return 0;
 871}
 872
 873static int __devinit lp5523_probe(struct i2c_client *client,
 874                        const struct i2c_device_id *id)
 875{
 876        struct lp5523_chip              *chip;
 877        struct lp5523_platform_data     *pdata;
 878        int ret, i, led;
 879
 880        chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 881        if (!chip)
 882                return -ENOMEM;
 883
 884        i2c_set_clientdata(client, chip);
 885        chip->client = client;
 886
 887        pdata = client->dev.platform_data;
 888
 889        if (!pdata) {
 890                dev_err(&client->dev, "no platform data\n");
 891                return -EINVAL;
 892        }
 893
 894        mutex_init(&chip->lock);
 895
 896        chip->pdata   = pdata;
 897
 898        if (pdata->setup_resources) {
 899                ret = pdata->setup_resources();
 900                if (ret < 0)
 901                        return ret;
 902        }
 903
 904        if (pdata->enable) {
 905                pdata->enable(0);
 906                usleep_range(1000, 2000); /* Keep enable down at least 1ms */
 907                pdata->enable(1);
 908                usleep_range(1000, 2000); /* 500us abs min. */
 909        }
 910
 911        lp5523_write(client, LP5523_REG_RESET, 0xff);
 912        usleep_range(10000, 20000); /*
 913                                     * Exact value is not available. 10 - 20ms
 914                                     * appears to be enough for reset.
 915                                     */
 916        ret = lp5523_detect(client);
 917        if (ret)
 918                goto fail1;
 919
 920        dev_info(&client->dev, "LP5523 Programmable led chip found\n");
 921
 922        /* Initialize engines */
 923        for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
 924                ret = lp5523_init_engine(&chip->engines[i], i + 1);
 925                if (ret) {
 926                        dev_err(&client->dev, "error initializing engine\n");
 927                        goto fail1;
 928                }
 929        }
 930        ret = lp5523_configure(client);
 931        if (ret < 0) {
 932                dev_err(&client->dev, "error configuring chip\n");
 933                goto fail1;
 934        }
 935
 936        /* Initialize leds */
 937        chip->num_channels = pdata->num_channels;
 938        chip->num_leds = 0;
 939        led = 0;
 940        for (i = 0; i < pdata->num_channels; i++) {
 941                /* Do not initialize channels that are not connected */
 942                if (pdata->led_config[i].led_current == 0)
 943                        continue;
 944
 945                INIT_WORK(&chip->leds[led].brightness_work,
 946                        lp5523_led_brightness_work);
 947
 948                ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata);
 949                if (ret) {
 950                        dev_err(&client->dev, "error initializing leds\n");
 951                        goto fail2;
 952                }
 953                chip->num_leds++;
 954
 955                chip->leds[led].id = led;
 956                /* Set LED current */
 957                lp5523_write(client,
 958                          LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr,
 959                          chip->leds[led].led_current);
 960
 961                led++;
 962        }
 963
 964        ret = lp5523_register_sysfs(client);
 965        if (ret) {
 966                dev_err(&client->dev, "registering sysfs failed\n");
 967                goto fail2;
 968        }
 969        return ret;
 970fail2:
 971        for (i = 0; i < chip->num_leds; i++) {
 972                led_classdev_unregister(&chip->leds[i].cdev);
 973                cancel_work_sync(&chip->leds[i].brightness_work);
 974        }
 975fail1:
 976        if (pdata->enable)
 977                pdata->enable(0);
 978        if (pdata->release_resources)
 979                pdata->release_resources();
 980        return ret;
 981}
 982
 983static int lp5523_remove(struct i2c_client *client)
 984{
 985        struct lp5523_chip *chip = i2c_get_clientdata(client);
 986        int i;
 987
 988        lp5523_unregister_sysfs(client);
 989
 990        for (i = 0; i < chip->num_leds; i++) {
 991                led_classdev_unregister(&chip->leds[i].cdev);
 992                cancel_work_sync(&chip->leds[i].brightness_work);
 993        }
 994
 995        if (chip->pdata->enable)
 996                chip->pdata->enable(0);
 997        if (chip->pdata->release_resources)
 998                chip->pdata->release_resources();
 999        return 0;
1000}
1001
1002static const struct i2c_device_id lp5523_id[] = {
1003        { "lp5523", 0 },
1004        { }
1005};
1006
1007MODULE_DEVICE_TABLE(i2c, lp5523_id);
1008
1009static struct i2c_driver lp5523_driver = {
1010        .driver = {
1011                .name   = "lp5523",
1012        },
1013        .probe          = lp5523_probe,
1014        .remove         = lp5523_remove,
1015        .id_table       = lp5523_id,
1016};
1017
1018module_i2c_driver(lp5523_driver);
1019
1020MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
1021MODULE_DESCRIPTION("LP5523 LED engine");
1022MODULE_LICENSE("GPL");
1023
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.