Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: sy7802: Add support for Silergy SY7802 flash LED controller

The SY7802 is a current-regulated charge pump which can regulate two
current levels for Flash and Torch modes.

It is a high-current synchronous boost converter with 2-channel high
side current sources. Each channel is able to deliver 900mA current.

Acked-by: Lee Jones <lee@kernel.org>
Signed-off-by: André Apitzsch <git@apitzsch.eu>
Link: https://lore.kernel.org/r/20240624-sy7802-v5-2-7abc9d96bfa6@apitzsch.eu
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

André Apitzsch and committed by
Lee Jones
c581f17a a5aff5da

+551
+11
drivers/leds/flash/Kconfig
··· 121 121 This option enables support for the SGM3140 500mA Buck/Boost Charge 122 122 Pump LED Driver. 123 123 124 + config LEDS_SY7802 125 + tristate "LED support for the Silergy SY7802" 126 + depends on I2C && OF 127 + depends on GPIOLIB 128 + select REGMAP_I2C 129 + help 130 + This option enables support for the SY7802 flash LED controller. 131 + SY7802 includes torch and flash functions with programmable current. 132 + 133 + This driver can be built as a module, it will be called "leds-sy7802". 134 + 124 135 endif # LEDS_CLASS_FLASH
+1
drivers/leds/flash/Makefile
··· 11 11 obj-$(CONFIG_LEDS_RT4505) += leds-rt4505.o 12 12 obj-$(CONFIG_LEDS_RT8515) += leds-rt8515.o 13 13 obj-$(CONFIG_LEDS_SGM3140) += leds-sgm3140.o 14 + obj-$(CONFIG_LEDS_SY7802) += leds-sy7802.o
+539
drivers/leds/flash/leds-sy7802.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Silergy SY7802 flash LED driver with an I2C interface 4 + * 5 + * Copyright 2024 André Apitzsch <git@apitzsch.eu> 6 + */ 7 + 8 + #include <linux/gpio/consumer.h> 9 + #include <linux/i2c.h> 10 + #include <linux/kernel.h> 11 + #include <linux/led-class-flash.h> 12 + #include <linux/module.h> 13 + #include <linux/mutex.h> 14 + #include <linux/regmap.h> 15 + #include <linux/regulator/consumer.h> 16 + 17 + #define SY7802_MAX_LEDS 2 18 + #define SY7802_LED_JOINT 2 19 + 20 + #define SY7802_REG_ENABLE 0x10 21 + #define SY7802_REG_TORCH_BRIGHTNESS 0xa0 22 + #define SY7802_REG_FLASH_BRIGHTNESS 0xb0 23 + #define SY7802_REG_FLASH_DURATION 0xc0 24 + #define SY7802_REG_FLAGS 0xd0 25 + #define SY7802_REG_CONFIG_1 0xe0 26 + #define SY7802_REG_CONFIG_2 0xf0 27 + #define SY7802_REG_VIN_MONITOR 0x80 28 + #define SY7802_REG_LAST_FLASH 0x81 29 + #define SY7802_REG_VLED_MONITOR 0x30 30 + #define SY7802_REG_ADC_DELAY 0x31 31 + #define SY7802_REG_DEV_ID 0xff 32 + 33 + #define SY7802_MODE_OFF 0 34 + #define SY7802_MODE_TORCH 2 35 + #define SY7802_MODE_FLASH 3 36 + #define SY7802_MODE_MASK GENMASK(1, 0) 37 + 38 + #define SY7802_LEDS_SHIFT 3 39 + #define SY7802_LEDS_MASK(_id) (BIT(_id) << SY7802_LEDS_SHIFT) 40 + #define SY7802_LEDS_MASK_ALL (SY7802_LEDS_MASK(0) | SY7802_LEDS_MASK(1)) 41 + 42 + #define SY7802_TORCH_CURRENT_SHIFT 3 43 + #define SY7802_TORCH_CURRENT_MASK(_id) \ 44 + (GENMASK(2, 0) << (SY7802_TORCH_CURRENT_SHIFT * (_id))) 45 + #define SY7802_TORCH_CURRENT_MASK_ALL \ 46 + (SY7802_TORCH_CURRENT_MASK(0) | SY7802_TORCH_CURRENT_MASK(1)) 47 + 48 + #define SY7802_FLASH_CURRENT_SHIFT 4 49 + #define SY7802_FLASH_CURRENT_MASK(_id) \ 50 + (GENMASK(3, 0) << (SY7802_FLASH_CURRENT_SHIFT * (_id))) 51 + #define SY7802_FLASH_CURRENT_MASK_ALL \ 52 + (SY7802_FLASH_CURRENT_MASK(0) | SY7802_FLASH_CURRENT_MASK(1)) 53 + 54 + #define SY7802_TIMEOUT_DEFAULT_US 512000U 55 + #define SY7802_TIMEOUT_MIN_US 32000U 56 + #define SY7802_TIMEOUT_MAX_US 1024000U 57 + #define SY7802_TIMEOUT_STEPSIZE_US 32000U 58 + 59 + #define SY7802_TORCH_BRIGHTNESS_MAX 8 60 + 61 + #define SY7802_FLASH_BRIGHTNESS_DEFAULT 14 62 + #define SY7802_FLASH_BRIGHTNESS_MIN 0 63 + #define SY7802_FLASH_BRIGHTNESS_MAX 15 64 + #define SY7802_FLASH_BRIGHTNESS_STEP 1 65 + 66 + #define SY7802_FLAG_TIMEOUT BIT(0) 67 + #define SY7802_FLAG_THERMAL_SHUTDOWN BIT(1) 68 + #define SY7802_FLAG_LED_FAULT BIT(2) 69 + #define SY7802_FLAG_TX1_INTERRUPT BIT(3) 70 + #define SY7802_FLAG_TX2_INTERRUPT BIT(4) 71 + #define SY7802_FLAG_LED_THERMAL_FAULT BIT(5) 72 + #define SY7802_FLAG_FLASH_INPUT_VOLTAGE_LOW BIT(6) 73 + #define SY7802_FLAG_INPUT_VOLTAGE_LOW BIT(7) 74 + 75 + #define SY7802_CHIP_ID 0x51 76 + 77 + static const struct reg_default sy7802_regmap_defs[] = { 78 + { SY7802_REG_ENABLE, SY7802_LEDS_MASK_ALL }, 79 + { SY7802_REG_TORCH_BRIGHTNESS, 0x92 }, 80 + { SY7802_REG_FLASH_BRIGHTNESS, SY7802_FLASH_BRIGHTNESS_DEFAULT | 81 + SY7802_FLASH_BRIGHTNESS_DEFAULT << SY7802_FLASH_CURRENT_SHIFT }, 82 + { SY7802_REG_FLASH_DURATION, 0x6f }, 83 + { SY7802_REG_FLAGS, 0x0 }, 84 + { SY7802_REG_CONFIG_1, 0x68 }, 85 + { SY7802_REG_CONFIG_2, 0xf0 }, 86 + }; 87 + 88 + struct sy7802_led { 89 + struct led_classdev_flash flash; 90 + struct sy7802 *chip; 91 + u8 led_id; 92 + }; 93 + 94 + struct sy7802 { 95 + struct device *dev; 96 + struct regmap *regmap; 97 + struct mutex mutex; 98 + 99 + struct gpio_desc *enable_gpio; 100 + struct regulator *vin_regulator; 101 + 102 + unsigned int fled_strobe_used; 103 + unsigned int fled_torch_used; 104 + unsigned int leds_active; 105 + int num_leds; 106 + struct sy7802_led leds[] __counted_by(num_leds); 107 + }; 108 + 109 + static int sy7802_torch_brightness_set(struct led_classdev *lcdev, enum led_brightness brightness) 110 + { 111 + struct sy7802_led *led = container_of(lcdev, struct sy7802_led, flash.led_cdev); 112 + struct sy7802 *chip = led->chip; 113 + u32 fled_torch_used_tmp; 114 + u32 led_enable_mask; 115 + u32 enable_mask; 116 + u32 torch_mask; 117 + u32 val; 118 + int ret; 119 + 120 + mutex_lock(&chip->mutex); 121 + 122 + if (chip->fled_strobe_used) { 123 + dev_warn(chip->dev, "Cannot set torch brightness whilst strobe is enabled\n"); 124 + ret = -EBUSY; 125 + goto unlock; 126 + } 127 + 128 + if (brightness) 129 + fled_torch_used_tmp = chip->fled_torch_used | BIT(led->led_id); 130 + else 131 + fled_torch_used_tmp = chip->fled_torch_used & ~BIT(led->led_id); 132 + 133 + led_enable_mask = led->led_id == SY7802_LED_JOINT ? 134 + SY7802_LEDS_MASK_ALL : 135 + SY7802_LEDS_MASK(led->led_id); 136 + 137 + val = brightness ? led_enable_mask : SY7802_MODE_OFF; 138 + if (fled_torch_used_tmp) 139 + val |= SY7802_MODE_TORCH; 140 + 141 + /* Disable torch to apply brightness */ 142 + ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, SY7802_MODE_MASK, 143 + SY7802_MODE_OFF); 144 + if (ret) 145 + goto unlock; 146 + 147 + torch_mask = led->led_id == SY7802_LED_JOINT ? 148 + SY7802_TORCH_CURRENT_MASK_ALL : 149 + SY7802_TORCH_CURRENT_MASK(led->led_id); 150 + 151 + /* Register expects brightness between 0 and MAX_BRIGHTNESS - 1 */ 152 + if (brightness) 153 + brightness -= 1; 154 + 155 + brightness |= (brightness << SY7802_TORCH_CURRENT_SHIFT); 156 + 157 + ret = regmap_update_bits(chip->regmap, SY7802_REG_TORCH_BRIGHTNESS, torch_mask, brightness); 158 + if (ret) 159 + goto unlock; 160 + 161 + enable_mask = SY7802_MODE_MASK | led_enable_mask; 162 + ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, enable_mask, val); 163 + if (ret) 164 + goto unlock; 165 + 166 + chip->fled_torch_used = fled_torch_used_tmp; 167 + 168 + unlock: 169 + mutex_unlock(&chip->mutex); 170 + return ret; 171 + } 172 + 173 + static int sy7802_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness) 174 + { 175 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 176 + struct led_flash_setting *s = &fl_cdev->brightness; 177 + u32 val = (brightness - s->min) / s->step; 178 + struct sy7802 *chip = led->chip; 179 + u32 flash_mask; 180 + int ret; 181 + 182 + val |= (val << SY7802_FLASH_CURRENT_SHIFT); 183 + flash_mask = led->led_id == SY7802_LED_JOINT ? 184 + SY7802_FLASH_CURRENT_MASK_ALL : 185 + SY7802_FLASH_CURRENT_MASK(led->led_id); 186 + 187 + mutex_lock(&chip->mutex); 188 + ret = regmap_update_bits(chip->regmap, SY7802_REG_FLASH_BRIGHTNESS, flash_mask, val); 189 + mutex_unlock(&chip->mutex); 190 + 191 + return ret; 192 + } 193 + 194 + static int sy7802_strobe_set(struct led_classdev_flash *fl_cdev, bool state) 195 + { 196 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 197 + struct sy7802 *chip = led->chip; 198 + u32 fled_strobe_used_tmp; 199 + u32 led_enable_mask; 200 + u32 enable_mask; 201 + u32 val; 202 + int ret; 203 + 204 + mutex_lock(&chip->mutex); 205 + 206 + if (chip->fled_torch_used) { 207 + dev_warn(chip->dev, "Cannot set strobe brightness whilst torch is enabled\n"); 208 + ret = -EBUSY; 209 + goto unlock; 210 + } 211 + 212 + if (state) 213 + fled_strobe_used_tmp = chip->fled_strobe_used | BIT(led->led_id); 214 + else 215 + fled_strobe_used_tmp = chip->fled_strobe_used & ~BIT(led->led_id); 216 + 217 + led_enable_mask = led->led_id == SY7802_LED_JOINT ? 218 + SY7802_LEDS_MASK_ALL : 219 + SY7802_LEDS_MASK(led->led_id); 220 + 221 + val = state ? led_enable_mask : SY7802_MODE_OFF; 222 + if (fled_strobe_used_tmp) 223 + val |= SY7802_MODE_FLASH; 224 + 225 + enable_mask = SY7802_MODE_MASK | led_enable_mask; 226 + ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, enable_mask, val); 227 + 228 + if (ret) 229 + goto unlock; 230 + 231 + chip->fled_strobe_used = fled_strobe_used_tmp; 232 + 233 + unlock: 234 + mutex_unlock(&chip->mutex); 235 + return ret; 236 + } 237 + 238 + static int sy7802_strobe_get(struct led_classdev_flash *fl_cdev, bool *state) 239 + { 240 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 241 + struct sy7802 *chip = led->chip; 242 + 243 + mutex_lock(&chip->mutex); 244 + *state = !!(chip->fled_strobe_used & BIT(led->led_id)); 245 + mutex_unlock(&chip->mutex); 246 + 247 + return 0; 248 + } 249 + 250 + static int sy7802_timeout_set(struct led_classdev_flash *fl_cdev, u32 timeout) 251 + { 252 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 253 + struct led_flash_setting *s = &fl_cdev->timeout; 254 + u32 val = (timeout - s->min) / s->step; 255 + struct sy7802 *chip = led->chip; 256 + 257 + return regmap_write(chip->regmap, SY7802_REG_FLASH_DURATION, val); 258 + } 259 + 260 + static int sy7802_fault_get(struct led_classdev_flash *fl_cdev, u32 *fault) 261 + { 262 + struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash); 263 + struct sy7802 *chip = led->chip; 264 + u32 val, led_faults = 0; 265 + int ret; 266 + 267 + /* NOTE: reading register clears fault status */ 268 + ret = regmap_read(chip->regmap, SY7802_REG_FLAGS, &val); 269 + if (ret) 270 + return ret; 271 + 272 + if (val & (SY7802_FLAG_FLASH_INPUT_VOLTAGE_LOW | SY7802_FLAG_INPUT_VOLTAGE_LOW)) 273 + led_faults |= LED_FAULT_INPUT_VOLTAGE; 274 + 275 + if (val & SY7802_FLAG_THERMAL_SHUTDOWN) 276 + led_faults |= LED_FAULT_OVER_TEMPERATURE; 277 + 278 + if (val & SY7802_FLAG_TIMEOUT) 279 + led_faults |= LED_FAULT_TIMEOUT; 280 + 281 + *fault = led_faults; 282 + return 0; 283 + } 284 + 285 + static const struct led_flash_ops sy7802_flash_ops = { 286 + .flash_brightness_set = sy7802_flash_brightness_set, 287 + .strobe_set = sy7802_strobe_set, 288 + .strobe_get = sy7802_strobe_get, 289 + .timeout_set = sy7802_timeout_set, 290 + .fault_get = sy7802_fault_get, 291 + }; 292 + 293 + static void sy7802_init_flash_brightness(struct led_classdev_flash *fl_cdev) 294 + { 295 + struct led_flash_setting *s; 296 + 297 + /* Init flash brightness setting */ 298 + s = &fl_cdev->brightness; 299 + s->min = SY7802_FLASH_BRIGHTNESS_MIN; 300 + s->max = SY7802_FLASH_BRIGHTNESS_MAX; 301 + s->step = SY7802_FLASH_BRIGHTNESS_STEP; 302 + s->val = SY7802_FLASH_BRIGHTNESS_DEFAULT; 303 + } 304 + 305 + static void sy7802_init_flash_timeout(struct led_classdev_flash *fl_cdev) 306 + { 307 + struct led_flash_setting *s; 308 + 309 + /* Init flash timeout setting */ 310 + s = &fl_cdev->timeout; 311 + s->min = SY7802_TIMEOUT_MIN_US; 312 + s->max = SY7802_TIMEOUT_MAX_US; 313 + s->step = SY7802_TIMEOUT_STEPSIZE_US; 314 + s->val = SY7802_TIMEOUT_DEFAULT_US; 315 + } 316 + 317 + static int sy7802_led_register(struct device *dev, struct sy7802_led *led, 318 + struct device_node *np) 319 + { 320 + struct led_init_data init_data = {}; 321 + int ret; 322 + 323 + init_data.fwnode = of_fwnode_handle(np); 324 + 325 + ret = devm_led_classdev_flash_register_ext(dev, &led->flash, &init_data); 326 + if (ret) { 327 + dev_err(dev, "Couldn't register flash %d\n", led->led_id); 328 + return ret; 329 + } 330 + 331 + return 0; 332 + } 333 + 334 + static int sy7802_init_flash_properties(struct device *dev, struct sy7802_led *led, 335 + struct device_node *np) 336 + { 337 + struct led_classdev_flash *flash = &led->flash; 338 + struct led_classdev *lcdev = &flash->led_cdev; 339 + u32 sources[SY7802_MAX_LEDS]; 340 + int i, num, ret; 341 + 342 + num = of_property_count_u32_elems(np, "led-sources"); 343 + if (num < 1) { 344 + dev_err(dev, "Not specified or wrong number of led-sources\n"); 345 + return -EINVAL; 346 + } 347 + 348 + ret = of_property_read_u32_array(np, "led-sources", sources, num); 349 + if (ret) 350 + return ret; 351 + 352 + for (i = 0; i < num; i++) { 353 + if (sources[i] >= SY7802_MAX_LEDS) 354 + return -EINVAL; 355 + if (led->chip->leds_active & BIT(sources[i])) 356 + return -EINVAL; 357 + led->chip->leds_active |= BIT(sources[i]); 358 + } 359 + 360 + /* If both channels are specified in 'led-sources', joint flash output mode is used */ 361 + led->led_id = num == 2 ? SY7802_LED_JOINT : sources[0]; 362 + 363 + lcdev->max_brightness = SY7802_TORCH_BRIGHTNESS_MAX; 364 + lcdev->brightness_set_blocking = sy7802_torch_brightness_set; 365 + lcdev->flags |= LED_DEV_CAP_FLASH; 366 + 367 + flash->ops = &sy7802_flash_ops; 368 + 369 + sy7802_init_flash_brightness(flash); 370 + sy7802_init_flash_timeout(flash); 371 + 372 + return 0; 373 + } 374 + 375 + static int sy7802_chip_check(struct sy7802 *chip) 376 + { 377 + struct device *dev = chip->dev; 378 + u32 chipid; 379 + int ret; 380 + 381 + ret = regmap_read(chip->regmap, SY7802_REG_DEV_ID, &chipid); 382 + if (ret) 383 + return dev_err_probe(dev, ret, "Failed to read chip ID\n"); 384 + 385 + if (chipid != SY7802_CHIP_ID) 386 + return dev_err_probe(dev, -ENODEV, "Unsupported chip detected: %x\n", chipid); 387 + 388 + return 0; 389 + } 390 + 391 + static void sy7802_enable(struct sy7802 *chip) 392 + { 393 + gpiod_set_value_cansleep(chip->enable_gpio, 1); 394 + usleep_range(200, 300); 395 + } 396 + 397 + static void sy7802_disable(struct sy7802 *chip) 398 + { 399 + gpiod_set_value_cansleep(chip->enable_gpio, 0); 400 + } 401 + 402 + static int sy7802_probe_dt(struct sy7802 *chip) 403 + { 404 + struct device_node *np = dev_of_node(chip->dev); 405 + int child_num; 406 + int ret; 407 + 408 + regmap_write(chip->regmap, SY7802_REG_ENABLE, SY7802_MODE_OFF); 409 + regmap_write(chip->regmap, SY7802_REG_TORCH_BRIGHTNESS, LED_OFF); 410 + 411 + child_num = 0; 412 + for_each_available_child_of_node_scoped(np, child) { 413 + struct sy7802_led *led = chip->leds + child_num; 414 + 415 + led->chip = chip; 416 + led->led_id = child_num; 417 + 418 + ret = sy7802_init_flash_properties(chip->dev, led, child); 419 + if (ret) 420 + return ret; 421 + 422 + ret = sy7802_led_register(chip->dev, led, child); 423 + if (ret) 424 + return ret; 425 + 426 + child_num++; 427 + } 428 + return 0; 429 + } 430 + 431 + static void sy7802_chip_disable_action(void *data) 432 + { 433 + struct sy7802 *chip = data; 434 + 435 + sy7802_disable(chip); 436 + } 437 + 438 + static void sy7802_regulator_disable_action(void *data) 439 + { 440 + struct sy7802 *chip = data; 441 + 442 + regulator_disable(chip->vin_regulator); 443 + } 444 + 445 + static const struct regmap_config sy7802_regmap_config = { 446 + .reg_bits = 8, 447 + .val_bits = 8, 448 + .max_register = 0xff, 449 + .cache_type = REGCACHE_MAPLE, 450 + .reg_defaults = sy7802_regmap_defs, 451 + .num_reg_defaults = ARRAY_SIZE(sy7802_regmap_defs), 452 + }; 453 + 454 + static int sy7802_probe(struct i2c_client *client) 455 + { 456 + struct device *dev = &client->dev; 457 + struct sy7802 *chip; 458 + size_t count; 459 + int ret; 460 + 461 + count = device_get_child_node_count(dev); 462 + if (!count || count > SY7802_MAX_LEDS) 463 + return dev_err_probe(dev, -EINVAL, "Invalid amount of LED nodes %zu\n", count); 464 + 465 + chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL); 466 + if (!chip) 467 + return -ENOMEM; 468 + 469 + chip->num_leds = count; 470 + 471 + chip->dev = dev; 472 + i2c_set_clientdata(client, chip); 473 + 474 + chip->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 475 + ret = PTR_ERR_OR_ZERO(chip->enable_gpio); 476 + if (ret) 477 + return dev_err_probe(dev, ret, "Failed to request enable gpio\n"); 478 + 479 + chip->vin_regulator = devm_regulator_get(dev, "vin"); 480 + ret = PTR_ERR_OR_ZERO(chip->vin_regulator); 481 + if (ret) 482 + return dev_err_probe(dev, ret, "Failed to request regulator\n"); 483 + 484 + ret = regulator_enable(chip->vin_regulator); 485 + if (ret) 486 + return dev_err_probe(dev, ret, "Failed to enable regulator\n"); 487 + 488 + ret = devm_add_action_or_reset(dev, sy7802_regulator_disable_action, chip); 489 + if (ret) 490 + return ret; 491 + 492 + ret = devm_mutex_init(dev, &chip->mutex); 493 + if (ret) 494 + return ret; 495 + 496 + mutex_lock(&chip->mutex); 497 + 498 + chip->regmap = devm_regmap_init_i2c(client, &sy7802_regmap_config); 499 + if (IS_ERR(chip->regmap)) { 500 + ret = PTR_ERR(chip->regmap); 501 + dev_err_probe(dev, ret, "Failed to allocate register map\n"); 502 + goto error; 503 + } 504 + 505 + ret = sy7802_probe_dt(chip); 506 + if (ret < 0) 507 + goto error; 508 + 509 + sy7802_enable(chip); 510 + 511 + ret = devm_add_action_or_reset(dev, sy7802_chip_disable_action, chip); 512 + if (ret) 513 + goto error; 514 + 515 + ret = sy7802_chip_check(chip); 516 + 517 + error: 518 + mutex_unlock(&chip->mutex); 519 + return ret; 520 + } 521 + 522 + static const struct of_device_id __maybe_unused sy7802_leds_match[] = { 523 + { .compatible = "silergy,sy7802", }, 524 + {} 525 + }; 526 + MODULE_DEVICE_TABLE(of, sy7802_leds_match); 527 + 528 + static struct i2c_driver sy7802_driver = { 529 + .driver = { 530 + .name = "sy7802", 531 + .of_match_table = of_match_ptr(sy7802_leds_match), 532 + }, 533 + .probe = sy7802_probe, 534 + }; 535 + module_i2c_driver(sy7802_driver); 536 + 537 + MODULE_AUTHOR("André Apitzsch <git@apitzsch.eu>"); 538 + MODULE_DESCRIPTION("Silergy SY7802 flash LED driver"); 539 + MODULE_LICENSE("GPL");