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

[media] lm3646: add new dual LED Flash driver

This patch adds the driver for the LM3646, dual LED Flash driver.
The LM3646 has two 1.5A sync. boost converter with dual white current source.
It is controlled via an I2C compatible interface.
Each flash brightness, torch brightness and enable/disable can be controlled.
Under voltage, input voltage monitor and thermal threshhold Faults are added.
Please refer the datasheet http://www.ti.com/lit/ds/snvs962/snvs962.pdf

Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Daniel Jeong and committed by
Mauro Carvalho Chehab
dc76df5d 935aa6b2

+511
+9
drivers/media/i2c/Kconfig
··· 629 629 This is a driver for the lm3560 dual flash controllers. It controls 630 630 flash, torch LEDs. 631 631 632 + config VIDEO_LM3646 633 + tristate "LM3646 dual flash driver support" 634 + depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER 635 + depends on MEDIA_CAMERA_SUPPORT 636 + select REGMAP_I2C 637 + ---help--- 638 + This is a driver for the lm3646 dual flash controllers. It controls 639 + flash, torch LEDs. 640 + 632 641 comment "Video improvement chips" 633 642 634 643 config VIDEO_UPD64031A
+1
drivers/media/i2c/Makefile
··· 72 72 obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o 73 73 obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o 74 74 obj-$(CONFIG_VIDEO_LM3560) += lm3560.o 75 + obj-$(CONFIG_VIDEO_LM3646) += lm3646.o 75 76 obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o 76 77 obj-$(CONFIG_VIDEO_AK881X) += ak881x.o 77 78 obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
+414
drivers/media/i2c/lm3646.c
··· 1 + /* 2 + * drivers/media/i2c/lm3646.c 3 + * General device driver for TI lm3646, Dual FLASH LED Driver 4 + * 5 + * Copyright (C) 2014 Texas Instruments 6 + * 7 + * Contact: Daniel Jeong <gshark.jeong@gmail.com> 8 + * Ldd-Mlp <ldd-mlp@list.ti.com> 9 + * 10 + * This program is free software; you can redistribute it and/or 11 + * modify it under the terms of the GNU General Public License 12 + * version 2 as published by the Free Software Foundation. 13 + */ 14 + 15 + #include <linux/delay.h> 16 + #include <linux/i2c.h> 17 + #include <linux/module.h> 18 + #include <linux/slab.h> 19 + #include <linux/regmap.h> 20 + #include <linux/videodev2.h> 21 + #include <media/lm3646.h> 22 + #include <media/v4l2-ctrls.h> 23 + #include <media/v4l2-device.h> 24 + 25 + /* registers definitions */ 26 + #define REG_ENABLE 0x01 27 + #define REG_TORCH_BR 0x05 28 + #define REG_FLASH_BR 0x05 29 + #define REG_FLASH_TOUT 0x04 30 + #define REG_FLAG 0x08 31 + #define REG_STROBE_SRC 0x06 32 + #define REG_LED1_FLASH_BR 0x06 33 + #define REG_LED1_TORCH_BR 0x07 34 + 35 + #define MASK_ENABLE 0x03 36 + #define MASK_TORCH_BR 0x70 37 + #define MASK_FLASH_BR 0x0F 38 + #define MASK_FLASH_TOUT 0x07 39 + #define MASK_FLAG 0xFF 40 + #define MASK_STROBE_SRC 0x80 41 + 42 + /* Fault Mask */ 43 + #define FAULT_TIMEOUT (1<<0) 44 + #define FAULT_SHORT_CIRCUIT (1<<1) 45 + #define FAULT_UVLO (1<<2) 46 + #define FAULT_IVFM (1<<3) 47 + #define FAULT_OCP (1<<4) 48 + #define FAULT_OVERTEMP (1<<5) 49 + #define FAULT_NTC_TRIP (1<<6) 50 + #define FAULT_OVP (1<<7) 51 + 52 + enum led_mode { 53 + MODE_SHDN = 0x0, 54 + MODE_TORCH = 0x2, 55 + MODE_FLASH = 0x3, 56 + }; 57 + 58 + /* 59 + * struct lm3646_flash 60 + * 61 + * @pdata: platform data 62 + * @regmap: reg. map for i2c 63 + * @lock: muxtex for serial access. 64 + * @led_mode: V4L2 LED mode 65 + * @ctrls_led: V4L2 contols 66 + * @subdev_led: V4L2 subdev 67 + * @mode_reg : mode register value 68 + */ 69 + struct lm3646_flash { 70 + struct device *dev; 71 + struct lm3646_platform_data *pdata; 72 + struct regmap *regmap; 73 + 74 + struct v4l2_ctrl_handler ctrls_led; 75 + struct v4l2_subdev subdev_led; 76 + 77 + u8 mode_reg; 78 + }; 79 + 80 + #define to_lm3646_flash(_ctrl) \ 81 + container_of(_ctrl->handler, struct lm3646_flash, ctrls_led) 82 + 83 + /* enable mode control */ 84 + static int lm3646_mode_ctrl(struct lm3646_flash *flash, 85 + enum v4l2_flash_led_mode led_mode) 86 + { 87 + switch (led_mode) { 88 + case V4L2_FLASH_LED_MODE_NONE: 89 + return regmap_write(flash->regmap, 90 + REG_ENABLE, flash->mode_reg | MODE_SHDN); 91 + case V4L2_FLASH_LED_MODE_TORCH: 92 + return regmap_write(flash->regmap, 93 + REG_ENABLE, flash->mode_reg | MODE_TORCH); 94 + case V4L2_FLASH_LED_MODE_FLASH: 95 + return regmap_write(flash->regmap, 96 + REG_ENABLE, flash->mode_reg | MODE_FLASH); 97 + } 98 + return -EINVAL; 99 + } 100 + 101 + /* V4L2 controls */ 102 + static int lm3646_get_ctrl(struct v4l2_ctrl *ctrl) 103 + { 104 + struct lm3646_flash *flash = to_lm3646_flash(ctrl); 105 + unsigned int reg_val; 106 + int rval; 107 + 108 + if (ctrl->id != V4L2_CID_FLASH_FAULT) 109 + return -EINVAL; 110 + 111 + rval = regmap_read(flash->regmap, REG_FLAG, &reg_val); 112 + if (rval < 0) 113 + return rval; 114 + 115 + ctrl->val = 0; 116 + if (reg_val & FAULT_TIMEOUT) 117 + ctrl->val |= V4L2_FLASH_FAULT_TIMEOUT; 118 + if (reg_val & FAULT_SHORT_CIRCUIT) 119 + ctrl->val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; 120 + if (reg_val & FAULT_UVLO) 121 + ctrl->val |= V4L2_FLASH_FAULT_UNDER_VOLTAGE; 122 + if (reg_val & FAULT_IVFM) 123 + ctrl->val |= V4L2_FLASH_FAULT_INPUT_VOLTAGE; 124 + if (reg_val & FAULT_OCP) 125 + ctrl->val |= V4L2_FLASH_FAULT_OVER_CURRENT; 126 + if (reg_val & FAULT_OVERTEMP) 127 + ctrl->val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; 128 + if (reg_val & FAULT_NTC_TRIP) 129 + ctrl->val |= V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE; 130 + if (reg_val & FAULT_OVP) 131 + ctrl->val |= V4L2_FLASH_FAULT_OVER_VOLTAGE; 132 + 133 + return 0; 134 + } 135 + 136 + static int lm3646_set_ctrl(struct v4l2_ctrl *ctrl) 137 + { 138 + struct lm3646_flash *flash = to_lm3646_flash(ctrl); 139 + unsigned int reg_val; 140 + int rval = -EINVAL; 141 + 142 + switch (ctrl->id) { 143 + case V4L2_CID_FLASH_LED_MODE: 144 + 145 + if (ctrl->val != V4L2_FLASH_LED_MODE_FLASH) 146 + return lm3646_mode_ctrl(flash, ctrl->val); 147 + /* switch to SHDN mode before flash strobe on */ 148 + return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE); 149 + 150 + case V4L2_CID_FLASH_STROBE_SOURCE: 151 + return regmap_update_bits(flash->regmap, 152 + REG_STROBE_SRC, MASK_STROBE_SRC, 153 + (ctrl->val) << 7); 154 + 155 + case V4L2_CID_FLASH_STROBE: 156 + 157 + /* read and check current mode of chip to start flash */ 158 + rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val); 159 + if (rval < 0 || ((reg_val & MASK_ENABLE) != MODE_SHDN)) 160 + return rval; 161 + /* flash on */ 162 + return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_FLASH); 163 + 164 + case V4L2_CID_FLASH_STROBE_STOP: 165 + 166 + /* 167 + * flash mode will be turned automatically 168 + * from FLASH mode to SHDN mode after flash duration timeout 169 + * read and check current mode of chip to stop flash 170 + */ 171 + rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val); 172 + if (rval < 0) 173 + return rval; 174 + if ((reg_val & MASK_ENABLE) == MODE_FLASH) 175 + return lm3646_mode_ctrl(flash, 176 + V4L2_FLASH_LED_MODE_NONE); 177 + return rval; 178 + 179 + case V4L2_CID_FLASH_TIMEOUT: 180 + return regmap_update_bits(flash->regmap, 181 + REG_FLASH_TOUT, MASK_FLASH_TOUT, 182 + LM3646_FLASH_TOUT_ms_TO_REG 183 + (ctrl->val)); 184 + 185 + case V4L2_CID_FLASH_INTENSITY: 186 + return regmap_update_bits(flash->regmap, 187 + REG_FLASH_BR, MASK_FLASH_BR, 188 + LM3646_TOTAL_FLASH_BRT_uA_TO_REG 189 + (ctrl->val)); 190 + 191 + case V4L2_CID_FLASH_TORCH_INTENSITY: 192 + return regmap_update_bits(flash->regmap, 193 + REG_TORCH_BR, MASK_TORCH_BR, 194 + LM3646_TOTAL_TORCH_BRT_uA_TO_REG 195 + (ctrl->val) << 4); 196 + } 197 + 198 + return -EINVAL; 199 + } 200 + 201 + static const struct v4l2_ctrl_ops lm3646_led_ctrl_ops = { 202 + .g_volatile_ctrl = lm3646_get_ctrl, 203 + .s_ctrl = lm3646_set_ctrl, 204 + }; 205 + 206 + static int lm3646_init_controls(struct lm3646_flash *flash) 207 + { 208 + struct v4l2_ctrl *fault; 209 + struct v4l2_ctrl_handler *hdl = &flash->ctrls_led; 210 + const struct v4l2_ctrl_ops *ops = &lm3646_led_ctrl_ops; 211 + 212 + v4l2_ctrl_handler_init(hdl, 8); 213 + /* flash mode */ 214 + v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE, 215 + V4L2_FLASH_LED_MODE_TORCH, ~0x7, 216 + V4L2_FLASH_LED_MODE_NONE); 217 + 218 + /* flash source */ 219 + v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE, 220 + 0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE); 221 + 222 + /* flash strobe */ 223 + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0); 224 + /* flash strobe stop */ 225 + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0); 226 + 227 + /* flash strobe timeout */ 228 + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT, 229 + LM3646_FLASH_TOUT_MIN, 230 + LM3646_FLASH_TOUT_MAX, 231 + LM3646_FLASH_TOUT_STEP, flash->pdata->flash_timeout); 232 + 233 + /* max flash current */ 234 + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY, 235 + LM3646_TOTAL_FLASH_BRT_MIN, 236 + LM3646_TOTAL_FLASH_BRT_MAX, 237 + LM3646_TOTAL_FLASH_BRT_STEP, 238 + LM3646_TOTAL_FLASH_BRT_MAX); 239 + 240 + /* max torch current */ 241 + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY, 242 + LM3646_TOTAL_TORCH_BRT_MIN, 243 + LM3646_TOTAL_TORCH_BRT_MAX, 244 + LM3646_TOTAL_TORCH_BRT_STEP, 245 + LM3646_TOTAL_TORCH_BRT_MAX); 246 + 247 + /* fault */ 248 + fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0, 249 + V4L2_FLASH_FAULT_OVER_VOLTAGE 250 + | V4L2_FLASH_FAULT_OVER_TEMPERATURE 251 + | V4L2_FLASH_FAULT_SHORT_CIRCUIT 252 + | V4L2_FLASH_FAULT_TIMEOUT, 0, 0); 253 + if (fault != NULL) 254 + fault->flags |= V4L2_CTRL_FLAG_VOLATILE; 255 + 256 + if (hdl->error) 257 + return hdl->error; 258 + 259 + flash->subdev_led.ctrl_handler = hdl; 260 + return 0; 261 + } 262 + 263 + /* initialize device */ 264 + static const struct v4l2_subdev_ops lm3646_ops = { 265 + .core = NULL, 266 + }; 267 + 268 + static const struct regmap_config lm3646_regmap = { 269 + .reg_bits = 8, 270 + .val_bits = 8, 271 + .max_register = 0xFF, 272 + }; 273 + 274 + static int lm3646_subdev_init(struct lm3646_flash *flash) 275 + { 276 + struct i2c_client *client = to_i2c_client(flash->dev); 277 + int rval; 278 + 279 + v4l2_i2c_subdev_init(&flash->subdev_led, client, &lm3646_ops); 280 + flash->subdev_led.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 281 + strcpy(flash->subdev_led.name, LM3646_NAME); 282 + rval = lm3646_init_controls(flash); 283 + if (rval) 284 + goto err_out; 285 + rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0); 286 + if (rval < 0) 287 + goto err_out; 288 + flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; 289 + return rval; 290 + 291 + err_out: 292 + v4l2_ctrl_handler_free(&flash->ctrls_led); 293 + return rval; 294 + } 295 + 296 + static int lm3646_init_device(struct lm3646_flash *flash) 297 + { 298 + unsigned int reg_val; 299 + int rval; 300 + 301 + /* read the value of mode register to reduce redundant i2c accesses */ 302 + rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val); 303 + if (rval < 0) 304 + return rval; 305 + flash->mode_reg = reg_val & 0xfc; 306 + 307 + /* output disable */ 308 + rval = lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE); 309 + if (rval < 0) 310 + return rval; 311 + 312 + /* 313 + * LED1 flash current setting 314 + * LED2 flash current = Total(Max) flash current - LED1 flash current 315 + */ 316 + rval = regmap_update_bits(flash->regmap, 317 + REG_LED1_FLASH_BR, 0x7F, 318 + LM3646_LED1_FLASH_BRT_uA_TO_REG 319 + (flash->pdata->led1_flash_brt)); 320 + 321 + if (rval < 0) 322 + return rval; 323 + 324 + /* 325 + * LED1 torch current setting 326 + * LED2 torch current = Total(Max) torch current - LED1 torch current 327 + */ 328 + rval = regmap_update_bits(flash->regmap, 329 + REG_LED1_TORCH_BR, 0x7F, 330 + LM3646_LED1_TORCH_BRT_uA_TO_REG 331 + (flash->pdata->led1_torch_brt)); 332 + if (rval < 0) 333 + return rval; 334 + 335 + /* Reset flag register */ 336 + return regmap_read(flash->regmap, REG_FLAG, &reg_val); 337 + } 338 + 339 + static int lm3646_probe(struct i2c_client *client, 340 + const struct i2c_device_id *devid) 341 + { 342 + struct lm3646_flash *flash; 343 + struct lm3646_platform_data *pdata = dev_get_platdata(&client->dev); 344 + int rval; 345 + 346 + flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); 347 + if (flash == NULL) 348 + return -ENOMEM; 349 + 350 + flash->regmap = devm_regmap_init_i2c(client, &lm3646_regmap); 351 + if (IS_ERR(flash->regmap)) 352 + return PTR_ERR(flash->regmap); 353 + 354 + /* check device tree if there is no platform data */ 355 + if (pdata == NULL) { 356 + pdata = devm_kzalloc(&client->dev, 357 + sizeof(struct lm3646_platform_data), 358 + GFP_KERNEL); 359 + if (pdata == NULL) 360 + return -ENOMEM; 361 + /* use default data in case of no platform data */ 362 + pdata->flash_timeout = LM3646_FLASH_TOUT_MAX; 363 + pdata->led1_torch_brt = LM3646_LED1_TORCH_BRT_MAX; 364 + pdata->led1_flash_brt = LM3646_LED1_FLASH_BRT_MAX; 365 + } 366 + flash->pdata = pdata; 367 + flash->dev = &client->dev; 368 + 369 + rval = lm3646_subdev_init(flash); 370 + if (rval < 0) 371 + return rval; 372 + 373 + rval = lm3646_init_device(flash); 374 + if (rval < 0) 375 + return rval; 376 + 377 + i2c_set_clientdata(client, flash); 378 + 379 + return 0; 380 + } 381 + 382 + static int lm3646_remove(struct i2c_client *client) 383 + { 384 + struct lm3646_flash *flash = i2c_get_clientdata(client); 385 + 386 + v4l2_device_unregister_subdev(&flash->subdev_led); 387 + v4l2_ctrl_handler_free(&flash->ctrls_led); 388 + media_entity_cleanup(&flash->subdev_led.entity); 389 + 390 + return 0; 391 + } 392 + 393 + static const struct i2c_device_id lm3646_id_table[] = { 394 + {LM3646_NAME, 0}, 395 + {} 396 + }; 397 + 398 + MODULE_DEVICE_TABLE(i2c, lm3646_id_table); 399 + 400 + static struct i2c_driver lm3646_i2c_driver = { 401 + .driver = { 402 + .name = LM3646_NAME, 403 + }, 404 + .probe = lm3646_probe, 405 + .remove = lm3646_remove, 406 + .id_table = lm3646_id_table, 407 + }; 408 + 409 + module_i2c_driver(lm3646_i2c_driver); 410 + 411 + MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); 412 + MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>"); 413 + MODULE_DESCRIPTION("Texas Instruments LM3646 Dual Flash LED driver"); 414 + MODULE_LICENSE("GPL");
+87
include/media/lm3646.h
··· 1 + /* 2 + * include/media/lm3646.h 3 + * 4 + * Copyright (C) 2014 Texas Instruments 5 + * 6 + * Contact: Daniel Jeong <gshark.jeong@gmail.com> 7 + * Ldd-Mlp <ldd-mlp@list.ti.com> 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License 11 + * version 2 as published by the Free Software Foundation. 12 + */ 13 + 14 + #ifndef __LM3646_H__ 15 + #define __LM3646_H__ 16 + 17 + #include <media/v4l2-subdev.h> 18 + 19 + #define LM3646_NAME "lm3646" 20 + #define LM3646_I2C_ADDR_REV1 (0x67) 21 + #define LM3646_I2C_ADDR_REV0 (0x63) 22 + 23 + /* TOTAL FLASH Brightness Max 24 + * min 93350uA, step 93750uA, max 1499600uA 25 + */ 26 + #define LM3646_TOTAL_FLASH_BRT_MIN 93350 27 + #define LM3646_TOTAL_FLASH_BRT_STEP 93750 28 + #define LM3646_TOTAL_FLASH_BRT_MAX 1499600 29 + #define LM3646_TOTAL_FLASH_BRT_uA_TO_REG(a) \ 30 + ((a) < LM3646_TOTAL_FLASH_BRT_MIN ? 0 : \ 31 + ((((a) - LM3646_TOTAL_FLASH_BRT_MIN) / LM3646_TOTAL_FLASH_BRT_STEP))) 32 + 33 + /* TOTAL TORCH Brightness Max 34 + * min 23040uA, step 23430uA, max 187100uA 35 + */ 36 + #define LM3646_TOTAL_TORCH_BRT_MIN 23040 37 + #define LM3646_TOTAL_TORCH_BRT_STEP 23430 38 + #define LM3646_TOTAL_TORCH_BRT_MAX 187100 39 + #define LM3646_TOTAL_TORCH_BRT_uA_TO_REG(a) \ 40 + ((a) < LM3646_TOTAL_TORCH_BRT_MIN ? 0 : \ 41 + ((((a) - LM3646_TOTAL_TORCH_BRT_MIN) / LM3646_TOTAL_TORCH_BRT_STEP))) 42 + 43 + /* LED1 FLASH Brightness 44 + * min 23040uA, step 11718uA, max 1499600uA 45 + */ 46 + #define LM3646_LED1_FLASH_BRT_MIN 23040 47 + #define LM3646_LED1_FLASH_BRT_STEP 11718 48 + #define LM3646_LED1_FLASH_BRT_MAX 1499600 49 + #define LM3646_LED1_FLASH_BRT_uA_TO_REG(a) \ 50 + ((a) <= LM3646_LED1_FLASH_BRT_MIN ? 0 : \ 51 + ((((a) - LM3646_LED1_FLASH_BRT_MIN) / LM3646_LED1_FLASH_BRT_STEP))+1) 52 + 53 + /* LED1 TORCH Brightness 54 + * min 2530uA, step 1460uA, max 187100uA 55 + */ 56 + #define LM3646_LED1_TORCH_BRT_MIN 2530 57 + #define LM3646_LED1_TORCH_BRT_STEP 1460 58 + #define LM3646_LED1_TORCH_BRT_MAX 187100 59 + #define LM3646_LED1_TORCH_BRT_uA_TO_REG(a) \ 60 + ((a) <= LM3646_LED1_TORCH_BRT_MIN ? 0 : \ 61 + ((((a) - LM3646_LED1_TORCH_BRT_MIN) / LM3646_LED1_TORCH_BRT_STEP))+1) 62 + 63 + /* FLASH TIMEOUT DURATION 64 + * min 50ms, step 50ms, max 400ms 65 + */ 66 + #define LM3646_FLASH_TOUT_MIN 50 67 + #define LM3646_FLASH_TOUT_STEP 50 68 + #define LM3646_FLASH_TOUT_MAX 400 69 + #define LM3646_FLASH_TOUT_ms_TO_REG(a) \ 70 + ((a) <= LM3646_FLASH_TOUT_MIN ? 0 : \ 71 + (((a) - LM3646_FLASH_TOUT_MIN) / LM3646_FLASH_TOUT_STEP)) 72 + 73 + /* struct lm3646_platform_data 74 + * 75 + * @flash_timeout: flash timeout 76 + * @led1_flash_brt: led1 flash mode brightness, uA 77 + * @led1_torch_brt: led1 torch mode brightness, uA 78 + */ 79 + struct lm3646_platform_data { 80 + 81 + u32 flash_timeout; 82 + 83 + u32 led1_flash_brt; 84 + u32 led1_torch_brt; 85 + }; 86 + 87 + #endif /* __LM3646_H__ */