cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

leds-lp5521.c (15741B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * LP5521 LED chip driver.
      4 *
      5 * Copyright (C) 2010 Nokia Corporation
      6 * Copyright (C) 2012 Texas Instruments
      7 *
      8 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
      9 *          Milo(Woogyom) Kim <milo.kim@ti.com>
     10 */
     11
     12#include <linux/delay.h>
     13#include <linux/firmware.h>
     14#include <linux/i2c.h>
     15#include <linux/leds.h>
     16#include <linux/module.h>
     17#include <linux/mutex.h>
     18#include <linux/platform_data/leds-lp55xx.h>
     19#include <linux/slab.h>
     20#include <linux/of.h>
     21
     22#include "leds-lp55xx-common.h"
     23
     24#define LP5521_PROGRAM_LENGTH		32
     25#define LP5521_MAX_LEDS			3
     26#define LP5521_CMD_DIRECT		0x3F
     27
     28/* Registers */
     29#define LP5521_REG_ENABLE		0x00
     30#define LP5521_REG_OP_MODE		0x01
     31#define LP5521_REG_R_PWM		0x02
     32#define LP5521_REG_G_PWM		0x03
     33#define LP5521_REG_B_PWM		0x04
     34#define LP5521_REG_R_CURRENT		0x05
     35#define LP5521_REG_G_CURRENT		0x06
     36#define LP5521_REG_B_CURRENT		0x07
     37#define LP5521_REG_CONFIG		0x08
     38#define LP5521_REG_STATUS		0x0C
     39#define LP5521_REG_RESET		0x0D
     40#define LP5521_REG_R_PROG_MEM		0x10
     41#define LP5521_REG_G_PROG_MEM		0x30
     42#define LP5521_REG_B_PROG_MEM		0x50
     43
     44/* Base register to set LED current */
     45#define LP5521_REG_LED_CURRENT_BASE	LP5521_REG_R_CURRENT
     46/* Base register to set the brightness */
     47#define LP5521_REG_LED_PWM_BASE		LP5521_REG_R_PWM
     48
     49/* Bits in ENABLE register */
     50#define LP5521_MASTER_ENABLE		0x40	/* Chip master enable */
     51#define LP5521_LOGARITHMIC_PWM		0x80	/* Logarithmic PWM adjustment */
     52#define LP5521_EXEC_RUN			0x2A
     53#define LP5521_ENABLE_DEFAULT	\
     54	(LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)
     55#define LP5521_ENABLE_RUN_PROGRAM	\
     56	(LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
     57
     58/* CONFIG register */
     59#define LP5521_PWM_HF			0x40	/* PWM: 0 = 256Hz, 1 = 558Hz */
     60#define LP5521_PWRSAVE_EN		0x20	/* 1 = Power save mode */
     61#define LP5521_CP_MODE_OFF		0	/* Charge pump (CP) off */
     62#define LP5521_CP_MODE_BYPASS		8	/* CP forced to bypass mode */
     63#define LP5521_CP_MODE_1X5		0x10	/* CP forced to 1.5x mode */
     64#define LP5521_CP_MODE_AUTO		0x18	/* Automatic mode selection */
     65#define LP5521_R_TO_BATT		0x04	/* R out: 0 = CP, 1 = Vbat */
     66#define LP5521_CLK_INT			0x01	/* Internal clock */
     67#define LP5521_DEFAULT_CFG		\
     68	(LP5521_PWM_HF | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO)
     69
     70/* Status */
     71#define LP5521_EXT_CLK_USED		0x08
     72
     73/* default R channel current register value */
     74#define LP5521_REG_R_CURR_DEFAULT	0xAF
     75
     76/* Reset register value */
     77#define LP5521_RESET			0xFF
     78
     79/* Program Memory Operations */
     80#define LP5521_MODE_R_M			0x30	/* Operation Mode Register */
     81#define LP5521_MODE_G_M			0x0C
     82#define LP5521_MODE_B_M			0x03
     83#define LP5521_LOAD_R			0x10
     84#define LP5521_LOAD_G			0x04
     85#define LP5521_LOAD_B			0x01
     86
     87#define LP5521_R_IS_LOADING(mode)	\
     88	((mode & LP5521_MODE_R_M) == LP5521_LOAD_R)
     89#define LP5521_G_IS_LOADING(mode)	\
     90	((mode & LP5521_MODE_G_M) == LP5521_LOAD_G)
     91#define LP5521_B_IS_LOADING(mode)	\
     92	((mode & LP5521_MODE_B_M) == LP5521_LOAD_B)
     93
     94#define LP5521_EXEC_R_M			0x30	/* Enable Register */
     95#define LP5521_EXEC_G_M			0x0C
     96#define LP5521_EXEC_B_M			0x03
     97#define LP5521_EXEC_M			0x3F
     98#define LP5521_RUN_R			0x20
     99#define LP5521_RUN_G			0x08
    100#define LP5521_RUN_B			0x02
    101
    102static inline void lp5521_wait_opmode_done(void)
    103{
    104	/* operation mode change needs to be longer than 153 us */
    105	usleep_range(200, 300);
    106}
    107
    108static inline void lp5521_wait_enable_done(void)
    109{
    110	/* it takes more 488 us to update ENABLE register */
    111	usleep_range(500, 600);
    112}
    113
    114static void lp5521_set_led_current(struct lp55xx_led *led, u8 led_current)
    115{
    116	led->led_current = led_current;
    117	lp55xx_write(led->chip, LP5521_REG_LED_CURRENT_BASE + led->chan_nr,
    118		led_current);
    119}
    120
    121static void lp5521_load_engine(struct lp55xx_chip *chip)
    122{
    123	enum lp55xx_engine_index idx = chip->engine_idx;
    124	static const u8 mask[] = {
    125		[LP55XX_ENGINE_1] = LP5521_MODE_R_M,
    126		[LP55XX_ENGINE_2] = LP5521_MODE_G_M,
    127		[LP55XX_ENGINE_3] = LP5521_MODE_B_M,
    128	};
    129
    130	static const u8 val[] = {
    131		[LP55XX_ENGINE_1] = LP5521_LOAD_R,
    132		[LP55XX_ENGINE_2] = LP5521_LOAD_G,
    133		[LP55XX_ENGINE_3] = LP5521_LOAD_B,
    134	};
    135
    136	lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], val[idx]);
    137
    138	lp5521_wait_opmode_done();
    139}
    140
    141static void lp5521_stop_all_engines(struct lp55xx_chip *chip)
    142{
    143	lp55xx_write(chip, LP5521_REG_OP_MODE, 0);
    144	lp5521_wait_opmode_done();
    145}
    146
    147static void lp5521_stop_engine(struct lp55xx_chip *chip)
    148{
    149	enum lp55xx_engine_index idx = chip->engine_idx;
    150	static const u8 mask[] = {
    151		[LP55XX_ENGINE_1] = LP5521_MODE_R_M,
    152		[LP55XX_ENGINE_2] = LP5521_MODE_G_M,
    153		[LP55XX_ENGINE_3] = LP5521_MODE_B_M,
    154	};
    155
    156	lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], 0);
    157
    158	lp5521_wait_opmode_done();
    159}
    160
    161static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
    162{
    163	int ret;
    164	u8 mode;
    165	u8 exec;
    166
    167	/* stop engine */
    168	if (!start) {
    169		lp5521_stop_engine(chip);
    170		lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
    171		lp5521_wait_opmode_done();
    172		return;
    173	}
    174
    175	/*
    176	 * To run the engine,
    177	 * operation mode and enable register should updated at the same time
    178	 */
    179
    180	ret = lp55xx_read(chip, LP5521_REG_OP_MODE, &mode);
    181	if (ret)
    182		return;
    183
    184	ret = lp55xx_read(chip, LP5521_REG_ENABLE, &exec);
    185	if (ret)
    186		return;
    187
    188	/* change operation mode to RUN only when each engine is loading */
    189	if (LP5521_R_IS_LOADING(mode)) {
    190		mode = (mode & ~LP5521_MODE_R_M) | LP5521_RUN_R;
    191		exec = (exec & ~LP5521_EXEC_R_M) | LP5521_RUN_R;
    192	}
    193
    194	if (LP5521_G_IS_LOADING(mode)) {
    195		mode = (mode & ~LP5521_MODE_G_M) | LP5521_RUN_G;
    196		exec = (exec & ~LP5521_EXEC_G_M) | LP5521_RUN_G;
    197	}
    198
    199	if (LP5521_B_IS_LOADING(mode)) {
    200		mode = (mode & ~LP5521_MODE_B_M) | LP5521_RUN_B;
    201		exec = (exec & ~LP5521_EXEC_B_M) | LP5521_RUN_B;
    202	}
    203
    204	lp55xx_write(chip, LP5521_REG_OP_MODE, mode);
    205	lp5521_wait_opmode_done();
    206
    207	lp55xx_update_bits(chip, LP5521_REG_ENABLE, LP5521_EXEC_M, exec);
    208	lp5521_wait_enable_done();
    209}
    210
    211static int lp5521_update_program_memory(struct lp55xx_chip *chip,
    212					const u8 *data, size_t size)
    213{
    214	enum lp55xx_engine_index idx = chip->engine_idx;
    215	u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
    216	static const u8 addr[] = {
    217		[LP55XX_ENGINE_1] = LP5521_REG_R_PROG_MEM,
    218		[LP55XX_ENGINE_2] = LP5521_REG_G_PROG_MEM,
    219		[LP55XX_ENGINE_3] = LP5521_REG_B_PROG_MEM,
    220	};
    221	unsigned cmd;
    222	char c[3];
    223	int nrchars;
    224	int ret;
    225	int offset = 0;
    226	int i = 0;
    227
    228	while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) {
    229		/* separate sscanfs because length is working only for %s */
    230		ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
    231		if (ret != 1)
    232			goto err;
    233
    234		ret = sscanf(c, "%2x", &cmd);
    235		if (ret != 1)
    236			goto err;
    237
    238		pattern[i] = (u8)cmd;
    239		offset += nrchars;
    240		i++;
    241	}
    242
    243	/* Each instruction is 16bit long. Check that length is even */
    244	if (i % 2)
    245		goto err;
    246
    247	for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) {
    248		ret = lp55xx_write(chip, addr[idx] + i, pattern[i]);
    249		if (ret)
    250			return -EINVAL;
    251	}
    252
    253	return size;
    254
    255err:
    256	dev_err(&chip->cl->dev, "wrong pattern format\n");
    257	return -EINVAL;
    258}
    259
    260static void lp5521_firmware_loaded(struct lp55xx_chip *chip)
    261{
    262	const struct firmware *fw = chip->fw;
    263
    264	if (fw->size > LP5521_PROGRAM_LENGTH) {
    265		dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
    266			fw->size);
    267		return;
    268	}
    269
    270	/*
    271	 * Program memory sequence
    272	 *  1) set engine mode to "LOAD"
    273	 *  2) write firmware data into program memory
    274	 */
    275
    276	lp5521_load_engine(chip);
    277	lp5521_update_program_memory(chip, fw->data, fw->size);
    278}
    279
    280static int lp5521_post_init_device(struct lp55xx_chip *chip)
    281{
    282	int ret;
    283	u8 val;
    284
    285	/*
    286	 * Make sure that the chip is reset by reading back the r channel
    287	 * current reg. This is dummy read is required on some platforms -
    288	 * otherwise further access to the R G B channels in the
    289	 * LP5521_REG_ENABLE register will not have any effect - strange!
    290	 */
    291	ret = lp55xx_read(chip, LP5521_REG_R_CURRENT, &val);
    292	if (ret) {
    293		dev_err(&chip->cl->dev, "error in resetting chip\n");
    294		return ret;
    295	}
    296	if (val != LP5521_REG_R_CURR_DEFAULT) {
    297		dev_err(&chip->cl->dev,
    298			"unexpected data in register (expected 0x%x got 0x%x)\n",
    299			LP5521_REG_R_CURR_DEFAULT, val);
    300		ret = -EINVAL;
    301		return ret;
    302	}
    303	usleep_range(10000, 20000);
    304
    305	/* Set all PWMs to direct control mode */
    306	ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
    307
    308	/* Update configuration for the clock setting */
    309	val = LP5521_DEFAULT_CFG;
    310	if (!lp55xx_is_extclk_used(chip))
    311		val |= LP5521_CLK_INT;
    312
    313	ret = lp55xx_write(chip, LP5521_REG_CONFIG, val);
    314	if (ret)
    315		return ret;
    316
    317	/* Initialize all channels PWM to zero -> leds off */
    318	lp55xx_write(chip, LP5521_REG_R_PWM, 0);
    319	lp55xx_write(chip, LP5521_REG_G_PWM, 0);
    320	lp55xx_write(chip, LP5521_REG_B_PWM, 0);
    321
    322	/* Set engines are set to run state when OP_MODE enables engines */
    323	ret = lp55xx_write(chip, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM);
    324	if (ret)
    325		return ret;
    326
    327	lp5521_wait_enable_done();
    328
    329	return 0;
    330}
    331
    332static int lp5521_run_selftest(struct lp55xx_chip *chip, char *buf)
    333{
    334	struct lp55xx_platform_data *pdata = chip->pdata;
    335	int ret;
    336	u8 status;
    337
    338	ret = lp55xx_read(chip, LP5521_REG_STATUS, &status);
    339	if (ret < 0)
    340		return ret;
    341
    342	if (pdata->clock_mode != LP55XX_CLOCK_EXT)
    343		return 0;
    344
    345	/* Check that ext clock is really in use if requested */
    346	if  ((status & LP5521_EXT_CLK_USED) == 0)
    347		return -EIO;
    348
    349	return 0;
    350}
    351
    352static int lp5521_multicolor_brightness(struct lp55xx_led *led)
    353{
    354	struct lp55xx_chip *chip = led->chip;
    355	int ret;
    356	int i;
    357
    358	mutex_lock(&chip->lock);
    359	for (i = 0; i < led->mc_cdev.num_colors; i++) {
    360		ret = lp55xx_write(chip,
    361				   LP5521_REG_LED_PWM_BASE +
    362				   led->mc_cdev.subled_info[i].channel,
    363				   led->mc_cdev.subled_info[i].brightness);
    364		if (ret)
    365			break;
    366	}
    367	mutex_unlock(&chip->lock);
    368	return ret;
    369}
    370
    371static int lp5521_led_brightness(struct lp55xx_led *led)
    372{
    373	struct lp55xx_chip *chip = led->chip;
    374	int ret;
    375
    376	mutex_lock(&chip->lock);
    377	ret = lp55xx_write(chip, LP5521_REG_LED_PWM_BASE + led->chan_nr,
    378		led->brightness);
    379	mutex_unlock(&chip->lock);
    380
    381	return ret;
    382}
    383
    384static ssize_t show_engine_mode(struct device *dev,
    385				struct device_attribute *attr,
    386				char *buf, int nr)
    387{
    388	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
    389	struct lp55xx_chip *chip = led->chip;
    390	enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode;
    391
    392	switch (mode) {
    393	case LP55XX_ENGINE_RUN:
    394		return sprintf(buf, "run\n");
    395	case LP55XX_ENGINE_LOAD:
    396		return sprintf(buf, "load\n");
    397	case LP55XX_ENGINE_DISABLED:
    398	default:
    399		return sprintf(buf, "disabled\n");
    400	}
    401}
    402show_mode(1)
    403show_mode(2)
    404show_mode(3)
    405
    406static ssize_t store_engine_mode(struct device *dev,
    407				 struct device_attribute *attr,
    408				 const char *buf, size_t len, int nr)
    409{
    410	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
    411	struct lp55xx_chip *chip = led->chip;
    412	struct lp55xx_engine *engine = &chip->engines[nr - 1];
    413
    414	mutex_lock(&chip->lock);
    415
    416	chip->engine_idx = nr;
    417
    418	if (!strncmp(buf, "run", 3)) {
    419		lp5521_run_engine(chip, true);
    420		engine->mode = LP55XX_ENGINE_RUN;
    421	} else if (!strncmp(buf, "load", 4)) {
    422		lp5521_stop_engine(chip);
    423		lp5521_load_engine(chip);
    424		engine->mode = LP55XX_ENGINE_LOAD;
    425	} else if (!strncmp(buf, "disabled", 8)) {
    426		lp5521_stop_engine(chip);
    427		engine->mode = LP55XX_ENGINE_DISABLED;
    428	}
    429
    430	mutex_unlock(&chip->lock);
    431
    432	return len;
    433}
    434store_mode(1)
    435store_mode(2)
    436store_mode(3)
    437
    438static ssize_t store_engine_load(struct device *dev,
    439			     struct device_attribute *attr,
    440			     const char *buf, size_t len, int nr)
    441{
    442	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
    443	struct lp55xx_chip *chip = led->chip;
    444	int ret;
    445
    446	mutex_lock(&chip->lock);
    447
    448	chip->engine_idx = nr;
    449	lp5521_load_engine(chip);
    450	ret = lp5521_update_program_memory(chip, buf, len);
    451
    452	mutex_unlock(&chip->lock);
    453
    454	return ret;
    455}
    456store_load(1)
    457store_load(2)
    458store_load(3)
    459
    460static ssize_t lp5521_selftest(struct device *dev,
    461			       struct device_attribute *attr,
    462			       char *buf)
    463{
    464	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
    465	struct lp55xx_chip *chip = led->chip;
    466	int ret;
    467
    468	mutex_lock(&chip->lock);
    469	ret = lp5521_run_selftest(chip, buf);
    470	mutex_unlock(&chip->lock);
    471
    472	return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK");
    473}
    474
    475/* device attributes */
    476static LP55XX_DEV_ATTR_RW(engine1_mode, show_engine1_mode, store_engine1_mode);
    477static LP55XX_DEV_ATTR_RW(engine2_mode, show_engine2_mode, store_engine2_mode);
    478static LP55XX_DEV_ATTR_RW(engine3_mode, show_engine3_mode, store_engine3_mode);
    479static LP55XX_DEV_ATTR_WO(engine1_load, store_engine1_load);
    480static LP55XX_DEV_ATTR_WO(engine2_load, store_engine2_load);
    481static LP55XX_DEV_ATTR_WO(engine3_load, store_engine3_load);
    482static LP55XX_DEV_ATTR_RO(selftest, lp5521_selftest);
    483
    484static struct attribute *lp5521_attributes[] = {
    485	&dev_attr_engine1_mode.attr,
    486	&dev_attr_engine2_mode.attr,
    487	&dev_attr_engine3_mode.attr,
    488	&dev_attr_engine1_load.attr,
    489	&dev_attr_engine2_load.attr,
    490	&dev_attr_engine3_load.attr,
    491	&dev_attr_selftest.attr,
    492	NULL
    493};
    494
    495static const struct attribute_group lp5521_group = {
    496	.attrs = lp5521_attributes,
    497};
    498
    499/* Chip specific configurations */
    500static struct lp55xx_device_config lp5521_cfg = {
    501	.reset = {
    502		.addr = LP5521_REG_RESET,
    503		.val  = LP5521_RESET,
    504	},
    505	.enable = {
    506		.addr = LP5521_REG_ENABLE,
    507		.val  = LP5521_ENABLE_DEFAULT,
    508	},
    509	.max_channel  = LP5521_MAX_LEDS,
    510	.post_init_device   = lp5521_post_init_device,
    511	.brightness_fn      = lp5521_led_brightness,
    512	.multicolor_brightness_fn = lp5521_multicolor_brightness,
    513	.set_led_current    = lp5521_set_led_current,
    514	.firmware_cb        = lp5521_firmware_loaded,
    515	.run_engine         = lp5521_run_engine,
    516	.dev_attr_group     = &lp5521_group,
    517};
    518
    519static int lp5521_probe(struct i2c_client *client,
    520			const struct i2c_device_id *id)
    521{
    522	int ret;
    523	struct lp55xx_chip *chip;
    524	struct lp55xx_led *led;
    525	struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
    526	struct device_node *np = dev_of_node(&client->dev);
    527
    528	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
    529	if (!chip)
    530		return -ENOMEM;
    531
    532	chip->cfg = &lp5521_cfg;
    533
    534	if (!pdata) {
    535		if (np) {
    536			pdata = lp55xx_of_populate_pdata(&client->dev, np,
    537							 chip);
    538			if (IS_ERR(pdata))
    539				return PTR_ERR(pdata);
    540		} else {
    541			dev_err(&client->dev, "no platform data\n");
    542			return -EINVAL;
    543		}
    544	}
    545
    546	led = devm_kcalloc(&client->dev,
    547			pdata->num_channels, sizeof(*led), GFP_KERNEL);
    548	if (!led)
    549		return -ENOMEM;
    550
    551	chip->cl = client;
    552	chip->pdata = pdata;
    553
    554	mutex_init(&chip->lock);
    555
    556	i2c_set_clientdata(client, led);
    557
    558	ret = lp55xx_init_device(chip);
    559	if (ret)
    560		goto err_init;
    561
    562	dev_info(&client->dev, "%s programmable led chip found\n", id->name);
    563
    564	ret = lp55xx_register_leds(led, chip);
    565	if (ret)
    566		goto err_out;
    567
    568	ret = lp55xx_register_sysfs(chip);
    569	if (ret) {
    570		dev_err(&client->dev, "registering sysfs failed\n");
    571		goto err_out;
    572	}
    573
    574	return 0;
    575
    576err_out:
    577	lp55xx_deinit_device(chip);
    578err_init:
    579	return ret;
    580}
    581
    582static int lp5521_remove(struct i2c_client *client)
    583{
    584	struct lp55xx_led *led = i2c_get_clientdata(client);
    585	struct lp55xx_chip *chip = led->chip;
    586
    587	lp5521_stop_all_engines(chip);
    588	lp55xx_unregister_sysfs(chip);
    589	lp55xx_deinit_device(chip);
    590
    591	return 0;
    592}
    593
    594static const struct i2c_device_id lp5521_id[] = {
    595	{ "lp5521", 0 }, /* Three channel chip */
    596	{ }
    597};
    598MODULE_DEVICE_TABLE(i2c, lp5521_id);
    599
    600#ifdef CONFIG_OF
    601static const struct of_device_id of_lp5521_leds_match[] = {
    602	{ .compatible = "national,lp5521", },
    603	{},
    604};
    605
    606MODULE_DEVICE_TABLE(of, of_lp5521_leds_match);
    607#endif
    608static struct i2c_driver lp5521_driver = {
    609	.driver = {
    610		.name	= "lp5521",
    611		.of_match_table = of_match_ptr(of_lp5521_leds_match),
    612	},
    613	.probe		= lp5521_probe,
    614	.remove		= lp5521_remove,
    615	.id_table	= lp5521_id,
    616};
    617
    618module_i2c_driver(lp5521_driver);
    619
    620MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo");
    621MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
    622MODULE_DESCRIPTION("LP5521 LED engine");
    623MODULE_LICENSE("GPL v2");