Lines Matching +full:on +full:- +full:flash
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2008--2011 Nokia Corporation
15 * - fault interrupt handling
16 * - hardware strobe
17 * - power doesn't need to be ON if all lights are off
27 #include <media/v4l2-device.h>
31 #define TIMEOUT_MIN (TIMEOUT_MAX - ADP1653_REG_CONFIG_TMR_SET_MAX \
33 #define TIMEOUT_US_TO_CODE(t) ((TIMEOUT_MAX + (TIMEOUT_STEP / 2) - (t)) \
35 #define TIMEOUT_CODE_TO_US(c) (TIMEOUT_MAX - (c) * TIMEOUT_STEP)
38 static int adp1653_update_hw(struct adp1653_flash *flash) in adp1653_update_hw() argument
40 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); in adp1653_update_hw()
46 flash->indicator_intensity->val) in adp1653_update_hw()
49 switch (flash->led_mode->val) { in adp1653_update_hw()
53 /* Flash mode, light on with strobe, duration from timer */ in adp1653_update_hw()
55 config |= TIMEOUT_US_TO_CODE(flash->flash_timeout->val) in adp1653_update_hw()
59 /* Torch mode, light immediately on, duration indefinite */ in adp1653_update_hw()
61 flash->torch_intensity->val) in adp1653_update_hw()
77 static int adp1653_get_fault(struct adp1653_flash *flash) in adp1653_get_fault() argument
79 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); in adp1653_get_fault()
87 flash->fault |= fault; in adp1653_get_fault()
89 if (!flash->fault) in adp1653_get_fault()
97 flash->led_mode->val = V4L2_FLASH_LED_MODE_NONE; in adp1653_get_fault()
99 rval = adp1653_update_hw(flash); in adp1653_get_fault()
103 return flash->fault; in adp1653_get_fault()
106 static int adp1653_strobe(struct adp1653_flash *flash, int enable) in adp1653_strobe() argument
108 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); in adp1653_strobe()
110 flash->indicator_intensity->val) in adp1653_strobe()
114 if (flash->led_mode->val != V4L2_FLASH_LED_MODE_FLASH) in adp1653_strobe()
115 return -EBUSY; in adp1653_strobe()
122 flash->flash_intensity->val) in adp1653_strobe()
136 /* --------------------------------------------------------------------------
142 struct adp1653_flash *flash = in adp1653_get_ctrl() local
143 container_of(ctrl->handler, struct adp1653_flash, ctrls); in adp1653_get_ctrl()
146 rval = adp1653_get_fault(flash); in adp1653_get_ctrl()
150 ctrl->cur.val = 0; in adp1653_get_ctrl()
152 if (flash->fault & ADP1653_REG_FAULT_FLT_SCP) in adp1653_get_ctrl()
153 ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; in adp1653_get_ctrl()
154 if (flash->fault & ADP1653_REG_FAULT_FLT_OT) in adp1653_get_ctrl()
155 ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; in adp1653_get_ctrl()
156 if (flash->fault & ADP1653_REG_FAULT_FLT_TMR) in adp1653_get_ctrl()
157 ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT; in adp1653_get_ctrl()
158 if (flash->fault & ADP1653_REG_FAULT_FLT_OV) in adp1653_get_ctrl()
159 ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE; in adp1653_get_ctrl()
161 flash->fault = 0; in adp1653_get_ctrl()
168 struct adp1653_flash *flash = in adp1653_set_ctrl() local
169 container_of(ctrl->handler, struct adp1653_flash, ctrls); in adp1653_set_ctrl()
172 rval = adp1653_get_fault(flash); in adp1653_set_ctrl()
178 (ctrl->id == V4L2_CID_FLASH_STROBE || in adp1653_set_ctrl()
179 ctrl->id == V4L2_CID_FLASH_TORCH_INTENSITY || in adp1653_set_ctrl()
180 ctrl->id == V4L2_CID_FLASH_LED_MODE)) in adp1653_set_ctrl()
181 return -EBUSY; in adp1653_set_ctrl()
183 switch (ctrl->id) { in adp1653_set_ctrl()
185 return adp1653_strobe(flash, 1); in adp1653_set_ctrl()
187 return adp1653_strobe(flash, 0); in adp1653_set_ctrl()
190 return adp1653_update_hw(flash); in adp1653_set_ctrl()
198 static int adp1653_init_controls(struct adp1653_flash *flash) in adp1653_init_controls() argument
202 v4l2_ctrl_handler_init(&flash->ctrls, 9); in adp1653_init_controls()
204 flash->led_mode = in adp1653_init_controls()
205 v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
208 v4l2_ctrl_new_std_menu(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
211 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
213 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
215 flash->flash_timeout = in adp1653_init_controls()
216 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
218 flash->platform_data->max_flash_timeout, in adp1653_init_controls()
220 flash->platform_data->max_flash_timeout); in adp1653_init_controls()
221 flash->flash_intensity = in adp1653_init_controls()
222 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
225 flash->platform_data->max_flash_intensity, in adp1653_init_controls()
226 1, flash->platform_data->max_flash_intensity); in adp1653_init_controls()
227 flash->torch_intensity = in adp1653_init_controls()
228 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
231 flash->platform_data->max_torch_intensity, in adp1653_init_controls()
233 flash->platform_data->max_torch_intensity); in adp1653_init_controls()
234 flash->indicator_intensity = in adp1653_init_controls()
235 v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
238 flash->platform_data->max_indicator_intensity, in adp1653_init_controls()
241 fault = v4l2_ctrl_new_std(&flash->ctrls, &adp1653_ctrl_ops, in adp1653_init_controls()
247 if (flash->ctrls.error) in adp1653_init_controls()
248 return flash->ctrls.error; in adp1653_init_controls()
250 fault->flags |= V4L2_CTRL_FLAG_VOLATILE; in adp1653_init_controls()
252 flash->subdev.ctrl_handler = &flash->ctrls; in adp1653_init_controls()
256 /* --------------------------------------------------------------------------
261 adp1653_init_device(struct adp1653_flash *flash) in adp1653_init_device() argument
263 struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev); in adp1653_init_device()
269 dev_err(&client->dev, "failed writing fault register\n"); in adp1653_init_device()
270 return -EIO; in adp1653_init_device()
273 mutex_lock(flash->ctrls.lock); in adp1653_init_device()
275 flash->fault = 0; in adp1653_init_device()
276 rval = adp1653_get_fault(flash); in adp1653_init_device()
277 mutex_unlock(flash->ctrls.lock); in adp1653_init_device()
279 dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval); in adp1653_init_device()
280 return -EIO; in adp1653_init_device()
283 mutex_lock(flash->ctrls.lock); in adp1653_init_device()
284 rval = adp1653_update_hw(flash); in adp1653_init_device()
285 mutex_unlock(flash->ctrls.lock); in adp1653_init_device()
287 dev_err(&client->dev, in adp1653_init_device()
289 return -EIO; in adp1653_init_device()
296 __adp1653_set_power(struct adp1653_flash *flash, int on) in __adp1653_set_power() argument
300 if (flash->platform_data->power) { in __adp1653_set_power()
301 ret = flash->platform_data->power(&flash->subdev, on); in __adp1653_set_power()
305 gpiod_set_value(flash->platform_data->enable_gpio, on); in __adp1653_set_power()
306 if (on) in __adp1653_set_power()
311 if (!on) in __adp1653_set_power()
314 ret = adp1653_init_device(flash); in __adp1653_set_power()
318 if (flash->platform_data->power) in __adp1653_set_power()
319 flash->platform_data->power(&flash->subdev, 0); in __adp1653_set_power()
321 gpiod_set_value(flash->platform_data->enable_gpio, 0); in __adp1653_set_power()
327 adp1653_set_power(struct v4l2_subdev *subdev, int on) in adp1653_set_power() argument
329 struct adp1653_flash *flash = to_adp1653_flash(subdev); in adp1653_set_power() local
332 mutex_lock(&flash->power_lock); in adp1653_set_power()
337 if (flash->power_count == !on) { in adp1653_set_power()
338 ret = __adp1653_set_power(flash, !!on); in adp1653_set_power()
344 flash->power_count += on ? 1 : -1; in adp1653_set_power()
345 WARN_ON(flash->power_count < 0); in adp1653_set_power()
348 mutex_unlock(&flash->power_lock); in adp1653_set_power()
375 /* --------------------------------------------------------------------------
383 struct adp1653_flash *flash = to_adp1653_flash(subdev); in adp1653_suspend() local
385 if (!flash->power_count) in adp1653_suspend()
388 return __adp1653_set_power(flash, 0); in adp1653_suspend()
394 struct adp1653_flash *flash = to_adp1653_flash(subdev); in adp1653_resume() local
396 if (!flash->power_count) in adp1653_resume()
399 return __adp1653_set_power(flash, 1); in adp1653_resume()
410 struct adp1653_flash *flash, in adp1653_of_init() argument
417 pd = devm_kzalloc(&client->dev, sizeof(*pd), GFP_KERNEL); in adp1653_of_init()
419 return -ENOMEM; in adp1653_of_init()
420 flash->platform_data = pd; in adp1653_of_init()
422 node_flash = of_get_child_by_name(node, "flash"); in adp1653_of_init()
424 return -EINVAL; in adp1653_of_init()
426 if (of_property_read_u32(node_flash, "flash-timeout-us", in adp1653_of_init()
427 &pd->max_flash_timeout)) in adp1653_of_init()
430 if (of_property_read_u32(node_flash, "flash-max-microamp", in adp1653_of_init()
431 &pd->max_flash_intensity)) in adp1653_of_init()
434 pd->max_flash_intensity /= 1000; in adp1653_of_init()
436 if (of_property_read_u32(node_flash, "led-max-microamp", in adp1653_of_init()
437 &pd->max_torch_intensity)) in adp1653_of_init()
440 pd->max_torch_intensity /= 1000; in adp1653_of_init()
446 if (of_property_read_u32(node_indicator, "led-max-microamp", in adp1653_of_init()
447 &pd->max_indicator_intensity)) in adp1653_of_init()
453 pd->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW); in adp1653_of_init()
454 if (IS_ERR(pd->enable_gpio)) { in adp1653_of_init()
455 dev_err(&client->dev, "Error getting GPIO\n"); in adp1653_of_init()
456 return PTR_ERR(pd->enable_gpio); in adp1653_of_init()
461 dev_err(&client->dev, "Required property not found\n"); in adp1653_of_init()
464 return -EINVAL; in adp1653_of_init()
470 struct adp1653_flash *flash; in adp1653_probe() local
473 flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); in adp1653_probe()
474 if (flash == NULL) in adp1653_probe()
475 return -ENOMEM; in adp1653_probe()
477 if (client->dev.of_node) { in adp1653_probe()
478 ret = adp1653_of_init(client, flash, client->dev.of_node); in adp1653_probe()
482 if (!client->dev.platform_data) { in adp1653_probe()
483 dev_err(&client->dev, in adp1653_probe()
485 return -EINVAL; in adp1653_probe()
487 flash->platform_data = client->dev.platform_data; in adp1653_probe()
490 mutex_init(&flash->power_lock); in adp1653_probe()
492 v4l2_i2c_subdev_init(&flash->subdev, client, &adp1653_ops); in adp1653_probe()
493 flash->subdev.internal_ops = &adp1653_internal_ops; in adp1653_probe()
494 flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in adp1653_probe()
496 ret = adp1653_init_controls(flash); in adp1653_probe()
500 ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL); in adp1653_probe()
504 flash->subdev.entity.function = MEDIA_ENT_F_FLASH; in adp1653_probe()
509 dev_err(&client->dev, "adp1653: failed to register device\n"); in adp1653_probe()
510 v4l2_ctrl_handler_free(&flash->ctrls); in adp1653_probe()
517 struct adp1653_flash *flash = to_adp1653_flash(subdev); in adp1653_remove() local
519 v4l2_device_unregister_subdev(&flash->subdev); in adp1653_remove()
520 v4l2_ctrl_handler_free(&flash->ctrls); in adp1653_remove()
521 media_entity_cleanup(&flash->subdev.entity); in adp1653_remove()
548 MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");