From a05f48869819c6098707c57b7e828a095b3d3c47 Mon Sep 17 00:00:00 2001 From: Daniel jeong Date: Tue, 8 Jul 2014 20:03:04 +0900 Subject: [PATCH] Add LM3643 new flash driver using LED-subsystem Signed-off-by: Daniel jeong --- drivers/leds/Kconfig | 9 + drivers/leds/Makefile | 1 + drivers/leds/leds-lm3643.c | 699 ++++++++++++++++++++++ include/linux/platform_data/leds-lm3643.h | 17 + 4 files changed, 726 insertions(+) create mode 100644 drivers/leds/leds-lm3643.c create mode 100644 include/linux/platform_data/leds-lm3643.h diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 288d39d..b5609c0 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -73,6 +73,15 @@ config LEDS_LM3642 converter plus 1.5A constant current driver for a high-current white LED. +config LEDS_LM3643 + tristate "LED support for LM3643 Chip" + depends on LEDS_CLASS && I2C + select REGMAP_I2C + help + This option enables support for LEDs connected to LM3643. + The LM3643 is a 2/4MHz fixed-frequency synchronous boost + converter with 1.5A constant current LED driver. + config LEDS_LOCOMO tristate "LED Support for Locomo device" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 4b61b5c..9bfa081 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o +obj-$(CONFIG_LEDS_LM3643) += leds-lm3643.o obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o diff --git a/drivers/leds/leds-lm3643.c b/drivers/leds/leds-lm3643.c new file mode 100644 index 0000000..791fed3 --- /dev/null +++ b/drivers/leds/leds-lm3643.c @@ -0,0 +1,699 @@ +/* + * drivers/leds/leds-lm3643.c + * General device driver for TI LM3643, FLASH LED Driver + * + * Copyright (C) 2014 Texas Instruments + * + * Contact: Daniel Jeong + * Ldd-Mlp + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* registers definitions */ +#define REG_ENABLE 0x01 +#define REG_FLASH_LED0_BR 0x03 +#define REG_FLASH_LED1_BR 0x04 +#define REG_TORCH_LED0_BR 0x05 +#define REG_TORCH_LED1_BR 0x06 +#define REG_FLASH_TOUT 0x08 +#define REG_FLAG0 0x0a +#define REG_FLAG1 0x0b + +enum lm3643_devid { + ID_FLASH0 = 0x0, + ID_FLASH1, + ID_TORCH0, + ID_TORCH1, + ID_MAX +}; + +enum lm3643_mode { + MODE_STDBY = 0x0, + MODE_IR, + MODE_TORCH, + MODE_FLASH, + MODE_MAX +}; + +enum lm3643_devfile { + DFILE_FLASH0_ENABLE = 0, + DFILE_FLASH0_ONOFF, + DFILE_FLASH0_SOURCE, + DFILE_FLASH0_TIMEOUT, + DFILE_FLASH1_ENABLE, + DFILE_FLASH1_ONOFF, + DFILE_TORCH0_ENABLE, + DFILE_TORCH0_ONOFF, + DFILE_TORCH0_SOURCE, + DFILE_TORCH1_ENABLE, + DFILE_TORCH1_ONOFF, + DFILE_MAX +}; + +#define to_lm3643(_ctrl, _no) container_of(_ctrl, struct lm3643, cdev[_no]) + +struct lm3643 { + struct device *dev; + + u8 brightness[ID_MAX]; + struct work_struct work[ID_MAX]; + struct led_classdev cdev[ID_MAX]; + + struct lm3643_platform_data *pdata; + struct regmap *regmap; + struct mutex lock; +}; + +static void lm3643_read_flag(struct lm3643 *pchip) +{ + + int rval; + unsigned int flag0, flag1; + + rval = regmap_read(pchip->regmap, REG_FLAG0, &flag0); + rval |= regmap_read(pchip->regmap, REG_FLAG1, &flag1); + + if (rval < 0) + dev_err(pchip->dev, "i2c access fail.\n"); + + dev_info(pchip->dev, "[flag1] 0x%x, [flag0] 0x%x\n", + flag1 & 0x1f, flag0); +} + +/* torch0 brightness control */ +static void lm3643_deferred_torch0_brightness_set(struct work_struct *work) +{ + struct lm3643 *pchip = container_of(work, + struct lm3643, work[ID_TORCH0]); + + if (regmap_update_bits(pchip->regmap, + REG_TORCH_LED0_BR, 0x7f, + pchip->brightness[ID_TORCH0])) + dev_err(pchip->dev, "i2c access fail.\n"); + lm3643_read_flag(pchip); +} + +static void lm3643_torch0_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct lm3643 *pchip = + container_of(cdev, struct lm3643, cdev[ID_TORCH0]); + + pchip->brightness[ID_TORCH0] = brightness; + schedule_work(&pchip->work[ID_TORCH0]); +} + +/* torch1 brightness control */ +static void lm3643_deferred_torch1_brightness_set(struct work_struct *work) +{ + struct lm3643 *pchip = container_of(work, + struct lm3643, work[ID_TORCH1]); + + if (regmap_update_bits(pchip->regmap, + REG_TORCH_LED1_BR, 0x7f, + pchip->brightness[ID_TORCH1])) + dev_err(pchip->dev, "i2c access fail.\n"); + lm3643_read_flag(pchip); +} + +static void lm3643_torch1_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct lm3643 *pchip = + container_of(cdev, struct lm3643, cdev[ID_TORCH1]); + + pchip->brightness[ID_TORCH1] = brightness; + schedule_work(&pchip->work[ID_TORCH1]); +} + +/* flash0 brightness control */ +static void lm3643_deferred_flash0_brightness_set(struct work_struct *work) +{ + struct lm3643 *pchip = container_of(work, + struct lm3643, work[ID_FLASH0]); + + if (regmap_update_bits(pchip->regmap, + REG_FLASH_LED0_BR, 0x7f, + pchip->brightness[ID_FLASH0])) + dev_err(pchip->dev, "i2c access fail.\n"); + lm3643_read_flag(pchip); +} + +static void lm3643_flash0_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct lm3643 *pchip = + container_of(cdev, struct lm3643, cdev[ID_FLASH0]); + + pchip->brightness[ID_FLASH0] = brightness; + schedule_work(&pchip->work[ID_FLASH0]); +} + +/* flash1 brightness control */ +static void lm3643_deferred_flash1_brightness_set(struct work_struct *work) +{ + struct lm3643 *pchip = container_of(work, + struct lm3643, work[ID_FLASH1]); + + if (regmap_update_bits(pchip->regmap, + REG_FLASH_LED1_BR, 0x7f, + pchip->brightness[ID_FLASH1])) + dev_err(pchip->dev, "i2c access fail.\n"); + lm3643_read_flag(pchip); +} + +static void lm3643_flash1_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct lm3643 *pchip = + container_of(cdev, struct lm3643, cdev[ID_FLASH1]); + + pchip->brightness[ID_FLASH1] = brightness; + schedule_work(&pchip->work[ID_FLASH1]); +} + +struct lm3643_devices { + struct led_classdev cdev; + work_func_t func; +}; + +static struct lm3643_devices lm3643_leds[ID_MAX] = { + [ID_FLASH0] = { + .cdev.name = "flash0", + .cdev.brightness = 0, + .cdev.max_brightness = 0x7f, + .cdev.brightness_set = lm3643_flash0_brightness_set, + .cdev.default_trigger = "flash0", + .func = lm3643_deferred_flash0_brightness_set}, + [ID_FLASH1] = { + .cdev.name = "flash1", + .cdev.brightness = 0, + .cdev.max_brightness = 0x7f, + .cdev.brightness_set = lm3643_flash1_brightness_set, + .cdev.default_trigger = "flash1", + .func = lm3643_deferred_flash1_brightness_set}, + [ID_TORCH0] = { + .cdev.name = "torch0", + .cdev.brightness = 0, + .cdev.max_brightness = 0x7f, + .cdev.brightness_set = lm3643_torch0_brightness_set, + .cdev.default_trigger = "torch0", + .func = lm3643_deferred_torch0_brightness_set}, + [ID_TORCH1] = { + .cdev.name = "torch1", + .cdev.brightness = 0, + .cdev.max_brightness = 0x7f, + .cdev.brightness_set = lm3643_torch1_brightness_set, + .cdev.default_trigger = "torch1", + .func = lm3643_deferred_torch1_brightness_set}, +}; + +static void lm3643_led_unregister(struct lm3643 *pchip, enum lm3643_devid id) +{ + int icnt; + + for (icnt = id; icnt > 0; icnt--) + led_classdev_unregister(&pchip->cdev[icnt - 1]); +} + +static int lm3643_led_register(struct lm3643 *pchip) +{ + int icnt, rval; + + for (icnt = 0; icnt < ID_MAX; icnt++) { + INIT_WORK(&pchip->work[icnt], lm3643_leds[icnt].func); + pchip->cdev[icnt].name = lm3643_leds[icnt].cdev.name; + pchip->cdev[icnt].max_brightness = + lm3643_leds[icnt].cdev.max_brightness; + pchip->cdev[icnt].brightness = + lm3643_leds[icnt].cdev.brightness; + pchip->cdev[icnt].brightness_set = + lm3643_leds[icnt].cdev.brightness_set; + pchip->cdev[icnt].default_trigger = + lm3643_leds[icnt].cdev.default_trigger; + rval = led_classdev_register((struct device *) + pchip->dev, &pchip->cdev[icnt]); + if (rval < 0) { + lm3643_led_unregister(pchip, icnt); + return rval; + } + } + return 0; +} + +/* device files to control registers */ +struct lm3643_commands { + char *str; + int size; +}; + +enum lm3643_cmd_id { + CMD_ENABLE = 0, + CMD_DISABLE, + CMD_ON, + CMD_OFF, + CMD_IRMODE, + CMD_OVERRIDE, + CMD_MAX +}; + +struct lm3643_commands cmds[CMD_MAX] = { + [CMD_ENABLE] = {"enable", 6}, + [CMD_DISABLE] = {"disable", 7}, + [CMD_ON] = {"on", 2}, + [CMD_OFF] = {"off", 3}, + [CMD_IRMODE] = {"irmode", 6}, + [CMD_OVERRIDE] = {"override", 8}, +}; + +struct lm3643_files { + enum lm3643_devid id; + struct device_attribute attr; +}; + +static size_t lm3643_ctrl(struct device *dev, + const char *buf, enum lm3643_devid id, + enum lm3643_devfile dfid, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct lm3643 *pchip = to_lm3643(led_cdev, id); + enum lm3643_cmd_id icnt; + int tout, rval; + + mutex_lock(&pchip->lock); + for (icnt = 0; icnt < CMD_MAX; icnt++) { + if (strncmp(buf, cmds[icnt].str, cmds[icnt].size) == 0) + break; + } + + switch (dfid) { + /* led 0 enable */ + case DFILE_FLASH0_ENABLE: + case DFILE_TORCH0_ENABLE: + if (icnt == CMD_ENABLE) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x1, + 0x1); + else if (icnt == CMD_DISABLE) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x1, + 0x0); + break; + /* led 1 enable, flash override */ + case DFILE_FLASH1_ENABLE: + if (icnt == CMD_ENABLE) { + rval = regmap_update_bits(pchip->regmap, + REG_FLASH_LED0_BR, 0x80, 0x0); + rval |= + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, + 0x2); + } else if (icnt == CMD_DISABLE) { + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, + 0x0); + } else if (icnt == CMD_OVERRIDE) { + rval = regmap_update_bits(pchip->regmap, + REG_FLASH_LED0_BR, 0x80, + 0x80); + rval |= + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, + 0x2); + } + break; + /* led 1 enable, torch override */ + case DFILE_TORCH1_ENABLE: + if (icnt == CMD_ENABLE) { + rval = regmap_update_bits(pchip->regmap, + REG_TORCH_LED0_BR, 0x80, 0x0); + rval |= + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, + 0x2); + } else if (icnt == CMD_DISABLE) { + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, + 0x0); + } else if (icnt == CMD_OVERRIDE) { + rval = regmap_update_bits(pchip->regmap, + REG_TORCH_LED0_BR, 0x80, + 0x80); + rval |= + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x2, + 0x2); + } + break; + /* mode control flash/ir */ + case DFILE_FLASH0_ONOFF: + case DFILE_FLASH1_ONOFF: + if (icnt == CMD_ON) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, + 0xc); + else if (icnt == CMD_OFF) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, + 0x0); + else if (icnt == CMD_IRMODE) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, + 0x4); + break; + /* mode control torch */ + case DFILE_TORCH0_ONOFF: + case DFILE_TORCH1_ONOFF: + if (icnt == CMD_ON) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, + 0x8); + else if (icnt == CMD_OFF) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0xc, + 0x0); + break; + /* strobe pin control */ + case DFILE_FLASH0_SOURCE: + if (icnt == CMD_ON) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x20, + 0x20); + else if (icnt == CMD_OFF) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x20, + 0x0); + break; + case DFILE_TORCH0_SOURCE: + if (icnt == CMD_ON) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x10, + 0x10); + else if (icnt == CMD_OFF) + rval = + regmap_update_bits(pchip->regmap, REG_ENABLE, 0x10, + 0x0); + break; + /* flash time out */ + case DFILE_FLASH0_TIMEOUT: + rval = kstrtouint((const char *)buf, 10, &tout); + if (rval < 0) + break; + rval = regmap_update_bits(pchip->regmap, + REG_FLASH_TOUT, 0x0f, tout); + break; + default: + dev_err(pchip->dev, "error : undefined dev file\n"); + break; + } + lm3643_read_flag(pchip); + mutex_unlock(&pchip->lock); + return size; +} + +/* flash enable control */ +static ssize_t lm3643_flash0_enable_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_ENABLE, size); +} + +static ssize_t lm3643_flash1_enable_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH1, DFILE_FLASH1_ENABLE, size); +} + +/* flash onoff control */ +static ssize_t lm3643_flash0_onoff_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_ONOFF, size); +} + +static ssize_t lm3643_flash1_onoff_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH1, DFILE_FLASH1_ONOFF, size); +} + +/* flash timeout control */ +static ssize_t lm3643_flash0_timeout_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_TIMEOUT, size); +} + +/* flash source control */ +static ssize_t lm3643_flash0_source_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_FLASH0_SOURCE, size); +} + +/* torch enable control */ +static ssize_t lm3643_torch0_enable_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_FLASH0, DFILE_TORCH0_ENABLE, size); +} + +static ssize_t lm3643_torch1_enable_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_TORCH1, DFILE_TORCH1_ENABLE, size); +} + +/* torch onoff control */ +static ssize_t lm3643_torch0_onoff_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_TORCH0, DFILE_TORCH0_ONOFF, size); +} + +static ssize_t lm3643_torch1_onoff_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_TORCH1, DFILE_TORCH1_ONOFF, size); +} + +/* torch source control */ +static ssize_t lm3643_torch0_source_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + return lm3643_ctrl(dev, buf, ID_TORCH0, DFILE_TORCH0_SOURCE, size); +} + +#define lm3643_attr(_name, _show, _store)\ +{\ + .attr = {\ + .name = _name,\ + .mode = 0644,\ + },\ + .show = _show,\ + .store = _store,\ +} + +static struct lm3643_files lm3643_devfiles[DFILE_MAX] = { + [DFILE_FLASH0_ENABLE] = { + .id = ID_FLASH0, + .attr = + lm3643_attr("enable", NULL, + lm3643_flash0_enable_store), + }, + [DFILE_FLASH0_ONOFF] = { + .id = ID_FLASH0, + .attr = + lm3643_attr("onoff", NULL, + lm3643_flash0_onoff_store), + }, + [DFILE_FLASH0_SOURCE] = { + .id = ID_FLASH0, + .attr = + lm3643_attr("source", NULL, + lm3643_flash0_source_store), + }, + [DFILE_FLASH0_TIMEOUT] = { + .id = ID_FLASH0, + .attr = + lm3643_attr("timeout", NULL, + lm3643_flash0_timeout_store), + }, + [DFILE_FLASH1_ENABLE] = { + .id = ID_FLASH1, + .attr = + lm3643_attr("enable", NULL, + lm3643_flash1_enable_store), + }, + [DFILE_FLASH1_ONOFF] = { + .id = ID_FLASH1, + .attr = + lm3643_attr("onoff", NULL, + lm3643_flash1_onoff_store), + }, + [DFILE_TORCH0_ENABLE] = { + .id = ID_TORCH0, + .attr = + lm3643_attr("enable", NULL, + lm3643_torch0_enable_store), + }, + [DFILE_TORCH0_ONOFF] = { + .id = ID_TORCH0, + .attr = + lm3643_attr("onoff", NULL, + lm3643_torch0_onoff_store), + }, + [DFILE_TORCH0_SOURCE] = { + .id = ID_TORCH0, + .attr = + lm3643_attr("source", NULL, + lm3643_torch0_source_store), + }, + [DFILE_TORCH1_ENABLE] = { + .id = ID_TORCH1, + .attr = + lm3643_attr("enable", NULL, + lm3643_torch1_enable_store), + }, + [DFILE_TORCH1_ONOFF] = { + .id = ID_TORCH1, + .attr = + lm3643_attr("onoff", NULL, + lm3643_torch1_onoff_store), + } +}; + +static void lm3643_df_remove(struct lm3643 *pchip, enum lm3643_devfile dfid) +{ + enum lm3643_devfile icnt; + + for (icnt = dfid; icnt > 0; icnt--) + device_remove_file(pchip->cdev[lm3643_devfiles[icnt - 1].id]. + dev, &lm3643_devfiles[icnt - 1].attr); +} + +static int lm3643_df_create(struct lm3643 *pchip) +{ + enum lm3643_devfile icnt; + int rval; + + for (icnt = 0; icnt < DFILE_MAX; icnt++) { + rval = + device_create_file(pchip->cdev[lm3643_devfiles[icnt].id]. + dev, &lm3643_devfiles[icnt].attr); + if (rval < 0) { + lm3643_df_remove(pchip, icnt); + return rval; + } + } + return 0; +} + +static const struct regmap_config lm3643_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xff, +}; + +static int lm3643_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct lm3643 *pchip; + int rval; + + /* i2c check */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "i2c functionality check fail.\n"); + return -EOPNOTSUPP; + } + + pchip = devm_kzalloc(&client->dev, sizeof(struct lm3643), GFP_KERNEL); + if (!pchip) + return -ENOMEM; + + pchip->dev = &client->dev; + pchip->regmap = devm_regmap_init_i2c(client, &lm3643_regmap); + if (IS_ERR(pchip->regmap)) { + rval = PTR_ERR(pchip->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + rval); + return rval; + } + mutex_init(&pchip->lock); + i2c_set_clientdata(client, pchip); + + /* led class register */ + rval = lm3643_led_register(pchip); + if (rval < 0) + return rval; + + /* create dev files */ + rval = lm3643_df_create(pchip); + if (rval < 0) { + lm3643_led_unregister(pchip, ID_MAX); + return rval; + } + + dev_info(pchip->dev, "lm3643 leds initialized\n"); + return 0; +} + +static int lm3643_remove(struct i2c_client *client) +{ + struct lm3643 *pchip = i2c_get_clientdata(client); + + lm3643_df_remove(pchip, DFILE_MAX); + lm3643_led_unregister(pchip, ID_MAX); + + return 0; +} + +static const struct i2c_device_id lm3643_id[] = { + {LM3643_NAME, 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, lm3643_id); + +static struct i2c_driver lm3643_i2c_driver = { + .driver = { + .name = LM3643_NAME, + .owner = THIS_MODULE, + .pm = NULL, + }, + .probe = lm3643_probe, + .remove = lm3643_remove, + .id_table = lm3643_id, +}; + +module_i2c_driver(lm3643_i2c_driver); + +MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3643"); +MODULE_AUTHOR("Daniel Jeong "); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/leds-lm3643.h b/include/linux/platform_data/leds-lm3643.h new file mode 100644 index 0000000..9782cd0 --- /dev/null +++ b/include/linux/platform_data/leds-lm3643.h @@ -0,0 +1,17 @@ +/* + * Simple driver for Texas Instruments LM3643 LED Flash driver chip + * Copyright (C) 2014 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __LM3643_H +#define __LM3643_H + +#define LM3643_NAME "leds-lm3643" +#define LM3643_ADDR 0x63 + +#endif /* __LM3643_H */ -- 2.39.2