Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * leds-lm3533.c -- LM3533 LED driver
0004  *
0005  * Copyright (C) 2011-2012 Texas Instruments
0006  *
0007  * Author: Johan Hovold <jhovold@gmail.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/leds.h>
0012 #include <linux/mfd/core.h>
0013 #include <linux/mutex.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016 
0017 #include <linux/mfd/lm3533.h>
0018 
0019 
0020 #define LM3533_LVCTRLBANK_MIN       2
0021 #define LM3533_LVCTRLBANK_MAX       5
0022 #define LM3533_LVCTRLBANK_COUNT     4
0023 #define LM3533_RISEFALLTIME_MAX     7
0024 #define LM3533_ALS_CHANNEL_LV_MIN   1
0025 #define LM3533_ALS_CHANNEL_LV_MAX   2
0026 
0027 #define LM3533_REG_CTRLBANK_BCONF_BASE      0x1b
0028 #define LM3533_REG_PATTERN_ENABLE       0x28
0029 #define LM3533_REG_PATTERN_LOW_TIME_BASE    0x71
0030 #define LM3533_REG_PATTERN_HIGH_TIME_BASE   0x72
0031 #define LM3533_REG_PATTERN_RISETIME_BASE    0x74
0032 #define LM3533_REG_PATTERN_FALLTIME_BASE    0x75
0033 
0034 #define LM3533_REG_PATTERN_STEP         0x10
0035 
0036 #define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK      0x04
0037 #define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK       0x02
0038 #define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK  0x01
0039 
0040 #define LM3533_LED_FLAG_PATTERN_ENABLE      1
0041 
0042 
0043 struct lm3533_led {
0044     struct lm3533 *lm3533;
0045     struct lm3533_ctrlbank cb;
0046     struct led_classdev cdev;
0047     int id;
0048 
0049     struct mutex mutex;
0050     unsigned long flags;
0051 };
0052 
0053 
0054 static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev)
0055 {
0056     return container_of(cdev, struct lm3533_led, cdev);
0057 }
0058 
0059 static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led)
0060 {
0061     return led->id + 2;
0062 }
0063 
0064 static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base)
0065 {
0066     return base + led->id;
0067 }
0068 
0069 static inline u8 lm3533_led_get_pattern(struct lm3533_led *led)
0070 {
0071     return led->id;
0072 }
0073 
0074 static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led,
0075                                 u8 base)
0076 {
0077     return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP;
0078 }
0079 
0080 static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
0081 {
0082     u8 mask;
0083     u8 val;
0084     int pattern;
0085     int state;
0086     int ret = 0;
0087 
0088     dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable);
0089 
0090     mutex_lock(&led->mutex);
0091 
0092     state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
0093     if ((enable && state) || (!enable && !state))
0094         goto out;
0095 
0096     pattern = lm3533_led_get_pattern(led);
0097     mask = 1 << (2 * pattern);
0098 
0099     if (enable)
0100         val = mask;
0101     else
0102         val = 0;
0103 
0104     ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask);
0105     if (ret) {
0106         dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n",
0107                             pattern, enable);
0108         goto out;
0109     }
0110 
0111     __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
0112 out:
0113     mutex_unlock(&led->mutex);
0114 
0115     return ret;
0116 }
0117 
0118 static int lm3533_led_set(struct led_classdev *cdev,
0119                         enum led_brightness value)
0120 {
0121     struct lm3533_led *led = to_lm3533_led(cdev);
0122 
0123     dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value);
0124 
0125     if (value == 0)
0126         lm3533_led_pattern_enable(led, 0);  /* disable blink */
0127 
0128     return lm3533_ctrlbank_set_brightness(&led->cb, value);
0129 }
0130 
0131 static enum led_brightness lm3533_led_get(struct led_classdev *cdev)
0132 {
0133     struct lm3533_led *led = to_lm3533_led(cdev);
0134     u8 val;
0135     int ret;
0136 
0137     ret = lm3533_ctrlbank_get_brightness(&led->cb, &val);
0138     if (ret)
0139         return ret;
0140 
0141     dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val);
0142 
0143     return val;
0144 }
0145 
0146 /* Pattern generator defines (delays in us). */
0147 #define LM3533_LED_DELAY1_VMIN  0x00
0148 #define LM3533_LED_DELAY2_VMIN  0x3d
0149 #define LM3533_LED_DELAY3_VMIN  0x80
0150 
0151 #define LM3533_LED_DELAY1_VMAX  (LM3533_LED_DELAY2_VMIN - 1)
0152 #define LM3533_LED_DELAY2_VMAX  (LM3533_LED_DELAY3_VMIN - 1)
0153 #define LM3533_LED_DELAY3_VMAX  0xff
0154 
0155 #define LM3533_LED_DELAY1_TMIN  16384U
0156 #define LM3533_LED_DELAY2_TMIN  1130496U
0157 #define LM3533_LED_DELAY3_TMIN  10305536U
0158 
0159 #define LM3533_LED_DELAY1_TMAX  999424U
0160 #define LM3533_LED_DELAY2_TMAX  9781248U
0161 #define LM3533_LED_DELAY3_TMAX  76890112U
0162 
0163 /* t_step = (t_max - t_min) / (v_max - v_min) */
0164 #define LM3533_LED_DELAY1_TSTEP 16384
0165 #define LM3533_LED_DELAY2_TSTEP 131072
0166 #define LM3533_LED_DELAY3_TSTEP 524288
0167 
0168 /* Delay limits for hardware accelerated blinking (in ms). */
0169 #define LM3533_LED_DELAY_ON_MAX \
0170     ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000)
0171 #define LM3533_LED_DELAY_OFF_MAX \
0172     ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000)
0173 
0174 /*
0175  * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step
0176  * size of t_step, where
0177  *
0178  *  t_step = (t_max - t_min) / (v_max - v_min)
0179  *
0180  * and updates *t to reflect the mapped value.
0181  */
0182 static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step,
0183                             u8 v_min, u8 v_max)
0184 {
0185     unsigned val;
0186 
0187     val = (*t + t_step / 2 - t_min) / t_step + v_min;
0188 
0189     *t = t_step * (val - v_min) + t_min;
0190 
0191     return (u8)val;
0192 }
0193 
0194 /*
0195  * Returns time code corresponding to *delay (in ms) and updates *delay to
0196  * reflect actual hardware delay.
0197  *
0198  * Hardware supports 256 discrete delay times, divided into three groups with
0199  * the following ranges and step-sizes:
0200  *
0201  *  [   16,   999]  [0x00, 0x3e]    step  16 ms
0202  *  [ 1130,  9781]  [0x3d, 0x7f]    step 131 ms
0203  *  [10306, 76890]  [0x80, 0xff]    step 524 ms
0204  *
0205  * Note that delay group 3 is only available for delay_off.
0206  */
0207 static u8 lm3533_led_get_hw_delay(unsigned *delay)
0208 {
0209     unsigned t;
0210     u8 val;
0211 
0212     t = *delay * 1000;
0213 
0214     if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) {
0215         t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX);
0216         val = time_to_val(&t,   LM3533_LED_DELAY3_TMIN,
0217                     LM3533_LED_DELAY3_TSTEP,
0218                     LM3533_LED_DELAY3_VMIN,
0219                     LM3533_LED_DELAY3_VMAX);
0220     } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) {
0221         t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX);
0222         val = time_to_val(&t,   LM3533_LED_DELAY2_TMIN,
0223                     LM3533_LED_DELAY2_TSTEP,
0224                     LM3533_LED_DELAY2_VMIN,
0225                     LM3533_LED_DELAY2_VMAX);
0226     } else {
0227         t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX);
0228         val = time_to_val(&t,   LM3533_LED_DELAY1_TMIN,
0229                     LM3533_LED_DELAY1_TSTEP,
0230                     LM3533_LED_DELAY1_VMIN,
0231                     LM3533_LED_DELAY1_VMAX);
0232     }
0233 
0234     *delay = (t + 500) / 1000;
0235 
0236     return val;
0237 }
0238 
0239 /*
0240  * Set delay register base to *delay (in ms) and update *delay to reflect
0241  * actual hardware delay used.
0242  */
0243 static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base,
0244                             unsigned long *delay)
0245 {
0246     unsigned t;
0247     u8 val;
0248     u8 reg;
0249     int ret;
0250 
0251     t = (unsigned)*delay;
0252 
0253     /* Delay group 3 is only available for low time (delay off). */
0254     if (base != LM3533_REG_PATTERN_LOW_TIME_BASE)
0255         t = min(t, LM3533_LED_DELAY2_TMAX / 1000);
0256 
0257     val = lm3533_led_get_hw_delay(&t);
0258 
0259     dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__,
0260                             *delay, t, val);
0261     reg = lm3533_led_get_pattern_reg(led, base);
0262     ret = lm3533_write(led->lm3533, reg, val);
0263     if (ret)
0264         dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
0265 
0266     *delay = t;
0267 
0268     return ret;
0269 }
0270 
0271 static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t)
0272 {
0273     return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t);
0274 }
0275 
0276 static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t)
0277 {
0278     return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t);
0279 }
0280 
0281 static int lm3533_led_blink_set(struct led_classdev *cdev,
0282                 unsigned long *delay_on,
0283                 unsigned long *delay_off)
0284 {
0285     struct lm3533_led *led = to_lm3533_led(cdev);
0286     int ret;
0287 
0288     dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__,
0289                             *delay_on, *delay_off);
0290 
0291     if (*delay_on > LM3533_LED_DELAY_ON_MAX ||
0292                     *delay_off > LM3533_LED_DELAY_OFF_MAX)
0293         return -EINVAL;
0294 
0295     if (*delay_on == 0 && *delay_off == 0) {
0296         *delay_on = 500;
0297         *delay_off = 500;
0298     }
0299 
0300     ret = lm3533_led_delay_on_set(led, delay_on);
0301     if (ret)
0302         return ret;
0303 
0304     ret = lm3533_led_delay_off_set(led, delay_off);
0305     if (ret)
0306         return ret;
0307 
0308     return lm3533_led_pattern_enable(led, 1);
0309 }
0310 
0311 static ssize_t show_id(struct device *dev,
0312                 struct device_attribute *attr, char *buf)
0313 {
0314     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0315     struct lm3533_led *led = to_lm3533_led(led_cdev);
0316 
0317     return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
0318 }
0319 
0320 /*
0321  * Pattern generator rise/fall times:
0322  *
0323  *   0 - 2048 us (default)
0324  *   1 - 262 ms
0325  *   2 - 524 ms
0326  *   3 - 1.049 s
0327  *   4 - 2.097 s
0328  *   5 - 4.194 s
0329  *   6 - 8.389 s
0330  *   7 - 16.78 s
0331  */
0332 static ssize_t show_risefalltime(struct device *dev,
0333                     struct device_attribute *attr,
0334                     char *buf, u8 base)
0335 {
0336     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0337     struct lm3533_led *led = to_lm3533_led(led_cdev);
0338     ssize_t ret;
0339     u8 reg;
0340     u8 val;
0341 
0342     reg = lm3533_led_get_pattern_reg(led, base);
0343     ret = lm3533_read(led->lm3533, reg, &val);
0344     if (ret)
0345         return ret;
0346 
0347     return scnprintf(buf, PAGE_SIZE, "%x\n", val);
0348 }
0349 
0350 static ssize_t show_risetime(struct device *dev,
0351                 struct device_attribute *attr, char *buf)
0352 {
0353     return show_risefalltime(dev, attr, buf,
0354                     LM3533_REG_PATTERN_RISETIME_BASE);
0355 }
0356 
0357 static ssize_t show_falltime(struct device *dev,
0358                 struct device_attribute *attr, char *buf)
0359 {
0360     return show_risefalltime(dev, attr, buf,
0361                     LM3533_REG_PATTERN_FALLTIME_BASE);
0362 }
0363 
0364 static ssize_t store_risefalltime(struct device *dev,
0365                     struct device_attribute *attr,
0366                     const char *buf, size_t len, u8 base)
0367 {
0368     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0369     struct lm3533_led *led = to_lm3533_led(led_cdev);
0370     u8 val;
0371     u8 reg;
0372     int ret;
0373 
0374     if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX)
0375         return -EINVAL;
0376 
0377     reg = lm3533_led_get_pattern_reg(led, base);
0378     ret = lm3533_write(led->lm3533, reg, val);
0379     if (ret)
0380         return ret;
0381 
0382     return len;
0383 }
0384 
0385 static ssize_t store_risetime(struct device *dev,
0386                     struct device_attribute *attr,
0387                     const char *buf, size_t len)
0388 {
0389     return store_risefalltime(dev, attr, buf, len,
0390                     LM3533_REG_PATTERN_RISETIME_BASE);
0391 }
0392 
0393 static ssize_t store_falltime(struct device *dev,
0394                     struct device_attribute *attr,
0395                     const char *buf, size_t len)
0396 {
0397     return store_risefalltime(dev, attr, buf, len,
0398                     LM3533_REG_PATTERN_FALLTIME_BASE);
0399 }
0400 
0401 static ssize_t show_als_channel(struct device *dev,
0402                 struct device_attribute *attr, char *buf)
0403 {
0404     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0405     struct lm3533_led *led = to_lm3533_led(led_cdev);
0406     unsigned channel;
0407     u8 reg;
0408     u8 val;
0409     int ret;
0410 
0411     reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
0412     ret = lm3533_read(led->lm3533, reg, &val);
0413     if (ret)
0414         return ret;
0415 
0416     channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
0417 
0418     return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
0419 }
0420 
0421 static ssize_t store_als_channel(struct device *dev,
0422                     struct device_attribute *attr,
0423                     const char *buf, size_t len)
0424 {
0425     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0426     struct lm3533_led *led = to_lm3533_led(led_cdev);
0427     unsigned channel;
0428     u8 reg;
0429     u8 val;
0430     u8 mask;
0431     int ret;
0432 
0433     if (kstrtouint(buf, 0, &channel))
0434         return -EINVAL;
0435 
0436     if (channel < LM3533_ALS_CHANNEL_LV_MIN ||
0437                     channel > LM3533_ALS_CHANNEL_LV_MAX)
0438         return -EINVAL;
0439 
0440     reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
0441     mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK;
0442     val = channel - 1;
0443 
0444     ret = lm3533_update(led->lm3533, reg, val, mask);
0445     if (ret)
0446         return ret;
0447 
0448     return len;
0449 }
0450 
0451 static ssize_t show_als_en(struct device *dev,
0452                 struct device_attribute *attr, char *buf)
0453 {
0454     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0455     struct lm3533_led *led = to_lm3533_led(led_cdev);
0456     bool enable;
0457     u8 reg;
0458     u8 val;
0459     int ret;
0460 
0461     reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
0462     ret = lm3533_read(led->lm3533, reg, &val);
0463     if (ret)
0464         return ret;
0465 
0466     enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
0467 
0468     return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
0469 }
0470 
0471 static ssize_t store_als_en(struct device *dev,
0472                     struct device_attribute *attr,
0473                     const char *buf, size_t len)
0474 {
0475     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0476     struct lm3533_led *led = to_lm3533_led(led_cdev);
0477     unsigned enable;
0478     u8 reg;
0479     u8 mask;
0480     u8 val;
0481     int ret;
0482 
0483     if (kstrtouint(buf, 0, &enable))
0484         return -EINVAL;
0485 
0486     reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
0487     mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
0488 
0489     if (enable)
0490         val = mask;
0491     else
0492         val = 0;
0493 
0494     ret = lm3533_update(led->lm3533, reg, val, mask);
0495     if (ret)
0496         return ret;
0497 
0498     return len;
0499 }
0500 
0501 static ssize_t show_linear(struct device *dev,
0502                 struct device_attribute *attr, char *buf)
0503 {
0504     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0505     struct lm3533_led *led = to_lm3533_led(led_cdev);
0506     u8 reg;
0507     u8 val;
0508     int linear;
0509     int ret;
0510 
0511     reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
0512     ret = lm3533_read(led->lm3533, reg, &val);
0513     if (ret)
0514         return ret;
0515 
0516     if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK)
0517         linear = 1;
0518     else
0519         linear = 0;
0520 
0521     return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
0522 }
0523 
0524 static ssize_t store_linear(struct device *dev,
0525                     struct device_attribute *attr,
0526                     const char *buf, size_t len)
0527 {
0528     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0529     struct lm3533_led *led = to_lm3533_led(led_cdev);
0530     unsigned long linear;
0531     u8 reg;
0532     u8 mask;
0533     u8 val;
0534     int ret;
0535 
0536     if (kstrtoul(buf, 0, &linear))
0537         return -EINVAL;
0538 
0539     reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
0540     mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK;
0541 
0542     if (linear)
0543         val = mask;
0544     else
0545         val = 0;
0546 
0547     ret = lm3533_update(led->lm3533, reg, val, mask);
0548     if (ret)
0549         return ret;
0550 
0551     return len;
0552 }
0553 
0554 static ssize_t show_pwm(struct device *dev,
0555                     struct device_attribute *attr,
0556                     char *buf)
0557 {
0558     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0559     struct lm3533_led *led = to_lm3533_led(led_cdev);
0560     u8 val;
0561     int ret;
0562 
0563     ret = lm3533_ctrlbank_get_pwm(&led->cb, &val);
0564     if (ret)
0565         return ret;
0566 
0567     return scnprintf(buf, PAGE_SIZE, "%u\n", val);
0568 }
0569 
0570 static ssize_t store_pwm(struct device *dev,
0571                     struct device_attribute *attr,
0572                     const char *buf, size_t len)
0573 {
0574     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0575     struct lm3533_led *led = to_lm3533_led(led_cdev);
0576     u8 val;
0577     int ret;
0578 
0579     if (kstrtou8(buf, 0, &val))
0580         return -EINVAL;
0581 
0582     ret = lm3533_ctrlbank_set_pwm(&led->cb, val);
0583     if (ret)
0584         return ret;
0585 
0586     return len;
0587 }
0588 
0589 static LM3533_ATTR_RW(als_channel);
0590 static LM3533_ATTR_RW(als_en);
0591 static LM3533_ATTR_RW(falltime);
0592 static LM3533_ATTR_RO(id);
0593 static LM3533_ATTR_RW(linear);
0594 static LM3533_ATTR_RW(pwm);
0595 static LM3533_ATTR_RW(risetime);
0596 
0597 static struct attribute *lm3533_led_attributes[] = {
0598     &dev_attr_als_channel.attr,
0599     &dev_attr_als_en.attr,
0600     &dev_attr_falltime.attr,
0601     &dev_attr_id.attr,
0602     &dev_attr_linear.attr,
0603     &dev_attr_pwm.attr,
0604     &dev_attr_risetime.attr,
0605     NULL,
0606 };
0607 
0608 static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
0609                          struct attribute *attr, int n)
0610 {
0611     struct device *dev = kobj_to_dev(kobj);
0612     struct led_classdev *led_cdev = dev_get_drvdata(dev);
0613     struct lm3533_led *led = to_lm3533_led(led_cdev);
0614     umode_t mode = attr->mode;
0615 
0616     if (attr == &dev_attr_als_channel.attr ||
0617                     attr == &dev_attr_als_en.attr) {
0618         if (!led->lm3533->have_als)
0619             mode = 0;
0620     }
0621 
0622     return mode;
0623 };
0624 
0625 static const struct attribute_group lm3533_led_attribute_group = {
0626     .is_visible = lm3533_led_attr_is_visible,
0627     .attrs      = lm3533_led_attributes
0628 };
0629 
0630 static const struct attribute_group *lm3533_led_attribute_groups[] = {
0631     &lm3533_led_attribute_group,
0632     NULL
0633 };
0634 
0635 static int lm3533_led_setup(struct lm3533_led *led,
0636                     struct lm3533_led_platform_data *pdata)
0637 {
0638     int ret;
0639 
0640     ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
0641     if (ret)
0642         return ret;
0643 
0644     return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
0645 }
0646 
0647 static int lm3533_led_probe(struct platform_device *pdev)
0648 {
0649     struct lm3533 *lm3533;
0650     struct lm3533_led_platform_data *pdata;
0651     struct lm3533_led *led;
0652     int ret;
0653 
0654     dev_dbg(&pdev->dev, "%s\n", __func__);
0655 
0656     lm3533 = dev_get_drvdata(pdev->dev.parent);
0657     if (!lm3533)
0658         return -EINVAL;
0659 
0660     pdata = dev_get_platdata(&pdev->dev);
0661     if (!pdata) {
0662         dev_err(&pdev->dev, "no platform data\n");
0663         return -EINVAL;
0664     }
0665 
0666     if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
0667         dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
0668         return -EINVAL;
0669     }
0670 
0671     led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
0672     if (!led)
0673         return -ENOMEM;
0674 
0675     led->lm3533 = lm3533;
0676     led->cdev.name = pdata->name;
0677     led->cdev.default_trigger = pdata->default_trigger;
0678     led->cdev.brightness_set_blocking = lm3533_led_set;
0679     led->cdev.brightness_get = lm3533_led_get;
0680     led->cdev.blink_set = lm3533_led_blink_set;
0681     led->cdev.brightness = LED_OFF;
0682     led->cdev.groups = lm3533_led_attribute_groups;
0683     led->id = pdev->id;
0684 
0685     mutex_init(&led->mutex);
0686 
0687     /* The class framework makes a callback to get brightness during
0688      * registration so use parent device (for error reporting) until
0689      * registered.
0690      */
0691     led->cb.lm3533 = lm3533;
0692     led->cb.id = lm3533_led_get_ctrlbank_id(led);
0693     led->cb.dev = lm3533->dev;
0694 
0695     platform_set_drvdata(pdev, led);
0696 
0697     ret = led_classdev_register(pdev->dev.parent, &led->cdev);
0698     if (ret) {
0699         dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
0700         return ret;
0701     }
0702 
0703     led->cb.dev = led->cdev.dev;
0704 
0705     ret = lm3533_led_setup(led, pdata);
0706     if (ret)
0707         goto err_deregister;
0708 
0709     ret = lm3533_ctrlbank_enable(&led->cb);
0710     if (ret)
0711         goto err_deregister;
0712 
0713     return 0;
0714 
0715 err_deregister:
0716     led_classdev_unregister(&led->cdev);
0717 
0718     return ret;
0719 }
0720 
0721 static int lm3533_led_remove(struct platform_device *pdev)
0722 {
0723     struct lm3533_led *led = platform_get_drvdata(pdev);
0724 
0725     dev_dbg(&pdev->dev, "%s\n", __func__);
0726 
0727     lm3533_ctrlbank_disable(&led->cb);
0728     led_classdev_unregister(&led->cdev);
0729 
0730     return 0;
0731 }
0732 
0733 static void lm3533_led_shutdown(struct platform_device *pdev)
0734 {
0735 
0736     struct lm3533_led *led = platform_get_drvdata(pdev);
0737 
0738     dev_dbg(&pdev->dev, "%s\n", __func__);
0739 
0740     lm3533_ctrlbank_disable(&led->cb);
0741     lm3533_led_set(&led->cdev, LED_OFF);        /* disable blink */
0742 }
0743 
0744 static struct platform_driver lm3533_led_driver = {
0745     .driver = {
0746         .name = "lm3533-leds",
0747     },
0748     .probe      = lm3533_led_probe,
0749     .remove     = lm3533_led_remove,
0750     .shutdown   = lm3533_led_shutdown,
0751 };
0752 module_platform_driver(lm3533_led_driver);
0753 
0754 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
0755 MODULE_DESCRIPTION("LM3533 LED driver");
0756 MODULE_LICENSE("GPL");
0757 MODULE_ALIAS("platform:lm3533-leds");