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/i2c/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 controls 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, ®_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, ®_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, ®_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 strscpy(flash->subdev_led.name, LM3646_NAME, 282 sizeof(flash->subdev_led.name)); 283 rval = lm3646_init_controls(flash); 284 if (rval) 285 goto err_out; 286 rval = media_entity_pads_init(&flash->subdev_led.entity, 0, NULL); 287 if (rval < 0) 288 goto err_out; 289 flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH; 290 return rval; 291 292 err_out: 293 v4l2_ctrl_handler_free(&flash->ctrls_led); 294 return rval; 295 } 296 297 static int lm3646_init_device(struct lm3646_flash *flash) 298 { 299 unsigned int reg_val; 300 int rval; 301 302 /* read the value of mode register to reduce redundant i2c accesses */ 303 rval = regmap_read(flash->regmap, REG_ENABLE, ®_val); 304 if (rval < 0) 305 return rval; 306 flash->mode_reg = reg_val & 0xfc; 307 308 /* output disable */ 309 rval = lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE); 310 if (rval < 0) 311 return rval; 312 313 /* 314 * LED1 flash current setting 315 * LED2 flash current = Total(Max) flash current - LED1 flash current 316 */ 317 rval = regmap_update_bits(flash->regmap, 318 REG_LED1_FLASH_BR, 0x7F, 319 LM3646_LED1_FLASH_BRT_uA_TO_REG 320 (flash->pdata->led1_flash_brt)); 321 322 if (rval < 0) 323 return rval; 324 325 /* 326 * LED1 torch current setting 327 * LED2 torch current = Total(Max) torch current - LED1 torch current 328 */ 329 rval = regmap_update_bits(flash->regmap, 330 REG_LED1_TORCH_BR, 0x7F, 331 LM3646_LED1_TORCH_BRT_uA_TO_REG 332 (flash->pdata->led1_torch_brt)); 333 if (rval < 0) 334 return rval; 335 336 /* Reset flag register */ 337 return regmap_read(flash->regmap, REG_FLAG, ®_val); 338 } 339 340 static int lm3646_probe(struct i2c_client *client, 341 const struct i2c_device_id *devid) 342 { 343 struct lm3646_flash *flash; 344 struct lm3646_platform_data *pdata = dev_get_platdata(&client->dev); 345 int rval; 346 347 flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); 348 if (flash == NULL) 349 return -ENOMEM; 350 351 flash->regmap = devm_regmap_init_i2c(client, &lm3646_regmap); 352 if (IS_ERR(flash->regmap)) 353 return PTR_ERR(flash->regmap); 354 355 /* check device tree if there is no platform data */ 356 if (pdata == NULL) { 357 pdata = devm_kzalloc(&client->dev, 358 sizeof(struct lm3646_platform_data), 359 GFP_KERNEL); 360 if (pdata == NULL) 361 return -ENOMEM; 362 /* use default data in case of no platform data */ 363 pdata->flash_timeout = LM3646_FLASH_TOUT_MAX; 364 pdata->led1_torch_brt = LM3646_LED1_TORCH_BRT_MAX; 365 pdata->led1_flash_brt = LM3646_LED1_FLASH_BRT_MAX; 366 } 367 flash->pdata = pdata; 368 flash->dev = &client->dev; 369 370 rval = lm3646_subdev_init(flash); 371 if (rval < 0) 372 return rval; 373 374 rval = lm3646_init_device(flash); 375 if (rval < 0) 376 return rval; 377 378 i2c_set_clientdata(client, flash); 379 380 return 0; 381 } 382 383 static int lm3646_remove(struct i2c_client *client) 384 { 385 struct lm3646_flash *flash = i2c_get_clientdata(client); 386 387 v4l2_device_unregister_subdev(&flash->subdev_led); 388 v4l2_ctrl_handler_free(&flash->ctrls_led); 389 media_entity_cleanup(&flash->subdev_led.entity); 390 391 return 0; 392 } 393 394 static const struct i2c_device_id lm3646_id_table[] = { 395 {LM3646_NAME, 0}, 396 {} 397 }; 398 399 MODULE_DEVICE_TABLE(i2c, lm3646_id_table); 400 401 static struct i2c_driver lm3646_i2c_driver = { 402 .driver = { 403 .name = LM3646_NAME, 404 }, 405 .probe = lm3646_probe, 406 .remove = lm3646_remove, 407 .id_table = lm3646_id_table, 408 }; 409 410 module_i2c_driver(lm3646_i2c_driver); 411 412 MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); 413 MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>"); 414 MODULE_DESCRIPTION("Texas Instruments LM3646 Dual Flash LED driver"); 415 MODULE_LICENSE("GPL"); 416