linux/drivers/leds/leds-lp5521.c
<<
>>
Prefs
   1/*
   2 * LP5521 LED chip 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-lp5521.h>
  35#include <linux/workqueue.h>
  36#include <linux/slab.h>
  37
  38#define LP5521_PROGRAM_LENGTH           32      /* in bytes */
  39
  40#define LP5521_MAX_LEDS                 3       /* Maximum number of LEDs */
  41#define LP5521_MAX_ENGINES              3       /* Maximum number of engines */
  42
  43#define LP5521_ENG_MASK_BASE            0x30    /* 00110000 */
  44#define LP5521_ENG_STATUS_MASK          0x07    /* 00000111 */
  45
  46#define LP5521_CMD_LOAD                 0x15    /* 00010101 */
  47#define LP5521_CMD_RUN                  0x2a    /* 00101010 */
  48#define LP5521_CMD_DIRECT               0x3f    /* 00111111 */
  49#define LP5521_CMD_DISABLED             0x00    /* 00000000 */
  50
  51/* Registers */
  52#define LP5521_REG_ENABLE               0x00
  53#define LP5521_REG_OP_MODE              0x01
  54#define LP5521_REG_R_PWM                0x02
  55#define LP5521_REG_G_PWM                0x03
  56#define LP5521_REG_B_PWM                0x04
  57#define LP5521_REG_R_CURRENT            0x05
  58#define LP5521_REG_G_CURRENT            0x06
  59#define LP5521_REG_B_CURRENT            0x07
  60#define LP5521_REG_CONFIG               0x08
  61#define LP5521_REG_R_CHANNEL_PC         0x09
  62#define LP5521_REG_G_CHANNEL_PC         0x0A
  63#define LP5521_REG_B_CHANNEL_PC         0x0B
  64#define LP5521_REG_STATUS               0x0C
  65#define LP5521_REG_RESET                0x0D
  66#define LP5521_REG_GPO                  0x0E
  67#define LP5521_REG_R_PROG_MEM           0x10
  68#define LP5521_REG_G_PROG_MEM           0x30
  69#define LP5521_REG_B_PROG_MEM           0x50
  70
  71#define LP5521_PROG_MEM_BASE            LP5521_REG_R_PROG_MEM
  72#define LP5521_PROG_MEM_SIZE            0x20
  73
  74/* Base register to set LED current */
  75#define LP5521_REG_LED_CURRENT_BASE     LP5521_REG_R_CURRENT
  76
  77/* Base register to set the brightness */
  78#define LP5521_REG_LED_PWM_BASE         LP5521_REG_R_PWM
  79
  80/* Bits in ENABLE register */
  81#define LP5521_MASTER_ENABLE            0x40    /* Chip master enable */
  82#define LP5521_LOGARITHMIC_PWM          0x80    /* Logarithmic PWM adjustment */
  83#define LP5521_EXEC_RUN                 0x2A
  84#define LP5521_ENABLE_DEFAULT   \
  85        (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)
  86#define LP5521_ENABLE_RUN_PROGRAM       \
  87        (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
  88
  89/* Status */
  90#define LP5521_EXT_CLK_USED             0x08
  91
  92/* default R channel current register value */
  93#define LP5521_REG_R_CURR_DEFAULT       0xAF
  94
  95/* Pattern Mode */
  96#define PATTERN_OFF     0
  97
  98struct lp5521_engine {
  99        int             id;
 100        u8              mode;
 101        u8              prog_page;
 102        u8              engine_mask;
 103};
 104
 105struct lp5521_led {
 106        int                     id;
 107        u8                      chan_nr;
 108        u8                      led_current;
 109        u8                      max_current;
 110        struct led_classdev     cdev;
 111        struct work_struct      brightness_work;
 112        u8                      brightness;
 113};
 114
 115struct lp5521_chip {
 116        struct lp5521_platform_data *pdata;
 117        struct mutex            lock; /* Serialize control */
 118        struct i2c_client       *client;
 119        struct lp5521_engine    engines[LP5521_MAX_ENGINES];
 120        struct lp5521_led       leds[LP5521_MAX_LEDS];
 121        u8                      num_channels;
 122        u8                      num_leds;
 123};
 124
 125static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev)
 126{
 127        return container_of(cdev, struct lp5521_led, cdev);
 128}
 129
 130static inline struct lp5521_chip *engine_to_lp5521(struct lp5521_engine *engine)
 131{
 132        return container_of(engine, struct lp5521_chip,
 133                            engines[engine->id - 1]);
 134}
 135
 136static inline struct lp5521_chip *led_to_lp5521(struct lp5521_led *led)
 137{
 138        return container_of(led, struct lp5521_chip,
 139                            leds[led->id]);
 140}
 141
 142static void lp5521_led_brightness_work(struct work_struct *work);
 143
 144static inline int lp5521_write(struct i2c_client *client, u8 reg, u8 value)
 145{
 146        return i2c_smbus_write_byte_data(client, reg, value);
 147}
 148
 149static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf)
 150{
 151        s32 ret;
 152
 153        ret = i2c_smbus_read_byte_data(client, reg);
 154        if (ret < 0)
 155                return -EIO;
 156
 157        *buf = ret;
 158        return 0;
 159}
 160
 161static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode)
 162{
 163        struct lp5521_chip *chip = engine_to_lp5521(engine);
 164        struct i2c_client *client = chip->client;
 165        int ret;
 166        u8 engine_state;
 167
 168        /* Only transition between RUN and DIRECT mode are handled here */
 169        if (mode == LP5521_CMD_LOAD)
 170                return 0;
 171
 172        if (mode == LP5521_CMD_DISABLED)
 173                mode = LP5521_CMD_DIRECT;
 174
 175        ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state);
 176        if (ret < 0)
 177                return ret;
 178
 179        /* set mode only for this engine */
 180        engine_state &= ~(engine->engine_mask);
 181        mode &= engine->engine_mask;
 182        engine_state |= mode;
 183        return lp5521_write(client, LP5521_REG_OP_MODE, engine_state);
 184}
 185
 186static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
 187{
 188        struct lp5521_chip *chip = engine_to_lp5521(eng);
 189        struct i2c_client *client = chip->client;
 190        int ret;
 191        int addr;
 192        u8 mode;
 193
 194        /* move current engine to direct mode and remember the state */
 195        ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT);
 196        if (ret)
 197                return ret;
 198
 199        /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
 200        usleep_range(1000, 2000);
 201        ret = lp5521_read(client, LP5521_REG_OP_MODE, &mode);
 202        if (ret)
 203                return ret;
 204
 205        /* For loading, all the engines to load mode */
 206        lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
 207        /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
 208        usleep_range(1000, 2000);
 209        lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
 210        /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
 211        usleep_range(1000, 2000);
 212
 213        addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE;
 214        i2c_smbus_write_i2c_block_data(client,
 215                                addr,
 216                                LP5521_PROG_MEM_SIZE,
 217                                pattern);
 218
 219        return lp5521_write(client, LP5521_REG_OP_MODE, mode);
 220}
 221
 222static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr)
 223{
 224        return lp5521_write(chip->client,
 225                    LP5521_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr,
 226                    curr);
 227}
 228
 229static void lp5521_init_engine(struct lp5521_chip *chip)
 230{
 231        int i;
 232        for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
 233                chip->engines[i].id = i + 1;
 234                chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2);
 235                chip->engines[i].prog_page = i;
 236        }
 237}
 238
 239static int lp5521_configure(struct i2c_client *client)
 240{
 241        struct lp5521_chip *chip = i2c_get_clientdata(client);
 242        int ret;
 243        u8 cfg;
 244
 245        lp5521_init_engine(chip);
 246
 247        /* Set all PWMs to direct control mode */
 248        ret = lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
 249
 250        cfg = chip->pdata->update_config ?
 251                : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
 252        ret |= lp5521_write(client, LP5521_REG_CONFIG, cfg);
 253
 254        /* Initialize all channels PWM to zero -> leds off */
 255        ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
 256        ret |= lp5521_write(client, LP5521_REG_G_PWM, 0);
 257        ret |= lp5521_write(client, LP5521_REG_B_PWM, 0);
 258
 259        /* Set engines are set to run state when OP_MODE enables engines */
 260        ret |= lp5521_write(client, LP5521_REG_ENABLE,
 261                        LP5521_ENABLE_RUN_PROGRAM);
 262        /* enable takes 500us. 1 - 2 ms leaves some margin */
 263        usleep_range(1000, 2000);
 264
 265        return ret;
 266}
 267
 268static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf)
 269{
 270        int ret;
 271        u8 status;
 272
 273        ret = lp5521_read(chip->client, LP5521_REG_STATUS, &status);
 274        if (ret < 0)
 275                return ret;
 276
 277        /* Check that ext clock is really in use if requested */
 278        if (chip->pdata && chip->pdata->clock_mode == LP5521_CLOCK_EXT)
 279                if  ((status & LP5521_EXT_CLK_USED) == 0)
 280                        return -EIO;
 281        return 0;
 282}
 283
 284static void lp5521_set_brightness(struct led_classdev *cdev,
 285                             enum led_brightness brightness)
 286{
 287        struct lp5521_led *led = cdev_to_led(cdev);
 288        led->brightness = (u8)brightness;
 289        schedule_work(&led->brightness_work);
 290}
 291
 292static void lp5521_led_brightness_work(struct work_struct *work)
 293{
 294        struct lp5521_led *led = container_of(work,
 295                                              struct lp5521_led,
 296                                              brightness_work);
 297        struct lp5521_chip *chip = led_to_lp5521(led);
 298        struct i2c_client *client = chip->client;
 299
 300        mutex_lock(&chip->lock);
 301        lp5521_write(client, LP5521_REG_LED_PWM_BASE + led->chan_nr,
 302                led->brightness);
 303        mutex_unlock(&chip->lock);
 304}
 305
 306/* Detect the chip by setting its ENABLE register and reading it back. */
 307static int lp5521_detect(struct i2c_client *client)
 308{
 309        int ret;
 310        u8 buf;
 311
 312        ret = lp5521_write(client, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
 313        if (ret)
 314                return ret;
 315        /* enable takes 500us. 1 - 2 ms leaves some margin */
 316        usleep_range(1000, 2000);
 317        ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
 318        if (ret)
 319                return ret;
 320        if (buf != LP5521_ENABLE_DEFAULT)
 321                return -ENODEV;
 322
 323        return 0;
 324}
 325
 326/* Set engine mode and create appropriate sysfs attributes, if required. */
 327static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode)
 328{
 329        int ret = 0;
 330
 331        /* if in that mode already do nothing, except for run */
 332        if (mode == engine->mode && mode != LP5521_CMD_RUN)
 333                return 0;
 334
 335        if (mode == LP5521_CMD_RUN) {
 336                ret = lp5521_set_engine_mode(engine, LP5521_CMD_RUN);
 337        } else if (mode == LP5521_CMD_LOAD) {
 338                lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED);
 339                lp5521_set_engine_mode(engine, LP5521_CMD_LOAD);
 340        } else if (mode == LP5521_CMD_DISABLED) {
 341                lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED);
 342        }
 343
 344        engine->mode = mode;
 345
 346        return ret;
 347}
 348
 349static int lp5521_do_store_load(struct lp5521_engine *engine,
 350                                const char *buf, size_t len)
 351{
 352        struct lp5521_chip *chip = engine_to_lp5521(engine);
 353        struct i2c_client *client = chip->client;
 354        int  ret, nrchars, offset = 0, i = 0;
 355        char c[3];
 356        unsigned cmd;
 357        u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
 358
 359        while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) {
 360                /* separate sscanfs because length is working only for %s */
 361                ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
 362                if (ret != 2)
 363                        goto fail;
 364                ret = sscanf(c, "%2x", &cmd);
 365                if (ret != 1)
 366                        goto fail;
 367                pattern[i] = (u8)cmd;
 368
 369                offset += nrchars;
 370                i++;
 371        }
 372
 373        /* Each instruction is 16bit long. Check that length is even */
 374        if (i % 2)
 375                goto fail;
 376
 377        mutex_lock(&chip->lock);
 378        if (engine->mode == LP5521_CMD_LOAD)
 379                ret = lp5521_load_program(engine, pattern);
 380        else
 381                ret = -EINVAL;
 382        mutex_unlock(&chip->lock);
 383
 384        if (ret) {
 385                dev_err(&client->dev, "failed loading pattern\n");
 386                return ret;
 387        }
 388
 389        return len;
 390fail:
 391        dev_err(&client->dev, "wrong pattern format\n");
 392        return -EINVAL;
 393}
 394
 395static ssize_t store_engine_load(struct device *dev,
 396                                     struct device_attribute *attr,
 397                                     const char *buf, size_t len, int nr)
 398{
 399        struct i2c_client *client = to_i2c_client(dev);
 400        struct lp5521_chip *chip = i2c_get_clientdata(client);
 401        return lp5521_do_store_load(&chip->engines[nr - 1], buf, len);
 402}
 403
 404#define store_load(nr)                                                  \
 405static ssize_t store_engine##nr##_load(struct device *dev,              \
 406                                     struct device_attribute *attr,     \
 407                                     const char *buf, size_t len)       \
 408{                                                                       \
 409        return store_engine_load(dev, attr, buf, len, nr);              \
 410}
 411store_load(1)
 412store_load(2)
 413store_load(3)
 414
 415static ssize_t show_engine_mode(struct device *dev,
 416                                struct device_attribute *attr,
 417                                char *buf, int nr)
 418{
 419        struct i2c_client *client = to_i2c_client(dev);
 420        struct lp5521_chip *chip = i2c_get_clientdata(client);
 421        switch (chip->engines[nr - 1].mode) {
 422        case LP5521_CMD_RUN:
 423                return sprintf(buf, "run\n");
 424        case LP5521_CMD_LOAD:
 425                return sprintf(buf, "load\n");
 426        case LP5521_CMD_DISABLED:
 427                return sprintf(buf, "disabled\n");
 428        default:
 429                return sprintf(buf, "disabled\n");
 430        }
 431}
 432
 433#define show_mode(nr)                                                   \
 434static ssize_t show_engine##nr##_mode(struct device *dev,               \
 435                                    struct device_attribute *attr,      \
 436                                    char *buf)                          \
 437{                                                                       \
 438        return show_engine_mode(dev, attr, buf, nr);                    \
 439}
 440show_mode(1)
 441show_mode(2)
 442show_mode(3)
 443
 444static ssize_t store_engine_mode(struct device *dev,
 445                                 struct device_attribute *attr,
 446                                 const char *buf, size_t len, int nr)
 447{
 448        struct i2c_client *client = to_i2c_client(dev);
 449        struct lp5521_chip *chip = i2c_get_clientdata(client);
 450        struct lp5521_engine *engine = &chip->engines[nr - 1];
 451        mutex_lock(&chip->lock);
 452
 453        if (!strncmp(buf, "run", 3))
 454                lp5521_set_mode(engine, LP5521_CMD_RUN);
 455        else if (!strncmp(buf, "load", 4))
 456                lp5521_set_mode(engine, LP5521_CMD_LOAD);
 457        else if (!strncmp(buf, "disabled", 8))
 458                lp5521_set_mode(engine, LP5521_CMD_DISABLED);
 459
 460        mutex_unlock(&chip->lock);
 461        return len;
 462}
 463
 464#define store_mode(nr)                                                  \
 465static ssize_t store_engine##nr##_mode(struct device *dev,              \
 466                                     struct device_attribute *attr,     \
 467                                     const char *buf, size_t len)       \
 468{                                                                       \
 469        return store_engine_mode(dev, attr, buf, len, nr);              \
 470}
 471store_mode(1)
 472store_mode(2)
 473store_mode(3)
 474
 475static ssize_t show_max_current(struct device *dev,
 476                            struct device_attribute *attr,
 477                            char *buf)
 478{
 479        struct led_classdev *led_cdev = dev_get_drvdata(dev);
 480        struct lp5521_led *led = cdev_to_led(led_cdev);
 481
 482        return sprintf(buf, "%d\n", led->max_current);
 483}
 484
 485static ssize_t show_current(struct device *dev,
 486                            struct device_attribute *attr,
 487                            char *buf)
 488{
 489        struct led_classdev *led_cdev = dev_get_drvdata(dev);
 490        struct lp5521_led *led = cdev_to_led(led_cdev);
 491
 492        return sprintf(buf, "%d\n", led->led_current);
 493}
 494
 495static ssize_t store_current(struct device *dev,
 496                             struct device_attribute *attr,
 497                             const char *buf, size_t len)
 498{
 499        struct led_classdev *led_cdev = dev_get_drvdata(dev);
 500        struct lp5521_led *led = cdev_to_led(led_cdev);
 501        struct lp5521_chip *chip = led_to_lp5521(led);
 502        ssize_t ret;
 503        unsigned long curr;
 504
 505        if (kstrtoul(buf, 0, &curr))
 506                return -EINVAL;
 507
 508        if (curr > led->max_current)
 509                return -EINVAL;
 510
 511        mutex_lock(&chip->lock);
 512        ret = lp5521_set_led_current(chip, led->id, curr);
 513        mutex_unlock(&chip->lock);
 514
 515        if (ret < 0)
 516                return ret;
 517
 518        led->led_current = (u8)curr;
 519
 520        return len;
 521}
 522
 523static ssize_t lp5521_selftest(struct device *dev,
 524                               struct device_attribute *attr,
 525                               char *buf)
 526{
 527        struct i2c_client *client = to_i2c_client(dev);
 528        struct lp5521_chip *chip = i2c_get_clientdata(client);
 529        int ret;
 530
 531        mutex_lock(&chip->lock);
 532        ret = lp5521_run_selftest(chip, buf);
 533        mutex_unlock(&chip->lock);
 534        return sprintf(buf, "%s\n", ret ? "FAIL" : "OK");
 535}
 536
 537static void lp5521_clear_program_memory(struct i2c_client *cl)
 538{
 539        int i;
 540        u8 rgb_mem[] = {
 541                LP5521_REG_R_PROG_MEM,
 542                LP5521_REG_G_PROG_MEM,
 543                LP5521_REG_B_PROG_MEM,
 544        };
 545
 546        for (i = 0; i < ARRAY_SIZE(rgb_mem); i++) {
 547                lp5521_write(cl, rgb_mem[i], 0);
 548                lp5521_write(cl, rgb_mem[i] + 1, 0);
 549        }
 550}
 551
 552static void lp5521_write_program_memory(struct i2c_client *cl,
 553                                u8 base, u8 *rgb, int size)
 554{
 555        int i;
 556
 557        if (!rgb || size <= 0)
 558                return;
 559
 560        for (i = 0; i < size; i++)
 561                lp5521_write(cl, base + i, *(rgb + i));
 562
 563        lp5521_write(cl, base + i, 0);
 564        lp5521_write(cl, base + i + 1, 0);
 565}
 566
 567static inline struct lp5521_led_pattern *lp5521_get_pattern
 568                                        (struct lp5521_chip *chip, u8 offset)
 569{
 570        struct lp5521_led_pattern *ptn;
 571        ptn = chip->pdata->patterns + (offset - 1);
 572        return ptn;
 573}
 574
 575static void lp5521_run_led_pattern(int mode, struct lp5521_chip *chip)
 576{
 577        struct lp5521_led_pattern *ptn;
 578        struct i2c_client *cl = chip->client;
 579        int num_patterns = chip->pdata->num_patterns;
 580
 581        if (mode > num_patterns || !(chip->pdata->patterns))
 582                return;
 583
 584        if (mode == PATTERN_OFF) {
 585                lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
 586                usleep_range(1000, 2000);
 587                lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
 588        } else {
 589                ptn = lp5521_get_pattern(chip, mode);
 590                if (!ptn)
 591                        return;
 592
 593                lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
 594                usleep_range(1000, 2000);
 595
 596                lp5521_clear_program_memory(cl);
 597
 598                lp5521_write_program_memory(cl, LP5521_REG_R_PROG_MEM,
 599                                        ptn->r, ptn->size_r);
 600                lp5521_write_program_memory(cl, LP5521_REG_G_PROG_MEM,
 601                                        ptn->g, ptn->size_g);
 602                lp5521_write_program_memory(cl, LP5521_REG_B_PROG_MEM,
 603                                        ptn->b, ptn->size_b);
 604
 605                lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_RUN);
 606                usleep_range(1000, 2000);
 607                lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM);
 608        }
 609}
 610
 611static ssize_t store_led_pattern(struct device *dev,
 612                                struct device_attribute *attr,
 613                                const char *buf, size_t len)
 614{
 615        struct lp5521_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
 616        unsigned long val;
 617        int ret;
 618
 619        ret = strict_strtoul(buf, 16, &val);
 620        if (ret)
 621                return ret;
 622
 623        lp5521_run_led_pattern(val, chip);
 624
 625        return len;
 626}
 627
 628/* led class device attributes */
 629static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
 630static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
 631
 632static struct attribute *lp5521_led_attributes[] = {
 633        &dev_attr_led_current.attr,
 634        &dev_attr_max_current.attr,
 635        NULL,
 636};
 637
 638static struct attribute_group lp5521_led_attribute_group = {
 639        .attrs = lp5521_led_attributes
 640};
 641
 642/* device attributes */
 643static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR,
 644                   show_engine1_mode, store_engine1_mode);
 645static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR,
 646                   show_engine2_mode, store_engine2_mode);
 647static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR,
 648                   show_engine3_mode, store_engine3_mode);
 649static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
 650static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
 651static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
 652static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
 653static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, store_led_pattern);
 654
 655static struct attribute *lp5521_attributes[] = {
 656        &dev_attr_engine1_mode.attr,
 657        &dev_attr_engine2_mode.attr,
 658        &dev_attr_engine3_mode.attr,
 659        &dev_attr_selftest.attr,
 660        &dev_attr_engine1_load.attr,
 661        &dev_attr_engine2_load.attr,
 662        &dev_attr_engine3_load.attr,
 663        &dev_attr_led_pattern.attr,
 664        NULL
 665};
 666
 667static const struct attribute_group lp5521_group = {
 668        .attrs = lp5521_attributes,
 669};
 670
 671static int lp5521_register_sysfs(struct i2c_client *client)
 672{
 673        struct device *dev = &client->dev;
 674        return sysfs_create_group(&dev->kobj, &lp5521_group);
 675}
 676
 677static void lp5521_unregister_sysfs(struct i2c_client *client)
 678{
 679        struct lp5521_chip *chip = i2c_get_clientdata(client);
 680        struct device *dev = &client->dev;
 681        int i;
 682
 683        sysfs_remove_group(&dev->kobj, &lp5521_group);
 684
 685        for (i = 0; i < chip->num_leds; i++)
 686                sysfs_remove_group(&chip->leds[i].cdev.dev->kobj,
 687                                &lp5521_led_attribute_group);
 688}
 689
 690static int __devinit lp5521_init_led(struct lp5521_led *led,
 691                                struct i2c_client *client,
 692                                int chan, struct lp5521_platform_data *pdata)
 693{
 694        struct device *dev = &client->dev;
 695        char name[32];
 696        int res;
 697
 698        if (chan >= LP5521_MAX_LEDS)
 699                return -EINVAL;
 700
 701        if (pdata->led_config[chan].led_current == 0)
 702                return 0;
 703
 704        led->led_current = pdata->led_config[chan].led_current;
 705        led->max_current = pdata->led_config[chan].max_current;
 706        led->chan_nr = pdata->led_config[chan].chan_nr;
 707
 708        if (led->chan_nr >= LP5521_MAX_LEDS) {
 709                dev_err(dev, "Use channel numbers between 0 and %d\n",
 710                        LP5521_MAX_LEDS - 1);
 711                return -EINVAL;
 712        }
 713
 714        led->cdev.brightness_set = lp5521_set_brightness;
 715        if (pdata->led_config[chan].name) {
 716                led->cdev.name = pdata->led_config[chan].name;
 717        } else {
 718                snprintf(name, sizeof(name), "%s:channel%d",
 719                        pdata->label ?: client->name, chan);
 720                led->cdev.name = name;
 721        }
 722
 723        res = led_classdev_register(dev, &led->cdev);
 724        if (res < 0) {
 725                dev_err(dev, "couldn't register led on channel %d\n", chan);
 726                return res;
 727        }
 728
 729        res = sysfs_create_group(&led->cdev.dev->kobj,
 730                        &lp5521_led_attribute_group);
 731        if (res < 0) {
 732                dev_err(dev, "couldn't register current attribute\n");
 733                led_classdev_unregister(&led->cdev);
 734                return res;
 735        }
 736        return 0;
 737}
 738
 739static int __devinit lp5521_probe(struct i2c_client *client,
 740                        const struct i2c_device_id *id)
 741{
 742        struct lp5521_chip              *chip;
 743        struct lp5521_platform_data     *pdata;
 744        int ret, i, led;
 745        u8 buf;
 746
 747        chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 748        if (!chip)
 749                return -ENOMEM;
 750
 751        i2c_set_clientdata(client, chip);
 752        chip->client = client;
 753
 754        pdata = client->dev.platform_data;
 755
 756        if (!pdata) {
 757                dev_err(&client->dev, "no platform data\n");
 758                return -EINVAL;
 759        }
 760
 761        mutex_init(&chip->lock);
 762
 763        chip->pdata   = pdata;
 764
 765        if (pdata->setup_resources) {
 766                ret = pdata->setup_resources();
 767                if (ret < 0)
 768                        return ret;
 769        }
 770
 771        if (pdata->enable) {
 772                pdata->enable(0);
 773                usleep_range(1000, 2000); /* Keep enable down at least 1ms */
 774                pdata->enable(1);
 775                usleep_range(1000, 2000); /* 500us abs min. */
 776        }
 777
 778        lp5521_write(client, LP5521_REG_RESET, 0xff);
 779        usleep_range(10000, 20000); /*
 780                                     * Exact value is not available. 10 - 20ms
 781                                     * appears to be enough for reset.
 782                                     */
 783
 784        /*
 785         * Make sure that the chip is reset by reading back the r channel
 786         * current reg. This is dummy read is required on some platforms -
 787         * otherwise further access to the R G B channels in the
 788         * LP5521_REG_ENABLE register will not have any effect - strange!
 789         */
 790        ret = lp5521_read(client, LP5521_REG_R_CURRENT, &buf);
 791        if (ret || buf != LP5521_REG_R_CURR_DEFAULT) {
 792                dev_err(&client->dev, "error in resetting chip\n");
 793                goto fail2;
 794        }
 795        usleep_range(10000, 20000);
 796
 797        ret = lp5521_detect(client);
 798
 799        if (ret) {
 800                dev_err(&client->dev, "Chip not found\n");
 801                goto fail2;
 802        }
 803
 804        dev_info(&client->dev, "%s programmable led chip found\n", id->name);
 805
 806        ret = lp5521_configure(client);
 807        if (ret < 0) {
 808                dev_err(&client->dev, "error configuring chip\n");
 809                goto fail1;
 810        }
 811
 812        /* Initialize leds */
 813        chip->num_channels = pdata->num_channels;
 814        chip->num_leds = 0;
 815        led = 0;
 816        for (i = 0; i < pdata->num_channels; i++) {
 817                /* Do not initialize channels that are not connected */
 818                if (pdata->led_config[i].led_current == 0)
 819                        continue;
 820
 821                ret = lp5521_init_led(&chip->leds[led], client, i, pdata);
 822                if (ret) {
 823                        dev_err(&client->dev, "error initializing leds\n");
 824                        goto fail2;
 825                }
 826                chip->num_leds++;
 827
 828                chip->leds[led].id = led;
 829                /* Set initial LED current */
 830                lp5521_set_led_current(chip, led,
 831                                chip->leds[led].led_current);
 832
 833                INIT_WORK(&(chip->leds[led].brightness_work),
 834                        lp5521_led_brightness_work);
 835
 836                led++;
 837        }
 838
 839        ret = lp5521_register_sysfs(client);
 840        if (ret) {
 841                dev_err(&client->dev, "registering sysfs failed\n");
 842                goto fail2;
 843        }
 844        return ret;
 845fail2:
 846        for (i = 0; i < chip->num_leds; i++) {
 847                led_classdev_unregister(&chip->leds[i].cdev);
 848                cancel_work_sync(&chip->leds[i].brightness_work);
 849        }
 850fail1:
 851        if (pdata->enable)
 852                pdata->enable(0);
 853        if (pdata->release_resources)
 854                pdata->release_resources();
 855        return ret;
 856}
 857
 858static int __devexit lp5521_remove(struct i2c_client *client)
 859{
 860        struct lp5521_chip *chip = i2c_get_clientdata(client);
 861        int i;
 862
 863        lp5521_run_led_pattern(PATTERN_OFF, chip);
 864        lp5521_unregister_sysfs(client);
 865
 866        for (i = 0; i < chip->num_leds; i++) {
 867                led_classdev_unregister(&chip->leds[i].cdev);
 868                cancel_work_sync(&chip->leds[i].brightness_work);
 869        }
 870
 871        if (chip->pdata->enable)
 872                chip->pdata->enable(0);
 873        if (chip->pdata->release_resources)
 874                chip->pdata->release_resources();
 875        return 0;
 876}
 877
 878static const struct i2c_device_id lp5521_id[] = {
 879        { "lp5521", 0 }, /* Three channel chip */
 880        { }
 881};
 882MODULE_DEVICE_TABLE(i2c, lp5521_id);
 883
 884static struct i2c_driver lp5521_driver = {
 885        .driver = {
 886                .name   = "lp5521",
 887        },
 888        .probe          = lp5521_probe,
 889        .remove         = __devexit_p(lp5521_remove),
 890        .id_table       = lp5521_id,
 891};
 892
 893module_i2c_driver(lp5521_driver);
 894
 895MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo");
 896MODULE_DESCRIPTION("LP5521 LED engine");
 897MODULE_LICENSE("GPL v2");
 898
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.