lm3560.c (12159B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * drivers/media/i2c/lm3560.c 4 * General device driver for TI lm3559, lm3560, FLASH LED Driver 5 * 6 * Copyright (C) 2013 Texas Instruments 7 * 8 * Contact: Daniel Jeong <gshark.jeong@gmail.com> 9 * Ldd-Mlp <ldd-mlp@list.ti.com> 10 */ 11 12#include <linux/delay.h> 13#include <linux/module.h> 14#include <linux/i2c.h> 15#include <linux/slab.h> 16#include <linux/mutex.h> 17#include <linux/regmap.h> 18#include <linux/videodev2.h> 19#include <media/i2c/lm3560.h> 20#include <media/v4l2-ctrls.h> 21#include <media/v4l2-device.h> 22 23/* registers definitions */ 24#define REG_ENABLE 0x10 25#define REG_TORCH_BR 0xa0 26#define REG_FLASH_BR 0xb0 27#define REG_FLASH_TOUT 0xc0 28#define REG_FLAG 0xd0 29#define REG_CONFIG1 0xe0 30 31/* fault mask */ 32#define FAULT_TIMEOUT (1<<0) 33#define FAULT_OVERTEMP (1<<1) 34#define FAULT_SHORT_CIRCUIT (1<<2) 35 36enum led_enable { 37 MODE_SHDN = 0x0, 38 MODE_TORCH = 0x2, 39 MODE_FLASH = 0x3, 40}; 41 42/** 43 * struct lm3560_flash 44 * 45 * @dev: pointer to &struct device 46 * @pdata: platform data 47 * @regmap: reg. map for i2c 48 * @lock: muxtex for serial access. 49 * @led_mode: V4L2 LED mode 50 * @ctrls_led: V4L2 controls 51 * @subdev_led: V4L2 subdev 52 */ 53struct lm3560_flash { 54 struct device *dev; 55 struct lm3560_platform_data *pdata; 56 struct regmap *regmap; 57 struct mutex lock; 58 59 enum v4l2_flash_led_mode led_mode; 60 struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX]; 61 struct v4l2_subdev subdev_led[LM3560_LED_MAX]; 62}; 63 64#define to_lm3560_flash(_ctrl, _no) \ 65 container_of(_ctrl->handler, struct lm3560_flash, ctrls_led[_no]) 66 67/* enable mode control */ 68static int lm3560_mode_ctrl(struct lm3560_flash *flash) 69{ 70 int rval = -EINVAL; 71 72 switch (flash->led_mode) { 73 case V4L2_FLASH_LED_MODE_NONE: 74 rval = regmap_update_bits(flash->regmap, 75 REG_ENABLE, 0x03, MODE_SHDN); 76 break; 77 case V4L2_FLASH_LED_MODE_TORCH: 78 rval = regmap_update_bits(flash->regmap, 79 REG_ENABLE, 0x03, MODE_TORCH); 80 break; 81 case V4L2_FLASH_LED_MODE_FLASH: 82 rval = regmap_update_bits(flash->regmap, 83 REG_ENABLE, 0x03, MODE_FLASH); 84 break; 85 } 86 return rval; 87} 88 89/* led1/2 enable/disable */ 90static int lm3560_enable_ctrl(struct lm3560_flash *flash, 91 enum lm3560_led_id led_no, bool on) 92{ 93 int rval; 94 95 if (led_no == LM3560_LED0) { 96 if (on) 97 rval = regmap_update_bits(flash->regmap, 98 REG_ENABLE, 0x08, 0x08); 99 else 100 rval = regmap_update_bits(flash->regmap, 101 REG_ENABLE, 0x08, 0x00); 102 } else { 103 if (on) 104 rval = regmap_update_bits(flash->regmap, 105 REG_ENABLE, 0x10, 0x10); 106 else 107 rval = regmap_update_bits(flash->regmap, 108 REG_ENABLE, 0x10, 0x00); 109 } 110 return rval; 111} 112 113/* torch1/2 brightness control */ 114static int lm3560_torch_brt_ctrl(struct lm3560_flash *flash, 115 enum lm3560_led_id led_no, unsigned int brt) 116{ 117 int rval; 118 u8 br_bits; 119 120 if (brt < LM3560_TORCH_BRT_MIN) 121 return lm3560_enable_ctrl(flash, led_no, false); 122 else 123 rval = lm3560_enable_ctrl(flash, led_no, true); 124 125 br_bits = LM3560_TORCH_BRT_uA_TO_REG(brt); 126 if (led_no == LM3560_LED0) 127 rval = regmap_update_bits(flash->regmap, 128 REG_TORCH_BR, 0x07, br_bits); 129 else 130 rval = regmap_update_bits(flash->regmap, 131 REG_TORCH_BR, 0x38, br_bits << 3); 132 133 return rval; 134} 135 136/* flash1/2 brightness control */ 137static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash, 138 enum lm3560_led_id led_no, unsigned int brt) 139{ 140 int rval; 141 u8 br_bits; 142 143 if (brt < LM3560_FLASH_BRT_MIN) 144 return lm3560_enable_ctrl(flash, led_no, false); 145 else 146 rval = lm3560_enable_ctrl(flash, led_no, true); 147 148 br_bits = LM3560_FLASH_BRT_uA_TO_REG(brt); 149 if (led_no == LM3560_LED0) 150 rval = regmap_update_bits(flash->regmap, 151 REG_FLASH_BR, 0x0f, br_bits); 152 else 153 rval = regmap_update_bits(flash->regmap, 154 REG_FLASH_BR, 0xf0, br_bits << 4); 155 156 return rval; 157} 158 159/* v4l2 controls */ 160static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) 161{ 162 struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); 163 int rval = -EINVAL; 164 165 mutex_lock(&flash->lock); 166 167 if (ctrl->id == V4L2_CID_FLASH_FAULT) { 168 s32 fault = 0; 169 unsigned int reg_val; 170 rval = regmap_read(flash->regmap, REG_FLAG, ®_val); 171 if (rval < 0) 172 goto out; 173 if (reg_val & FAULT_SHORT_CIRCUIT) 174 fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; 175 if (reg_val & FAULT_OVERTEMP) 176 fault |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; 177 if (reg_val & FAULT_TIMEOUT) 178 fault |= V4L2_FLASH_FAULT_TIMEOUT; 179 ctrl->cur.val = fault; 180 } 181 182out: 183 mutex_unlock(&flash->lock); 184 return rval; 185} 186 187static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) 188{ 189 struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); 190 u8 tout_bits; 191 int rval = -EINVAL; 192 193 mutex_lock(&flash->lock); 194 195 switch (ctrl->id) { 196 case V4L2_CID_FLASH_LED_MODE: 197 flash->led_mode = ctrl->val; 198 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) 199 rval = lm3560_mode_ctrl(flash); 200 break; 201 202 case V4L2_CID_FLASH_STROBE_SOURCE: 203 rval = regmap_update_bits(flash->regmap, 204 REG_CONFIG1, 0x04, (ctrl->val) << 2); 205 if (rval < 0) 206 goto err_out; 207 break; 208 209 case V4L2_CID_FLASH_STROBE: 210 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) { 211 rval = -EBUSY; 212 goto err_out; 213 } 214 flash->led_mode = V4L2_FLASH_LED_MODE_FLASH; 215 rval = lm3560_mode_ctrl(flash); 216 break; 217 218 case V4L2_CID_FLASH_STROBE_STOP: 219 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) { 220 rval = -EBUSY; 221 goto err_out; 222 } 223 flash->led_mode = V4L2_FLASH_LED_MODE_NONE; 224 rval = lm3560_mode_ctrl(flash); 225 break; 226 227 case V4L2_CID_FLASH_TIMEOUT: 228 tout_bits = LM3560_FLASH_TOUT_ms_TO_REG(ctrl->val); 229 rval = regmap_update_bits(flash->regmap, 230 REG_FLASH_TOUT, 0x1f, tout_bits); 231 break; 232 233 case V4L2_CID_FLASH_INTENSITY: 234 rval = lm3560_flash_brt_ctrl(flash, led_no, ctrl->val); 235 break; 236 237 case V4L2_CID_FLASH_TORCH_INTENSITY: 238 rval = lm3560_torch_brt_ctrl(flash, led_no, ctrl->val); 239 break; 240 } 241 242err_out: 243 mutex_unlock(&flash->lock); 244 return rval; 245} 246 247static int lm3560_led1_get_ctrl(struct v4l2_ctrl *ctrl) 248{ 249 return lm3560_get_ctrl(ctrl, LM3560_LED1); 250} 251 252static int lm3560_led1_set_ctrl(struct v4l2_ctrl *ctrl) 253{ 254 return lm3560_set_ctrl(ctrl, LM3560_LED1); 255} 256 257static int lm3560_led0_get_ctrl(struct v4l2_ctrl *ctrl) 258{ 259 return lm3560_get_ctrl(ctrl, LM3560_LED0); 260} 261 262static int lm3560_led0_set_ctrl(struct v4l2_ctrl *ctrl) 263{ 264 return lm3560_set_ctrl(ctrl, LM3560_LED0); 265} 266 267static const struct v4l2_ctrl_ops lm3560_led_ctrl_ops[LM3560_LED_MAX] = { 268 [LM3560_LED0] = { 269 .g_volatile_ctrl = lm3560_led0_get_ctrl, 270 .s_ctrl = lm3560_led0_set_ctrl, 271 }, 272 [LM3560_LED1] = { 273 .g_volatile_ctrl = lm3560_led1_get_ctrl, 274 .s_ctrl = lm3560_led1_set_ctrl, 275 } 276}; 277 278static int lm3560_init_controls(struct lm3560_flash *flash, 279 enum lm3560_led_id led_no) 280{ 281 struct v4l2_ctrl *fault; 282 u32 max_flash_brt = flash->pdata->max_flash_brt[led_no]; 283 u32 max_torch_brt = flash->pdata->max_torch_brt[led_no]; 284 struct v4l2_ctrl_handler *hdl = &flash->ctrls_led[led_no]; 285 const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no]; 286 287 v4l2_ctrl_handler_init(hdl, 8); 288 289 /* flash mode */ 290 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE, 291 V4L2_FLASH_LED_MODE_TORCH, ~0x7, 292 V4L2_FLASH_LED_MODE_NONE); 293 flash->led_mode = V4L2_FLASH_LED_MODE_NONE; 294 295 /* flash source */ 296 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE, 297 0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE); 298 299 /* flash strobe */ 300 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0); 301 302 /* flash strobe stop */ 303 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0); 304 305 /* flash strobe timeout */ 306 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT, 307 LM3560_FLASH_TOUT_MIN, 308 flash->pdata->max_flash_timeout, 309 LM3560_FLASH_TOUT_STEP, 310 flash->pdata->max_flash_timeout); 311 312 /* flash brt */ 313 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY, 314 LM3560_FLASH_BRT_MIN, max_flash_brt, 315 LM3560_FLASH_BRT_STEP, max_flash_brt); 316 317 /* torch brt */ 318 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY, 319 LM3560_TORCH_BRT_MIN, max_torch_brt, 320 LM3560_TORCH_BRT_STEP, max_torch_brt); 321 322 /* fault */ 323 fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0, 324 V4L2_FLASH_FAULT_OVER_VOLTAGE 325 | V4L2_FLASH_FAULT_OVER_TEMPERATURE 326 | V4L2_FLASH_FAULT_SHORT_CIRCUIT 327 | V4L2_FLASH_FAULT_TIMEOUT, 0, 0); 328 if (fault != NULL) 329 fault->flags |= V4L2_CTRL_FLAG_VOLATILE; 330 331 if (hdl->error) 332 return hdl->error; 333 334 flash->subdev_led[led_no].ctrl_handler = hdl; 335 return 0; 336} 337 338/* initialize device */ 339static const struct v4l2_subdev_ops lm3560_ops = { 340 .core = NULL, 341}; 342 343static const struct regmap_config lm3560_regmap = { 344 .reg_bits = 8, 345 .val_bits = 8, 346 .max_register = 0xFF, 347}; 348 349static int lm3560_subdev_init(struct lm3560_flash *flash, 350 enum lm3560_led_id led_no, char *led_name) 351{ 352 struct i2c_client *client = to_i2c_client(flash->dev); 353 int rval; 354 355 v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops); 356 flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 357 strscpy(flash->subdev_led[led_no].name, led_name, 358 sizeof(flash->subdev_led[led_no].name)); 359 rval = lm3560_init_controls(flash, led_no); 360 if (rval) 361 goto err_out; 362 rval = media_entity_pads_init(&flash->subdev_led[led_no].entity, 0, NULL); 363 if (rval < 0) 364 goto err_out; 365 flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH; 366 367 return rval; 368 369err_out: 370 v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); 371 return rval; 372} 373 374static int lm3560_init_device(struct lm3560_flash *flash) 375{ 376 int rval; 377 unsigned int reg_val; 378 379 /* set peak current */ 380 rval = regmap_update_bits(flash->regmap, 381 REG_FLASH_TOUT, 0x60, flash->pdata->peak); 382 if (rval < 0) 383 return rval; 384 /* output disable */ 385 flash->led_mode = V4L2_FLASH_LED_MODE_NONE; 386 rval = lm3560_mode_ctrl(flash); 387 if (rval < 0) 388 return rval; 389 /* reset faults */ 390 rval = regmap_read(flash->regmap, REG_FLAG, ®_val); 391 return rval; 392} 393 394static int lm3560_probe(struct i2c_client *client, 395 const struct i2c_device_id *devid) 396{ 397 struct lm3560_flash *flash; 398 struct lm3560_platform_data *pdata = dev_get_platdata(&client->dev); 399 int rval; 400 401 flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); 402 if (flash == NULL) 403 return -ENOMEM; 404 405 flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap); 406 if (IS_ERR(flash->regmap)) { 407 rval = PTR_ERR(flash->regmap); 408 return rval; 409 } 410 411 /* if there is no platform data, use chip default value */ 412 if (pdata == NULL) { 413 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 414 if (pdata == NULL) 415 return -ENODEV; 416 pdata->peak = LM3560_PEAK_3600mA; 417 pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX; 418 /* led 1 */ 419 pdata->max_flash_brt[LM3560_LED0] = LM3560_FLASH_BRT_MAX; 420 pdata->max_torch_brt[LM3560_LED0] = LM3560_TORCH_BRT_MAX; 421 /* led 2 */ 422 pdata->max_flash_brt[LM3560_LED1] = LM3560_FLASH_BRT_MAX; 423 pdata->max_torch_brt[LM3560_LED1] = LM3560_TORCH_BRT_MAX; 424 } 425 flash->pdata = pdata; 426 flash->dev = &client->dev; 427 mutex_init(&flash->lock); 428 429 rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0"); 430 if (rval < 0) 431 return rval; 432 433 rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1"); 434 if (rval < 0) 435 return rval; 436 437 rval = lm3560_init_device(flash); 438 if (rval < 0) 439 return rval; 440 441 i2c_set_clientdata(client, flash); 442 443 return 0; 444} 445 446static int lm3560_remove(struct i2c_client *client) 447{ 448 struct lm3560_flash *flash = i2c_get_clientdata(client); 449 unsigned int i; 450 451 for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) { 452 v4l2_device_unregister_subdev(&flash->subdev_led[i]); 453 v4l2_ctrl_handler_free(&flash->ctrls_led[i]); 454 media_entity_cleanup(&flash->subdev_led[i].entity); 455 } 456 457 return 0; 458} 459 460static const struct i2c_device_id lm3560_id_table[] = { 461 {LM3559_NAME, 0}, 462 {LM3560_NAME, 0}, 463 {} 464}; 465 466MODULE_DEVICE_TABLE(i2c, lm3560_id_table); 467 468static struct i2c_driver lm3560_i2c_driver = { 469 .driver = { 470 .name = LM3560_NAME, 471 .pm = NULL, 472 }, 473 .probe = lm3560_probe, 474 .remove = lm3560_remove, 475 .id_table = lm3560_id_table, 476}; 477 478module_i2c_driver(lm3560_i2c_driver); 479 480MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); 481MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>"); 482MODULE_DESCRIPTION("Texas Instruments LM3560 LED flash driver"); 483MODULE_LICENSE("GPL");