Lines Matching +full:flash +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-only
4 * General device driver for TI lm3646, Dual FLASH LED Driver
9 * Ldd-Mlp <ldd-mlp@list.ti.com>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-device.h>
61 * @led_mode: V4L2 LED mode
64 * @mode_reg : mode register value
78 container_of(_ctrl->handler, struct lm3646_flash, ctrls_led)
80 /* enable mode control */
81 static int lm3646_mode_ctrl(struct lm3646_flash *flash, in lm3646_mode_ctrl() argument
86 return regmap_write(flash->regmap, in lm3646_mode_ctrl()
87 REG_ENABLE, flash->mode_reg | MODE_SHDN); in lm3646_mode_ctrl()
89 return regmap_write(flash->regmap, in lm3646_mode_ctrl()
90 REG_ENABLE, flash->mode_reg | MODE_TORCH); in lm3646_mode_ctrl()
92 return regmap_write(flash->regmap, in lm3646_mode_ctrl()
93 REG_ENABLE, flash->mode_reg | MODE_FLASH); in lm3646_mode_ctrl()
95 return -EINVAL; in lm3646_mode_ctrl()
101 struct lm3646_flash *flash = to_lm3646_flash(ctrl); in lm3646_get_ctrl() local
105 if (ctrl->id != V4L2_CID_FLASH_FAULT) in lm3646_get_ctrl()
106 return -EINVAL; in lm3646_get_ctrl()
108 rval = regmap_read(flash->regmap, REG_FLAG, &reg_val); in lm3646_get_ctrl()
112 ctrl->val = 0; in lm3646_get_ctrl()
114 ctrl->val |= V4L2_FLASH_FAULT_TIMEOUT; in lm3646_get_ctrl()
116 ctrl->val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; in lm3646_get_ctrl()
118 ctrl->val |= V4L2_FLASH_FAULT_UNDER_VOLTAGE; in lm3646_get_ctrl()
120 ctrl->val |= V4L2_FLASH_FAULT_INPUT_VOLTAGE; in lm3646_get_ctrl()
122 ctrl->val |= V4L2_FLASH_FAULT_OVER_CURRENT; in lm3646_get_ctrl()
124 ctrl->val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; in lm3646_get_ctrl()
126 ctrl->val |= V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE; in lm3646_get_ctrl()
128 ctrl->val |= V4L2_FLASH_FAULT_OVER_VOLTAGE; in lm3646_get_ctrl()
135 struct lm3646_flash *flash = to_lm3646_flash(ctrl); in lm3646_set_ctrl() local
139 switch (ctrl->id) { in lm3646_set_ctrl()
142 if (ctrl->val != V4L2_FLASH_LED_MODE_FLASH) in lm3646_set_ctrl()
143 return lm3646_mode_ctrl(flash, ctrl->val); in lm3646_set_ctrl()
144 /* switch to SHDN mode before flash strobe on */ in lm3646_set_ctrl()
145 return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE); in lm3646_set_ctrl()
148 return regmap_update_bits(flash->regmap, in lm3646_set_ctrl()
150 (ctrl->val) << 7); in lm3646_set_ctrl()
154 /* read and check current mode of chip to start flash */ in lm3646_set_ctrl()
155 rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val); in lm3646_set_ctrl()
158 /* flash on */ in lm3646_set_ctrl()
159 return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_FLASH); in lm3646_set_ctrl()
164 * flash mode will be turned automatically in lm3646_set_ctrl()
165 * from FLASH mode to SHDN mode after flash duration timeout in lm3646_set_ctrl()
166 * read and check current mode of chip to stop flash in lm3646_set_ctrl()
168 rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val); in lm3646_set_ctrl()
172 return lm3646_mode_ctrl(flash, in lm3646_set_ctrl()
177 return regmap_update_bits(flash->regmap, in lm3646_set_ctrl()
180 (ctrl->val)); in lm3646_set_ctrl()
183 return regmap_update_bits(flash->regmap, in lm3646_set_ctrl()
186 (ctrl->val)); in lm3646_set_ctrl()
189 return regmap_update_bits(flash->regmap, in lm3646_set_ctrl()
192 (ctrl->val) << 4); in lm3646_set_ctrl()
195 return -EINVAL; in lm3646_set_ctrl()
203 static int lm3646_init_controls(struct lm3646_flash *flash) in lm3646_init_controls() argument
206 struct v4l2_ctrl_handler *hdl = &flash->ctrls_led; in lm3646_init_controls()
210 /* flash mode */ in lm3646_init_controls()
215 /* flash source */ in lm3646_init_controls()
219 /* flash strobe */ in lm3646_init_controls()
221 /* flash strobe stop */ in lm3646_init_controls()
224 /* flash strobe timeout */ in lm3646_init_controls()
228 LM3646_FLASH_TOUT_STEP, flash->pdata->flash_timeout); in lm3646_init_controls()
230 /* max flash current */ in lm3646_init_controls()
251 fault->flags |= V4L2_CTRL_FLAG_VOLATILE; in lm3646_init_controls()
253 if (hdl->error) in lm3646_init_controls()
254 return hdl->error; in lm3646_init_controls()
256 flash->subdev_led.ctrl_handler = hdl; in lm3646_init_controls()
271 static int lm3646_subdev_init(struct lm3646_flash *flash) in lm3646_subdev_init() argument
273 struct i2c_client *client = to_i2c_client(flash->dev); in lm3646_subdev_init()
276 v4l2_i2c_subdev_init(&flash->subdev_led, client, &lm3646_ops); in lm3646_subdev_init()
277 flash->subdev_led.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in lm3646_subdev_init()
278 strscpy(flash->subdev_led.name, LM3646_NAME, in lm3646_subdev_init()
279 sizeof(flash->subdev_led.name)); in lm3646_subdev_init()
280 rval = lm3646_init_controls(flash); in lm3646_subdev_init()
283 rval = media_entity_pads_init(&flash->subdev_led.entity, 0, NULL); in lm3646_subdev_init()
286 flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH; in lm3646_subdev_init()
290 v4l2_ctrl_handler_free(&flash->ctrls_led); in lm3646_subdev_init()
294 static int lm3646_init_device(struct lm3646_flash *flash) in lm3646_init_device() argument
299 /* read the value of mode register to reduce redundant i2c accesses */ in lm3646_init_device()
300 rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val); in lm3646_init_device()
303 flash->mode_reg = reg_val & 0xfc; in lm3646_init_device()
306 rval = lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE); in lm3646_init_device()
311 * LED1 flash current setting in lm3646_init_device()
312 * LED2 flash current = Total(Max) flash current - LED1 flash current in lm3646_init_device()
314 rval = regmap_update_bits(flash->regmap, in lm3646_init_device()
317 (flash->pdata->led1_flash_brt)); in lm3646_init_device()
324 * LED2 torch current = Total(Max) torch current - LED1 torch current in lm3646_init_device()
326 rval = regmap_update_bits(flash->regmap, in lm3646_init_device()
329 (flash->pdata->led1_torch_brt)); in lm3646_init_device()
334 return regmap_read(flash->regmap, REG_FLAG, &reg_val); in lm3646_init_device()
339 struct lm3646_flash *flash; in lm3646_probe() local
340 struct lm3646_platform_data *pdata = dev_get_platdata(&client->dev); in lm3646_probe()
343 flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); in lm3646_probe()
344 if (flash == NULL) in lm3646_probe()
345 return -ENOMEM; in lm3646_probe()
347 flash->regmap = devm_regmap_init_i2c(client, &lm3646_regmap); in lm3646_probe()
348 if (IS_ERR(flash->regmap)) in lm3646_probe()
349 return PTR_ERR(flash->regmap); in lm3646_probe()
353 pdata = devm_kzalloc(&client->dev, in lm3646_probe()
357 return -ENOMEM; in lm3646_probe()
359 pdata->flash_timeout = LM3646_FLASH_TOUT_MAX; in lm3646_probe()
360 pdata->led1_torch_brt = LM3646_LED1_TORCH_BRT_MAX; in lm3646_probe()
361 pdata->led1_flash_brt = LM3646_LED1_FLASH_BRT_MAX; in lm3646_probe()
363 flash->pdata = pdata; in lm3646_probe()
364 flash->dev = &client->dev; in lm3646_probe()
366 rval = lm3646_subdev_init(flash); in lm3646_probe()
370 rval = lm3646_init_device(flash); in lm3646_probe()
374 i2c_set_clientdata(client, flash); in lm3646_probe()
381 struct lm3646_flash *flash = i2c_get_clientdata(client); in lm3646_remove() local
383 v4l2_device_unregister_subdev(&flash->subdev_led); in lm3646_remove()
384 v4l2_ctrl_handler_free(&flash->ctrls_led); in lm3646_remove()
385 media_entity_cleanup(&flash->subdev_led.entity); in lm3646_remove()
407 MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>");
408 MODULE_DESCRIPTION("Texas Instruments LM3646 Dual Flash LED driver");