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-lp55xx-common.c (16549B)


      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");