linux/drivers/leds/leds-lp55xx-common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * LP5521/LP5523/LP55231/LP5562 Common Driver
   4 *
   5 * Copyright 2012 Texas Instruments
   6 *
   7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
   8 *
   9 * Derived from leds-lp5521.c, leds-lp5523.c
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/delay.h>
  14#include <linux/firmware.h>
  15#include <linux/i2c.h>
  16#include <linux/leds.h>
  17#include <linux/module.h>
  18#include <linux/platform_data/leds-lp55xx.h>
  19#include <linux/slab.h>
  20#include <linux/gpio/consumer.h>
  21
  22#include "leds-lp55xx-common.h"
  23
  24/* External clock rate */
  25#define LP55XX_CLK_32K                  32768
  26
  27static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)
  28{
  29        return container_of(cdev, struct lp55xx_led, cdev);
  30}
  31
  32static struct lp55xx_led *dev_to_lp55xx_led(struct device *dev)
  33{
  34        return cdev_to_lp55xx_led(dev_get_drvdata(dev));
  35}
  36
  37static struct lp55xx_led *mcled_cdev_to_led(struct led_classdev_mc *mc_cdev)
  38{
  39        return container_of(mc_cdev, struct lp55xx_led, mc_cdev);
  40}
  41
  42static void lp55xx_reset_device(struct lp55xx_chip *chip)
  43{
  44        struct lp55xx_device_config *cfg = chip->cfg;
  45        u8 addr = cfg->reset.addr;
  46        u8 val  = cfg->reset.val;
  47
  48        /* no error checking here because no ACK from the device after reset */
  49        lp55xx_write(chip, addr, val);
  50}
  51
  52static int lp55xx_detect_device(struct lp55xx_chip *chip)
  53{
  54        struct lp55xx_device_config *cfg = chip->cfg;
  55        u8 addr = cfg->enable.addr;
  56        u8 val  = cfg->enable.val;
  57        int ret;
  58
  59        ret = lp55xx_write(chip, addr, val);
  60        if (ret)
  61                return ret;
  62
  63        usleep_range(1000, 2000);
  64
  65        ret = lp55xx_read(chip, addr, &val);
  66        if (ret)
  67                return ret;
  68
  69        if (val != cfg->enable.val)
  70                return -ENODEV;
  71
  72        return 0;
  73}
  74
  75static int lp55xx_post_init_device(struct lp55xx_chip *chip)
  76{
  77        struct lp55xx_device_config *cfg = chip->cfg;
  78
  79        if (!cfg->post_init_device)
  80                return 0;
  81
  82        return cfg->post_init_device(chip);
  83}
  84
  85static ssize_t led_current_show(struct device *dev,
  86                            struct device_attribute *attr,
  87                            char *buf)
  88{
  89        struct lp55xx_led *led = dev_to_lp55xx_led(dev);
  90
  91        return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
  92}
  93
  94static ssize_t led_current_store(struct device *dev,
  95                             struct device_attribute *attr,
  96                             const char *buf, size_t len)
  97{
  98        struct lp55xx_led *led = dev_to_lp55xx_led(dev);
  99        struct lp55xx_chip *chip = led->chip;
 100        unsigned long curr;
 101
 102        if (kstrtoul(buf, 0, &curr))
 103                return -EINVAL;
 104
 105        if (curr > led->max_current)
 106                return -EINVAL;
 107
 108        if (!chip->cfg->set_led_current)
 109                return len;
 110
 111        mutex_lock(&chip->lock);
 112        chip->cfg->set_led_current(led, (u8)curr);
 113        mutex_unlock(&chip->lock);
 114
 115        return len;
 116}
 117
 118static ssize_t max_current_show(struct device *dev,
 119                            struct device_attribute *attr,
 120                            char *buf)
 121{
 122        struct lp55xx_led *led = dev_to_lp55xx_led(dev);
 123
 124        return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
 125}
 126
 127static DEVICE_ATTR_RW(led_current);
 128static DEVICE_ATTR_RO(max_current);
 129
 130static struct attribute *lp55xx_led_attrs[] = {
 131        &dev_attr_led_current.attr,
 132        &dev_attr_max_current.attr,
 133        NULL,
 134};
 135ATTRIBUTE_GROUPS(lp55xx_led);
 136
 137static int lp55xx_set_mc_brightness(struct led_classdev *cdev,
 138                                    enum led_brightness brightness)
 139{
 140        struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev);
 141        struct lp55xx_led *led = mcled_cdev_to_led(mc_dev);
 142        struct lp55xx_device_config *cfg = led->chip->cfg;
 143
 144        led_mc_calc_color_components(&led->mc_cdev, brightness);
 145        return cfg->multicolor_brightness_fn(led);
 146
 147}
 148
 149static int lp55xx_set_brightness(struct led_classdev *cdev,
 150                             enum led_brightness brightness)
 151{
 152        struct lp55xx_led *led = cdev_to_lp55xx_led(cdev);
 153        struct lp55xx_device_config *cfg = led->chip->cfg;
 154
 155        led->brightness = (u8)brightness;
 156        return cfg->brightness_fn(led);
 157}
 158
 159static int lp55xx_init_led(struct lp55xx_led *led,
 160                        struct lp55xx_chip *chip, int chan)
 161{
 162        struct lp55xx_platform_data *pdata = chip->pdata;
 163        struct lp55xx_device_config *cfg = chip->cfg;
 164        struct device *dev = &chip->cl->dev;
 165        int max_channel = cfg->max_channel;
 166        struct mc_subled *mc_led_info;
 167        struct led_classdev *led_cdev;
 168        char name[32];
 169        int i, j = 0;
 170        int ret;
 171
 172        if (chan >= max_channel) {
 173                dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel);
 174                return -EINVAL;
 175        }
 176
 177        if (pdata->led_config[chan].led_current == 0)
 178                return 0;
 179
 180        if (pdata->led_config[chan].name) {
 181                led->cdev.name = pdata->led_config[chan].name;
 182        } else {
 183                snprintf(name, sizeof(name), "%s:channel%d",
 184                        pdata->label ? : chip->cl->name, chan);
 185                led->cdev.name = name;
 186        }
 187
 188        if (pdata->led_config[chan].num_colors > 1) {
 189                mc_led_info = devm_kcalloc(dev,
 190                                           pdata->led_config[chan].num_colors,
 191                                           sizeof(*mc_led_info), GFP_KERNEL);
 192                if (!mc_led_info)
 193                        return -ENOMEM;
 194
 195                led_cdev = &led->mc_cdev.led_cdev;
 196                led_cdev->name = led->cdev.name;
 197                led_cdev->brightness_set_blocking = lp55xx_set_mc_brightness;
 198                led->mc_cdev.num_colors = pdata->led_config[chan].num_colors;
 199                for (i = 0; i < led->mc_cdev.num_colors; i++) {
 200                        mc_led_info[i].color_index =
 201                                pdata->led_config[chan].color_id[i];
 202                        mc_led_info[i].channel =
 203                                        pdata->led_config[chan].output_num[i];
 204                        j++;
 205                }
 206
 207                led->mc_cdev.subled_info = mc_led_info;
 208        } else {
 209                led->cdev.brightness_set_blocking = lp55xx_set_brightness;
 210        }
 211
 212        led->cdev.groups = lp55xx_led_groups;
 213        led->cdev.default_trigger = pdata->led_config[chan].default_trigger;
 214        led->led_current = pdata->led_config[chan].led_current;
 215        led->max_current = pdata->led_config[chan].max_current;
 216        led->chan_nr = pdata->led_config[chan].chan_nr;
 217
 218        if (led->chan_nr >= max_channel) {
 219                dev_err(dev, "Use channel numbers between 0 and %d\n",
 220                        max_channel - 1);
 221                return -EINVAL;
 222        }
 223
 224        if (pdata->led_config[chan].num_colors > 1)
 225                ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev);
 226        else
 227                ret = devm_led_classdev_register(dev, &led->cdev);
 228
 229        if (ret) {
 230                dev_err(dev, "led register err: %d\n", ret);
 231                return ret;
 232        }
 233
 234        return 0;
 235}
 236
 237static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 238{
 239        struct lp55xx_chip *chip = context;
 240        struct device *dev = &chip->cl->dev;
 241        enum lp55xx_engine_index idx = chip->engine_idx;
 242
 243        if (!fw) {
 244                dev_err(dev, "firmware request failed\n");
 245                return;
 246        }
 247
 248        /* handling firmware data is chip dependent */
 249        mutex_lock(&chip->lock);
 250
 251        chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD;
 252        chip->fw = fw;
 253        if (chip->cfg->firmware_cb)
 254                chip->cfg->firmware_cb(chip);
 255
 256        mutex_unlock(&chip->lock);
 257
 258        /* firmware should be released for other channel use */
 259        release_firmware(chip->fw);
 260        chip->fw = NULL;
 261}
 262
 263static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 264{
 265        const char *name = chip->cl->name;
 266        struct device *dev = &chip->cl->dev;
 267
 268        return request_firmware_nowait(THIS_MODULE, false, name, dev,
 269                                GFP_KERNEL, chip, lp55xx_firmware_loaded);
 270}
 271
 272static ssize_t select_engine_show(struct device *dev,
 273                            struct device_attribute *attr,
 274                            char *buf)
 275{
 276        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 277        struct lp55xx_chip *chip = led->chip;
 278
 279        return sprintf(buf, "%d\n", chip->engine_idx);
 280}
 281
 282static ssize_t select_engine_store(struct device *dev,
 283                             struct device_attribute *attr,
 284                             const char *buf, size_t len)
 285{
 286        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 287        struct lp55xx_chip *chip = led->chip;
 288        unsigned long val;
 289        int ret;
 290
 291        if (kstrtoul(buf, 0, &val))
 292                return -EINVAL;
 293
 294        /* select the engine to be run */
 295
 296        switch (val) {
 297        case LP55XX_ENGINE_1:
 298        case LP55XX_ENGINE_2:
 299        case LP55XX_ENGINE_3:
 300                mutex_lock(&chip->lock);
 301                chip->engine_idx = val;
 302                ret = lp55xx_request_firmware(chip);
 303                mutex_unlock(&chip->lock);
 304                break;
 305        default:
 306                dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val);
 307                return -EINVAL;
 308        }
 309
 310        if (ret) {
 311                dev_err(dev, "request firmware err: %d\n", ret);
 312                return ret;
 313        }
 314
 315        return len;
 316}
 317
 318static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start)
 319{
 320        if (chip->cfg->run_engine)
 321                chip->cfg->run_engine(chip, start);
 322}
 323
 324static ssize_t run_engine_store(struct device *dev,
 325                             struct device_attribute *attr,
 326                             const char *buf, size_t len)
 327{
 328        struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
 329        struct lp55xx_chip *chip = led->chip;
 330        unsigned long val;
 331
 332        if (kstrtoul(buf, 0, &val))
 333                return -EINVAL;
 334
 335        /* run or stop the selected engine */
 336
 337        if (val <= 0) {
 338                lp55xx_run_engine(chip, false);
 339                return len;
 340        }
 341
 342        mutex_lock(&chip->lock);
 343        lp55xx_run_engine(chip, true);
 344        mutex_unlock(&chip->lock);
 345
 346        return len;
 347}
 348
 349static DEVICE_ATTR_RW(select_engine);
 350static DEVICE_ATTR_WO(run_engine);
 351
 352static struct attribute *lp55xx_engine_attributes[] = {
 353        &dev_attr_select_engine.attr,
 354        &dev_attr_run_engine.attr,
 355        NULL,
 356};
 357
 358static const struct attribute_group lp55xx_engine_attr_group = {
 359        .attrs = lp55xx_engine_attributes,
 360};
 361
 362int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)
 363{
 364        return i2c_smbus_write_byte_data(chip->cl, reg, val);
 365}
 366EXPORT_SYMBOL_GPL(lp55xx_write);
 367
 368int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val)
 369{
 370        s32 ret;
 371
 372        ret = i2c_smbus_read_byte_data(chip->cl, reg);
 373        if (ret < 0)
 374                return ret;
 375
 376        *val = ret;
 377        return 0;
 378}
 379EXPORT_SYMBOL_GPL(lp55xx_read);
 380
 381int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)
 382{
 383        int ret;
 384        u8 tmp;
 385
 386        ret = lp55xx_read(chip, reg, &tmp);
 387        if (ret)
 388                return ret;
 389
 390        tmp &= ~mask;
 391        tmp |= val & mask;
 392
 393        return lp55xx_write(chip, reg, tmp);
 394}
 395EXPORT_SYMBOL_GPL(lp55xx_update_bits);
 396
 397bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)
 398{
 399        struct clk *clk;
 400        int err;
 401
 402        clk = devm_clk_get(&chip->cl->dev, "32k_clk");
 403        if (IS_ERR(clk))
 404                goto use_internal_clk;
 405
 406        err = clk_prepare_enable(clk);
 407        if (err)
 408                goto use_internal_clk;
 409
 410        if (clk_get_rate(clk) != LP55XX_CLK_32K) {
 411                clk_disable_unprepare(clk);
 412                goto use_internal_clk;
 413        }
 414
 415        dev_info(&chip->cl->dev, "%dHz external clock used\n",  LP55XX_CLK_32K);
 416
 417        chip->clk = clk;
 418        return true;
 419
 420use_internal_clk:
 421        dev_info(&chip->cl->dev, "internal clock used\n");
 422        return false;
 423}
 424EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
 425
 426int lp55xx_init_device(struct lp55xx_chip *chip)
 427{
 428        struct lp55xx_platform_data *pdata;
 429        struct lp55xx_device_config *cfg;
 430        struct device *dev = &chip->cl->dev;
 431        int ret = 0;
 432
 433        WARN_ON(!chip);
 434
 435        pdata = chip->pdata;
 436        cfg = chip->cfg;
 437
 438        if (!pdata || !cfg)
 439                return -EINVAL;
 440
 441        if (pdata->enable_gpiod) {
 442                gpiod_direction_output(pdata->enable_gpiod, 0);
 443
 444                gpiod_set_consumer_name(pdata->enable_gpiod, "LP55xx enable");
 445                gpiod_set_value(pdata->enable_gpiod, 0);
 446                usleep_range(1000, 2000); /* Keep enable down at least 1ms */
 447                gpiod_set_value(pdata->enable_gpiod, 1);
 448                usleep_range(1000, 2000); /* 500us abs min. */
 449        }
 450
 451        lp55xx_reset_device(chip);
 452
 453        /*
 454         * Exact value is not available. 10 - 20ms
 455         * appears to be enough for reset.
 456         */
 457        usleep_range(10000, 20000);
 458
 459        ret = lp55xx_detect_device(chip);
 460        if (ret) {
 461                dev_err(dev, "device detection err: %d\n", ret);
 462                goto err;
 463        }
 464
 465        /* chip specific initialization */
 466        ret = lp55xx_post_init_device(chip);
 467        if (ret) {
 468                dev_err(dev, "post init device err: %d\n", ret);
 469                goto err_post_init;
 470        }
 471
 472        return 0;
 473
 474err_post_init:
 475        lp55xx_deinit_device(chip);
 476err:
 477        return ret;
 478}
 479EXPORT_SYMBOL_GPL(lp55xx_init_device);
 480
 481void lp55xx_deinit_device(struct lp55xx_chip *chip)
 482{
 483        struct lp55xx_platform_data *pdata = chip->pdata;
 484
 485        if (chip->clk)
 486                clk_disable_unprepare(chip->clk);
 487
 488        if (pdata->enable_gpiod)
 489                gpiod_set_value(pdata->enable_gpiod, 0);
 490}
 491EXPORT_SYMBOL_GPL(lp55xx_deinit_device);
 492
 493int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)
 494{
 495        struct lp55xx_platform_data *pdata = chip->pdata;
 496        struct lp55xx_device_config *cfg = chip->cfg;
 497        int num_channels = pdata->num_channels;
 498        struct lp55xx_led *each;
 499        u8 led_current;
 500        int ret;
 501        int i;
 502
 503        if (!cfg->brightness_fn) {
 504                dev_err(&chip->cl->dev, "empty brightness configuration\n");
 505                return -EINVAL;
 506        }
 507
 508        for (i = 0; i < num_channels; i++) {
 509
 510                /* do not initialize channels that are not connected */
 511                if (pdata->led_config[i].led_current == 0)
 512                        continue;
 513
 514                led_current = pdata->led_config[i].led_current;
 515                each = led + i;
 516                ret = lp55xx_init_led(each, chip, i);
 517                if (ret)
 518                        goto err_init_led;
 519
 520                chip->num_leds++;
 521                each->chip = chip;
 522
 523                /* setting led current at each channel */
 524                if (cfg->set_led_current)
 525                        cfg->set_led_current(each, led_current);
 526        }
 527
 528        return 0;
 529
 530err_init_led:
 531        return ret;
 532}
 533EXPORT_SYMBOL_GPL(lp55xx_register_leds);
 534
 535int lp55xx_register_sysfs(struct lp55xx_chip *chip)
 536{
 537        struct device *dev = &chip->cl->dev;
 538        struct lp55xx_device_config *cfg = chip->cfg;
 539        int ret;
 540
 541        if (!cfg->run_engine || !cfg->firmware_cb)
 542                goto dev_specific_attrs;
 543
 544        ret = sysfs_create_group(&dev->kobj, &lp55xx_engine_attr_group);
 545        if (ret)
 546                return ret;
 547
 548dev_specific_attrs:
 549        return cfg->dev_attr_group ?
 550                sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0;
 551}
 552EXPORT_SYMBOL_GPL(lp55xx_register_sysfs);
 553
 554void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)
 555{
 556        struct device *dev = &chip->cl->dev;
 557        struct lp55xx_device_config *cfg = chip->cfg;
 558
 559        if (cfg->dev_attr_group)
 560                sysfs_remove_group(&dev->kobj, cfg->dev_attr_group);
 561
 562        sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group);
 563}
 564EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
 565
 566static int lp55xx_parse_common_child(struct device_node *np,
 567                                     struct lp55xx_led_config *cfg,
 568                                     int led_number, int *chan_nr)
 569{
 570        int ret;
 571
 572        of_property_read_string(np, "chan-name",
 573                                &cfg[led_number].name);
 574        of_property_read_u8(np, "led-cur",
 575                            &cfg[led_number].led_current);
 576        of_property_read_u8(np, "max-cur",
 577                            &cfg[led_number].max_current);
 578
 579        ret = of_property_read_u32(np, "reg", chan_nr);
 580        if (ret)
 581                return ret;
 582
 583        if (*chan_nr < 0 || *chan_nr > cfg->max_channel)
 584                return -EINVAL;
 585
 586        return 0;
 587}
 588
 589static int lp55xx_parse_multi_led_child(struct device_node *child,
 590                                         struct lp55xx_led_config *cfg,
 591                                         int child_number, int color_number)
 592{
 593        int chan_nr, color_id, ret;
 594
 595        ret = lp55xx_parse_common_child(child, cfg, child_number, &chan_nr);
 596        if (ret)
 597                return ret;
 598
 599        ret = of_property_read_u32(child, "color", &color_id);
 600        if (ret)
 601                return ret;
 602
 603        cfg[child_number].color_id[color_number] = color_id;
 604        cfg[child_number].output_num[color_number] = chan_nr;
 605
 606        return 0;
 607}
 608
 609static int lp55xx_parse_multi_led(struct device_node *np,
 610                                  struct lp55xx_led_config *cfg,
 611                                  int child_number)
 612{
 613        struct device_node *child;
 614        int num_colors = 0, ret;
 615
 616        for_each_available_child_of_node(np, child) {
 617                ret = lp55xx_parse_multi_led_child(child, cfg, child_number,
 618                                                   num_colors);
 619                if (ret) {
 620                        of_node_put(child);
 621                        return ret;
 622                }
 623                num_colors++;
 624        }
 625
 626        cfg[child_number].num_colors = num_colors;
 627
 628        return 0;
 629}
 630
 631static int lp55xx_parse_logical_led(struct device_node *np,
 632                                   struct lp55xx_led_config *cfg,
 633                                   int child_number)
 634{
 635        int led_color, ret;
 636        int chan_nr = 0;
 637
 638        cfg[child_number].default_trigger =
 639                of_get_property(np, "linux,default-trigger", NULL);
 640
 641        ret = of_property_read_u32(np, "color", &led_color);
 642        if (ret)
 643                return ret;
 644
 645        if (led_color == LED_COLOR_ID_RGB)
 646                return lp55xx_parse_multi_led(np, cfg, child_number);
 647
 648        ret =  lp55xx_parse_common_child(np, cfg, child_number, &chan_nr);
 649        if (ret < 0)
 650                return ret;
 651
 652        cfg[child_number].chan_nr = chan_nr;
 653
 654        return ret;
 655}
 656
 657struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
 658                                                      struct device_node *np,
 659                                                      struct lp55xx_chip *chip)
 660{
 661        struct device_node *child;
 662        struct lp55xx_platform_data *pdata;
 663        struct lp55xx_led_config *cfg;
 664        int num_channels;
 665        int i = 0;
 666        int ret;
 667
 668        pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 669        if (!pdata)
 670                return ERR_PTR(-ENOMEM);
 671
 672        num_channels = of_get_available_child_count(np);
 673        if (num_channels == 0) {
 674                dev_err(dev, "no LED channels\n");
 675                return ERR_PTR(-EINVAL);
 676        }
 677
 678        cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL);
 679        if (!cfg)
 680                return ERR_PTR(-ENOMEM);
 681
 682        pdata->led_config = &cfg[0];
 683        pdata->num_channels = num_channels;
 684        cfg->max_channel = chip->cfg->max_channel;
 685
 686        for_each_available_child_of_node(np, child) {
 687                ret = lp55xx_parse_logical_led(child, cfg, i);
 688                if (ret) {
 689                        of_node_put(child);
 690                        return ERR_PTR(-EINVAL);
 691                }
 692                i++;
 693        }
 694
 695        of_property_read_string(np, "label", &pdata->label);
 696        of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
 697
 698        pdata->enable_gpiod = devm_gpiod_get_optional(dev, "enable",
 699                                                      GPIOD_ASIS);
 700        if (IS_ERR(pdata->enable_gpiod))
 701                return ERR_CAST(pdata->enable_gpiod);
 702
 703        /* LP8501 specific */
 704        of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);
 705
 706        return pdata;
 707}
 708EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
 709
 710MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
 711MODULE_DESCRIPTION("LP55xx Common Driver");
 712MODULE_LICENSE("GPL");
 713