Loading arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi +0 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ qcom,torch-seq-val = <1 0>; qcom,flash-seq-val = <0 1>; qcom,duty-cycle = <0 30>; qcom,clk-freq = <0 150000>; linux,name = "flashlight"; linux,default-trigger = "flashlight-trigger"; }; Loading drivers/media/platform/msm/camera_v2/sensor/flash/Makefile +3 −0 Original line number Diff line number Diff line Loading @@ -2,5 +2,8 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci ccflags-y += -Idrivers/media/platform/msm/camera_v2 ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io obj-$(CONFIG_MSMB_CAMERA) += msm_led_flash.o obj-$(CONFIG_MSMB_CAMERA) += msm_led_trigger.o obj-$(CONFIG_MSMB_CAMERA) += msm_led_torch.o obj-$(CONFIG_MSMB_CAMERA) += msm_flash.o obj-$(CONFIG_MSMB_CAMERA) += qm215_gpio_flash.o drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c 0 → 100644 +126 −0 Original line number Diff line number Diff line /* Copyright (c) 2009-2014, 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ #include "msm_led_flash.h" #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) static struct v4l2_file_operations msm_led_flash_v4l2_subdev_fops; static long msm_led_flash_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct msm_led_flash_ctrl_t *fctrl = NULL; if (!sd) { pr_err("sd NULL\n"); return -EINVAL; } fctrl = v4l2_get_subdevdata(sd); if (!fctrl) { pr_err("fctrl NULL\n"); return -EINVAL; } switch (cmd) { case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID: return fctrl->func_tbl->flash_get_subdev_id(fctrl, arg); case VIDIOC_MSM_FLASH_LED_DATA_CFG: return fctrl->func_tbl->flash_led_config(fctrl, arg); case MSM_SD_NOTIFY_FREEZE: return 0; case MSM_SD_SHUTDOWN: *(int *)arg = MSM_CAMERA_LED_RELEASE; return fctrl->func_tbl->flash_led_config(fctrl, arg); default: pr_err_ratelimited("invalid cmd %d\n", cmd); return -ENOIOCTLCMD; } } static struct v4l2_subdev_core_ops msm_flash_subdev_core_ops = { .ioctl = msm_led_flash_subdev_ioctl, }; static struct v4l2_subdev_ops msm_flash_subdev_ops = { .core = &msm_flash_subdev_core_ops, }; static const struct v4l2_subdev_internal_ops msm_flash_internal_ops; int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev, void *data) { struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; CDBG("Enter\n"); if (!fctrl) { pr_err("fctrl NULL\n"); return -EINVAL; } /* Initialize sub device */ v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops); v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl); fctrl->pdev = pdev; fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops; fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name), "msm_flash"); media_entity_pads_init(&fctrl->msm_sd.sd.entity, 0, NULL); fctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LED_FLASH; fctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1; msm_sd_register(&fctrl->msm_sd); msm_led_flash_v4l2_subdev_fops = v4l2_subdev_fops; #ifdef CONFIG_COMPAT msm_led_flash_v4l2_subdev_fops.compat_ioctl32 = msm_led_flash_v4l2_subdev_fops.unlocked_ioctl; #endif fctrl->msm_sd.sd.devnode->fops = &msm_led_flash_v4l2_subdev_fops; CDBG("probe success\n"); return 0; } int32_t msm_led_i2c_flash_create_v4lsubdev(void *data) { struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; CDBG("Enter\n"); if (!fctrl) { pr_err("fctrl NULL\n"); return -EINVAL; } /* Initialize sub device */ v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops); v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl); fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops; fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name), "msm_flash"); media_entity_pads_init(&fctrl->msm_sd.sd.entity, 0, NULL); fctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LED_FLASH; msm_sd_register(&fctrl->msm_sd); msm_led_flash_v4l2_subdev_fops = v4l2_subdev_fops; fctrl->msm_sd.sd.devnode->fops = &msm_led_flash_v4l2_subdev_fops; CDBG("probe success\n"); return 0; } drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h 0 → 100644 +98 −0 Original line number Diff line number Diff line /* Copyright (c) 2009-2014, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #ifndef MSM_LED_FLASH_H #define MSM_LED_FLASH_H #include <linux/leds.h> #include <linux/platform_device.h> #include <media/v4l2-subdev.h> #include <media/msm_cam_sensor.h> #include <soc/qcom/camera2.h> #include "msm_camera_i2c.h" #include "msm_sd.h" struct msm_led_flash_ctrl_t; struct msm_flash_fn_t { int32_t (*flash_get_subdev_id)(struct msm_led_flash_ctrl_t *, void *); int32_t (*flash_led_config)(struct msm_led_flash_ctrl_t *, void *); int32_t (*flash_led_init)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_release)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_off)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_low)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_high)(struct msm_led_flash_ctrl_t *); }; struct msm_led_flash_reg_t { struct msm_camera_i2c_reg_setting *init_setting; struct msm_camera_i2c_reg_setting *off_setting; struct msm_camera_i2c_reg_setting *release_setting; struct msm_camera_i2c_reg_setting *low_setting; struct msm_camera_i2c_reg_setting *high_setting; }; struct msm_led_flash_ctrl_t { struct msm_camera_i2c_client *flash_i2c_client; struct msm_sd_subdev msm_sd; struct platform_device *pdev; struct msm_flash_fn_t *func_tbl; struct msm_camera_sensor_board_info *flashdata; struct msm_led_flash_reg_t *reg_setting; /* Flash */ const char *flash_trigger_name[MAX_LED_TRIGGERS]; struct led_trigger *flash_trigger[MAX_LED_TRIGGERS]; uint32_t flash_num_sources; uint32_t flash_op_current[MAX_LED_TRIGGERS]; uint32_t flash_max_current[MAX_LED_TRIGGERS]; uint32_t flash_max_duration[MAX_LED_TRIGGERS]; /* Torch */ const char *torch_trigger_name[MAX_LED_TRIGGERS]; struct led_trigger *torch_trigger[MAX_LED_TRIGGERS]; uint32_t torch_num_sources; uint32_t torch_op_current[MAX_LED_TRIGGERS]; uint32_t torch_max_current[MAX_LED_TRIGGERS]; void *data; enum msm_camera_device_type_t flash_device_type; enum cci_i2c_master_t cci_i2c_master; enum msm_camera_led_config_t led_state; uint32_t subdev_id; struct msm_pinctrl_info pinctrl_info; }; int msm_flash_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); int msm_flash_probe(struct platform_device *pdev, const void *data); int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev, void *data); int32_t msm_led_torch_create_classdev(struct platform_device *pdev, void *data); int32_t msm_led_i2c_flash_create_v4lsubdev(void *data); int32_t msm_led_i2c_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl, void *arg); int32_t msm_led_i2c_trigger_config(struct msm_led_flash_ctrl_t *fctrl, void *data); int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_off(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_low(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_high(struct msm_led_flash_ctrl_t *fctrl); #endif drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c 0 → 100644 +83 −0 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ #include <linux/module.h> #include "msm_led_flash.h" static struct led_trigger *torch_trigger; static void msm_led_torch_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) { if (!torch_trigger) { pr_err("No torch trigger found, can't set brightness\n"); return; } led_trigger_event(torch_trigger, value); }; static struct led_classdev msm_torch_led[MAX_LED_TRIGGERS] = { { .name = "flashlight", .brightness_set = msm_led_torch_brightness_set, .brightness = LED_OFF, }, { .name = "torch-light1", .brightness_set = msm_led_torch_brightness_set, .brightness = LED_OFF, }, { .name = "torch-light2", .brightness_set = msm_led_torch_brightness_set, .brightness = LED_OFF, }, }; int32_t msm_led_torch_create_classdev(struct platform_device *pdev, void *data) { int32_t i, rc = 0; struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; if (!fctrl) { pr_err("Invalid fctrl\n"); return -EINVAL; } for (i = 0; i < fctrl->torch_num_sources; i++) { if (fctrl->torch_trigger[i]) { torch_trigger = fctrl->torch_trigger[i]; msm_torch_led[i].flags |= LED_KEEP_TRIGGER; msm_led_torch_brightness_set(&msm_torch_led[i], LED_OFF); rc = led_classdev_register(&pdev->dev, &msm_torch_led[i]); if (rc) { pr_err("Failed to register %d led dev. rc = %d\n", i, rc); return rc; } } else { pr_err("Invalid fctrl->torch_trigger[%d]\n", i); return -EINVAL; } } return 0; }; Loading
arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi +0 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ qcom,torch-seq-val = <1 0>; qcom,flash-seq-val = <0 1>; qcom,duty-cycle = <0 30>; qcom,clk-freq = <0 150000>; linux,name = "flashlight"; linux,default-trigger = "flashlight-trigger"; }; Loading
drivers/media/platform/msm/camera_v2/sensor/flash/Makefile +3 −0 Original line number Diff line number Diff line Loading @@ -2,5 +2,8 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci ccflags-y += -Idrivers/media/platform/msm/camera_v2 ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io obj-$(CONFIG_MSMB_CAMERA) += msm_led_flash.o obj-$(CONFIG_MSMB_CAMERA) += msm_led_trigger.o obj-$(CONFIG_MSMB_CAMERA) += msm_led_torch.o obj-$(CONFIG_MSMB_CAMERA) += msm_flash.o obj-$(CONFIG_MSMB_CAMERA) += qm215_gpio_flash.o
drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c 0 → 100644 +126 −0 Original line number Diff line number Diff line /* Copyright (c) 2009-2014, 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ #include "msm_led_flash.h" #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) static struct v4l2_file_operations msm_led_flash_v4l2_subdev_fops; static long msm_led_flash_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct msm_led_flash_ctrl_t *fctrl = NULL; if (!sd) { pr_err("sd NULL\n"); return -EINVAL; } fctrl = v4l2_get_subdevdata(sd); if (!fctrl) { pr_err("fctrl NULL\n"); return -EINVAL; } switch (cmd) { case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID: return fctrl->func_tbl->flash_get_subdev_id(fctrl, arg); case VIDIOC_MSM_FLASH_LED_DATA_CFG: return fctrl->func_tbl->flash_led_config(fctrl, arg); case MSM_SD_NOTIFY_FREEZE: return 0; case MSM_SD_SHUTDOWN: *(int *)arg = MSM_CAMERA_LED_RELEASE; return fctrl->func_tbl->flash_led_config(fctrl, arg); default: pr_err_ratelimited("invalid cmd %d\n", cmd); return -ENOIOCTLCMD; } } static struct v4l2_subdev_core_ops msm_flash_subdev_core_ops = { .ioctl = msm_led_flash_subdev_ioctl, }; static struct v4l2_subdev_ops msm_flash_subdev_ops = { .core = &msm_flash_subdev_core_ops, }; static const struct v4l2_subdev_internal_ops msm_flash_internal_ops; int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev, void *data) { struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; CDBG("Enter\n"); if (!fctrl) { pr_err("fctrl NULL\n"); return -EINVAL; } /* Initialize sub device */ v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops); v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl); fctrl->pdev = pdev; fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops; fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name), "msm_flash"); media_entity_pads_init(&fctrl->msm_sd.sd.entity, 0, NULL); fctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LED_FLASH; fctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1; msm_sd_register(&fctrl->msm_sd); msm_led_flash_v4l2_subdev_fops = v4l2_subdev_fops; #ifdef CONFIG_COMPAT msm_led_flash_v4l2_subdev_fops.compat_ioctl32 = msm_led_flash_v4l2_subdev_fops.unlocked_ioctl; #endif fctrl->msm_sd.sd.devnode->fops = &msm_led_flash_v4l2_subdev_fops; CDBG("probe success\n"); return 0; } int32_t msm_led_i2c_flash_create_v4lsubdev(void *data) { struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; CDBG("Enter\n"); if (!fctrl) { pr_err("fctrl NULL\n"); return -EINVAL; } /* Initialize sub device */ v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops); v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl); fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops; fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name), "msm_flash"); media_entity_pads_init(&fctrl->msm_sd.sd.entity, 0, NULL); fctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LED_FLASH; msm_sd_register(&fctrl->msm_sd); msm_led_flash_v4l2_subdev_fops = v4l2_subdev_fops; fctrl->msm_sd.sd.devnode->fops = &msm_led_flash_v4l2_subdev_fops; CDBG("probe success\n"); return 0; }
drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h 0 → 100644 +98 −0 Original line number Diff line number Diff line /* Copyright (c) 2009-2014, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #ifndef MSM_LED_FLASH_H #define MSM_LED_FLASH_H #include <linux/leds.h> #include <linux/platform_device.h> #include <media/v4l2-subdev.h> #include <media/msm_cam_sensor.h> #include <soc/qcom/camera2.h> #include "msm_camera_i2c.h" #include "msm_sd.h" struct msm_led_flash_ctrl_t; struct msm_flash_fn_t { int32_t (*flash_get_subdev_id)(struct msm_led_flash_ctrl_t *, void *); int32_t (*flash_led_config)(struct msm_led_flash_ctrl_t *, void *); int32_t (*flash_led_init)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_release)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_off)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_low)(struct msm_led_flash_ctrl_t *); int32_t (*flash_led_high)(struct msm_led_flash_ctrl_t *); }; struct msm_led_flash_reg_t { struct msm_camera_i2c_reg_setting *init_setting; struct msm_camera_i2c_reg_setting *off_setting; struct msm_camera_i2c_reg_setting *release_setting; struct msm_camera_i2c_reg_setting *low_setting; struct msm_camera_i2c_reg_setting *high_setting; }; struct msm_led_flash_ctrl_t { struct msm_camera_i2c_client *flash_i2c_client; struct msm_sd_subdev msm_sd; struct platform_device *pdev; struct msm_flash_fn_t *func_tbl; struct msm_camera_sensor_board_info *flashdata; struct msm_led_flash_reg_t *reg_setting; /* Flash */ const char *flash_trigger_name[MAX_LED_TRIGGERS]; struct led_trigger *flash_trigger[MAX_LED_TRIGGERS]; uint32_t flash_num_sources; uint32_t flash_op_current[MAX_LED_TRIGGERS]; uint32_t flash_max_current[MAX_LED_TRIGGERS]; uint32_t flash_max_duration[MAX_LED_TRIGGERS]; /* Torch */ const char *torch_trigger_name[MAX_LED_TRIGGERS]; struct led_trigger *torch_trigger[MAX_LED_TRIGGERS]; uint32_t torch_num_sources; uint32_t torch_op_current[MAX_LED_TRIGGERS]; uint32_t torch_max_current[MAX_LED_TRIGGERS]; void *data; enum msm_camera_device_type_t flash_device_type; enum cci_i2c_master_t cci_i2c_master; enum msm_camera_led_config_t led_state; uint32_t subdev_id; struct msm_pinctrl_info pinctrl_info; }; int msm_flash_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); int msm_flash_probe(struct platform_device *pdev, const void *data); int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev, void *data); int32_t msm_led_torch_create_classdev(struct platform_device *pdev, void *data); int32_t msm_led_i2c_flash_create_v4lsubdev(void *data); int32_t msm_led_i2c_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl, void *arg); int32_t msm_led_i2c_trigger_config(struct msm_led_flash_ctrl_t *fctrl, void *data); int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_off(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_low(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_high(struct msm_led_flash_ctrl_t *fctrl); #endif
drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c 0 → 100644 +83 −0 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ #include <linux/module.h> #include "msm_led_flash.h" static struct led_trigger *torch_trigger; static void msm_led_torch_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) { if (!torch_trigger) { pr_err("No torch trigger found, can't set brightness\n"); return; } led_trigger_event(torch_trigger, value); }; static struct led_classdev msm_torch_led[MAX_LED_TRIGGERS] = { { .name = "flashlight", .brightness_set = msm_led_torch_brightness_set, .brightness = LED_OFF, }, { .name = "torch-light1", .brightness_set = msm_led_torch_brightness_set, .brightness = LED_OFF, }, { .name = "torch-light2", .brightness_set = msm_led_torch_brightness_set, .brightness = LED_OFF, }, }; int32_t msm_led_torch_create_classdev(struct platform_device *pdev, void *data) { int32_t i, rc = 0; struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; if (!fctrl) { pr_err("Invalid fctrl\n"); return -EINVAL; } for (i = 0; i < fctrl->torch_num_sources; i++) { if (fctrl->torch_trigger[i]) { torch_trigger = fctrl->torch_trigger[i]; msm_torch_led[i].flags |= LED_KEEP_TRIGGER; msm_led_torch_brightness_set(&msm_torch_led[i], LED_OFF); rc = led_classdev_register(&pdev->dev, &msm_torch_led[i]); if (rc) { pr_err("Failed to register %d led dev. rc = %d\n", i, rc); return rc; } } else { pr_err("Invalid fctrl->torch_trigger[%d]\n", i); return -EINVAL; } } return 0; };