Commit a40eba9b authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

media: v4l2-flash: Add sanity checks for flash and indicator controls

The V4L2 flash API supports combinations of indicator and flash LEDs. Due
to this, there's a fair amount of code that deals with all the possible
options and just reading one part of the file doesn't really tell which
combinations are really possible.

Make the checks more explicit to keep static analysers happy and to make
the code more resilient to future mishaps.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 41a95d04
......@@ -80,6 +80,7 @@ static void v4l2_flash_set_led_brightness(struct v4l2_flash *v4l2_flash,
struct v4l2_ctrl *ctrl)
{
struct v4l2_ctrl **ctrls = v4l2_flash->ctrls;
struct led_classdev *led_cdev;
enum led_brightness brightness;
if (has_flash_op(v4l2_flash, intensity_to_led_brightness))
......@@ -104,12 +105,18 @@ static void v4l2_flash_set_led_brightness(struct v4l2_flash *v4l2_flash,
if (ctrls[LED_MODE]->val != V4L2_FLASH_LED_MODE_TORCH)
return;
led_set_brightness_sync(&v4l2_flash->fled_cdev->led_cdev,
brightness);
if (WARN_ON_ONCE(!v4l2_flash->fled_cdev))
return;
led_cdev = &v4l2_flash->fled_cdev->led_cdev;
} else {
led_set_brightness_sync(v4l2_flash->iled_cdev,
brightness);
if (WARN_ON_ONCE(!v4l2_flash->iled_cdev))
return;
led_cdev = v4l2_flash->iled_cdev;
}
led_set_brightness_sync(led_cdev, brightness);
}
static int v4l2_flash_update_led_brightness(struct v4l2_flash *v4l2_flash,
......@@ -128,8 +135,15 @@ static int v4l2_flash_update_led_brightness(struct v4l2_flash *v4l2_flash,
*/
if (ctrls[LED_MODE]->val != V4L2_FLASH_LED_MODE_TORCH)
return 0;
if (WARN_ON_ONCE(!v4l2_flash->fled_cdev))
return -EINVAL;
led_cdev = &v4l2_flash->fled_cdev->led_cdev;
} else {
if (WARN_ON_ONCE(!v4l2_flash->iled_cdev))
return -EINVAL;
led_cdev = v4l2_flash->iled_cdev;
}
......@@ -159,6 +173,12 @@ static int v4l2_flash_g_volatile_ctrl(struct v4l2_ctrl *c)
case V4L2_CID_FLASH_TORCH_INTENSITY:
case V4L2_CID_FLASH_INDICATOR_INTENSITY:
return v4l2_flash_update_led_brightness(v4l2_flash, c);
}
if (!fled_cdev)
return -EINVAL;
switch (c->id) {
case V4L2_CID_FLASH_INTENSITY:
ret = led_update_flash_brightness(fled_cdev);
if (ret < 0)
......@@ -194,11 +214,23 @@ static int v4l2_flash_s_ctrl(struct v4l2_ctrl *c)
{
struct v4l2_flash *v4l2_flash = v4l2_ctrl_to_v4l2_flash(c);
struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev;
struct led_classdev *led_cdev = fled_cdev ? &fled_cdev->led_cdev : NULL;
struct led_classdev *led_cdev;
struct v4l2_ctrl **ctrls = v4l2_flash->ctrls;
bool external_strobe;
int ret = 0;
switch (c->id) {
case V4L2_CID_FLASH_TORCH_INTENSITY:
case V4L2_CID_FLASH_INDICATOR_INTENSITY:
v4l2_flash_set_led_brightness(v4l2_flash, c);
return 0;
}
if (!fled_cdev)
return -EINVAL;
led_cdev = &fled_cdev->led_cdev;
switch (c->id) {
case V4L2_CID_FLASH_LED_MODE:
switch (c->val) {
......@@ -268,10 +300,6 @@ static int v4l2_flash_s_ctrl(struct v4l2_ctrl *c)
* microamperes for flash intensity units.
*/
return led_set_flash_brightness(fled_cdev, c->val);
case V4L2_CID_FLASH_TORCH_INTENSITY:
case V4L2_CID_FLASH_INDICATOR_INTENSITY:
v4l2_flash_set_led_brightness(v4l2_flash, c);
return 0;
}
return -EINVAL;
......@@ -492,6 +520,9 @@ static int __sync_device_with_v4l2_controls(struct v4l2_flash *v4l2_flash)
ctrls[INDICATOR_INTENSITY]);
if (ctrls[FLASH_TIMEOUT]) {
if (WARN_ON_ONCE(!fled_cdev))
return -EINVAL;
ret = led_set_flash_timeout(fled_cdev,
ctrls[FLASH_TIMEOUT]->val);
if (ret < 0)
......@@ -499,6 +530,9 @@ static int __sync_device_with_v4l2_controls(struct v4l2_flash *v4l2_flash)
}
if (ctrls[FLASH_INTENSITY]) {
if (WARN_ON_ONCE(!fled_cdev))
return -EINVAL;
ret = led_set_flash_brightness(fled_cdev,
ctrls[FLASH_INTENSITY]->val);
if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment