Loading drivers/media/platform/msm/camera/cam_sensor_module/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -3,3 +3,4 @@ obj-$(CONFIG_SPECTRA_CAMERA) += cam_cci/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_io/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_csiphy/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_actuator/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor/ drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/Makefile 0 → 100644 +8 −0 Original line number Diff line number Diff line ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_dev.o cam_sensor_core.o cam_sensor_soc.o drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c 0 → 100644 +1002 −0 File added.Preview size limit exceeded, changes collapsed. Show changes drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.h 0 → 100644 +77 −0 Original line number Diff line number Diff line /* Copyright (c) 2017, 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 _CAM_SENSOR_CORE_H_ #define _CAM_SENSOR_CORE_H_ #include "cam_sensor_dev.h" /** * @s_ctrl: Sensor ctrl structure * * This API powers up the camera sensor module */ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl); /** * @s_ctrl: Sensor ctrl structure * * This API powers down the camera sensor module */ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl); /** * @sd: V4L2 subdevice * @on: Turn off/on flag * * This API powers down the sensor module */ int cam_sensor_power(struct v4l2_subdev *sd, int on); /** * @s_ctrl: Sensor ctrl structure * @req_id: Request id * * This API applies the req_id settings to sensor */ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl, int64_t req_id); /** * @apply: Req mgr structure for applying request * * This API applies the request that is mentioned */ int cam_sensor_apply_request(struct cam_req_mgr_apply_request *apply); /** * @info: Sub device info to req mgr * * Publish the subdevice info */ int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info); /** * @link: Link setup info * * This API establishes link with sensor subdevice with req mgr */ int cam_sensor_establish_link(struct cam_req_mgr_core_dev_link_setup *link); /** * @s_ctrl: Sensor ctrl structure * @arg: Camera control command argument * * This API handles the camera control argument reached to sensor */ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, void *arg); #endif /* _CAM_SENSOR_CORE_H_ */ drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c 0 → 100644 +294 −0 Original line number Diff line number Diff line /* Copyright (c) 2017, 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. */ #include "cam_sensor_dev.h" #include "cam_req_mgr_dev.h" #include "cam_sensor_soc.h" #include "cam_sensor_core.h" static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int rc = 0; struct cam_sensor_ctrl_t *s_ctrl = v4l2_get_subdevdata(sd); switch (cmd) { case VIDIOC_CAM_CONTROL: rc = cam_sensor_driver_cmd(s_ctrl, arg); break; default: pr_err("%s:%d Invalid ioctl cmd: %d\n", __func__, __LINE__, cmd); rc = -EINVAL; break; } return rc; } static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int32_t rc = 0; struct cam_sensor_ctrl_t *s_ctrl; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s %s :Error: i2c_check_functionality failed\n", __func__, client->name); return -EFAULT; } /* Create sensor control structure */ s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL); if (!s_ctrl) return -ENOMEM; i2c_set_clientdata(client, s_ctrl); /* Initialize sensor device type */ s_ctrl->of_node = client->dev.of_node; s_ctrl->io_master_info.master_type = I2C_MASTER; rc = cam_sensor_parse_dt(s_ctrl); if (rc < 0) { pr_err("%s:%d :Error: cam_sensor_parse_dt rc %d", __func__, __LINE__, rc); goto free_s_ctrl; } return rc; free_s_ctrl: kfree(s_ctrl); return rc; } static int cam_sensor_platform_remove(struct platform_device *pdev) { struct cam_sensor_ctrl_t *s_ctrl; s_ctrl = platform_get_drvdata(pdev); if (!s_ctrl) { pr_err("%s: sensor device is NULL\n", __func__); return 0; } kfree(s_ctrl->i2c_data.per_frame); devm_kfree(&pdev->dev, s_ctrl); return 0; } static int cam_sensor_driver_i2c_remove(struct i2c_client *client) { struct cam_sensor_ctrl_t *s_ctrl = i2c_get_clientdata(client); if (!s_ctrl) { pr_err("%s: sensor device is NULL\n", __func__); return 0; } kfree(s_ctrl->i2c_data.per_frame); kfree(s_ctrl); return 0; } #ifdef CONFIG_COMPAT static long cam_sensor_init_subdev_do_ioctl(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg) { struct cam_control cmd_data; int32_t rc = 0; if (copy_from_user(&cmd_data, (void __user *)arg, sizeof(cmd_data))) { pr_err("Failed to copy from user_ptr=%pK size=%zu\n", (void __user *)arg, sizeof(cmd_data)); return -EFAULT; } switch (cmd) { case VIDIOC_CAM_CONTROL: rc = cam_sensor_subdev_ioctl(sd, cmd, &cmd_data); if (rc < 0) pr_err("%s:%d cam_sensor_subdev_ioctl failed\n", __func__, __LINE__); break; default: pr_err("%s:%d Invalid compat ioctl cmd_type: %d\n", __func__, __LINE__, cmd); rc = -EINVAL; } if (!rc) { if (copy_to_user((void __user *)arg, &cmd_data, sizeof(cmd_data))) { pr_err("Failed to copy to user_ptr=%pK size=%zu\n", (void __user *)arg, sizeof(cmd_data)); rc = -EFAULT; } } return rc; } #endif static struct v4l2_subdev_core_ops cam_sensor_subdev_core_ops = { .ioctl = cam_sensor_subdev_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = cam_sensor_init_subdev_do_ioctl, #endif .s_power = cam_sensor_power, }; static struct v4l2_subdev_ops cam_sensor_subdev_ops = { .core = &cam_sensor_subdev_core_ops, }; static const struct v4l2_subdev_internal_ops cam_sensor_internal_ops; static const struct of_device_id cam_sensor_driver_dt_match[] = { {.compatible = "qcom,cam-sensor"}, {} }; static int32_t cam_sensor_driver_platform_probe( struct platform_device *pdev) { int32_t rc = 0, i = 0; struct cam_sensor_ctrl_t *s_ctrl = NULL; /* Create sensor control structure */ s_ctrl = devm_kzalloc(&pdev->dev, sizeof(struct cam_sensor_ctrl_t), GFP_KERNEL); if (!s_ctrl) return -ENOMEM; /* Initialize sensor device type */ s_ctrl->of_node = pdev->dev.of_node; s_ctrl->is_probe_succeed = 0; /*fill in platform device*/ s_ctrl->pdev = pdev; s_ctrl->io_master_info.master_type = CCI_MASTER; rc = cam_sensor_parse_dt(s_ctrl); if (rc < 0) { pr_err("failed: cam_sensor_parse_dt rc %d", rc); goto free_s_ctrl; } /* Fill platform device id*/ pdev->id = s_ctrl->id; s_ctrl->v4l2_dev_str.internal_ops = &cam_sensor_internal_ops; s_ctrl->v4l2_dev_str.ops = &cam_sensor_subdev_ops; strlcpy(s_ctrl->device_name, CAMX_SENSOR_DEV_NAME, sizeof(s_ctrl->device_name)); s_ctrl->v4l2_dev_str.name = s_ctrl->device_name; s_ctrl->v4l2_dev_str.sd_flags = (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); s_ctrl->v4l2_dev_str.ent_function = CAM_SENSOR_DEVICE_TYPE; s_ctrl->v4l2_dev_str.token = s_ctrl; rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str)); if (rc < 0) { pr_err("%s:%d :ERROR: Fail with cam_register_subdev\n", __func__, __LINE__); goto free_s_ctrl; } s_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) kzalloc(sizeof(struct i2c_settings_array) * MAX_PER_FRAME_ARRAY, GFP_KERNEL); if (s_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto free_s_ctrl; } INIT_LIST_HEAD(&(s_ctrl->i2c_data.init_settings.list_head)); for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head)); s_ctrl->bridge_intf.device_hdl = -1; s_ctrl->bridge_intf.ops.get_dev_info = cam_sensor_publish_dev_info; s_ctrl->bridge_intf.ops.link_setup = cam_sensor_establish_link; s_ctrl->bridge_intf.ops.apply_req = cam_sensor_apply_request; s_ctrl->sensordata->power_info.dev = &pdev->dev; platform_set_drvdata(pdev, s_ctrl); v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), s_ctrl); return rc; free_s_ctrl: devm_kfree(&pdev->dev, s_ctrl); return rc; } MODULE_DEVICE_TABLE(of, cam_sensor_driver_dt_match); static struct platform_driver cam_sensor_platform_driver = { .probe = cam_sensor_driver_platform_probe, .driver = { .name = "qcom,camera", .owner = THIS_MODULE, .of_match_table = cam_sensor_driver_dt_match, }, .remove = cam_sensor_platform_remove, }; static const struct i2c_device_id i2c_id[] = { {SENSOR_DRIVER_I2C, (kernel_ulong_t)NULL}, { } }; static struct i2c_driver cam_sensor_driver_i2c = { .id_table = i2c_id, .probe = cam_sensor_driver_i2c_probe, .remove = cam_sensor_driver_i2c_remove, .driver = { .name = SENSOR_DRIVER_I2C, }, }; static int __init cam_sensor_driver_init(void) { int32_t rc = 0; rc = platform_driver_register(&cam_sensor_platform_driver); if (rc) pr_err("%s platform_driver_register failed rc = %d", __func__, rc); rc = i2c_add_driver(&cam_sensor_driver_i2c); if (rc) pr_err("%s i2c_add_driver failed rc = %d", __func__, rc); return rc; } static void __exit cam_sensor_driver_exit(void) { platform_driver_unregister(&cam_sensor_platform_driver); i2c_del_driver(&cam_sensor_driver_i2c); } module_init(cam_sensor_driver_init); module_exit(cam_sensor_driver_exit); MODULE_DESCRIPTION("cam_sensor_driver"); MODULE_LICENSE("GPL v2"); Loading
drivers/media/platform/msm/camera/cam_sensor_module/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -3,3 +3,4 @@ obj-$(CONFIG_SPECTRA_CAMERA) += cam_cci/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_io/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_csiphy/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_actuator/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor/
drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/Makefile 0 → 100644 +8 −0 Original line number Diff line number Diff line ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr ccflags-y += -Idrivers/media/platform/msm/camera/cam_sensor_module/cam_cci obj-$(CONFIG_SPECTRA_CAMERA) += cam_sensor_dev.o cam_sensor_core.o cam_sensor_soc.o
drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c 0 → 100644 +1002 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.h 0 → 100644 +77 −0 Original line number Diff line number Diff line /* Copyright (c) 2017, 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 _CAM_SENSOR_CORE_H_ #define _CAM_SENSOR_CORE_H_ #include "cam_sensor_dev.h" /** * @s_ctrl: Sensor ctrl structure * * This API powers up the camera sensor module */ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl); /** * @s_ctrl: Sensor ctrl structure * * This API powers down the camera sensor module */ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl); /** * @sd: V4L2 subdevice * @on: Turn off/on flag * * This API powers down the sensor module */ int cam_sensor_power(struct v4l2_subdev *sd, int on); /** * @s_ctrl: Sensor ctrl structure * @req_id: Request id * * This API applies the req_id settings to sensor */ int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl, int64_t req_id); /** * @apply: Req mgr structure for applying request * * This API applies the request that is mentioned */ int cam_sensor_apply_request(struct cam_req_mgr_apply_request *apply); /** * @info: Sub device info to req mgr * * Publish the subdevice info */ int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info); /** * @link: Link setup info * * This API establishes link with sensor subdevice with req mgr */ int cam_sensor_establish_link(struct cam_req_mgr_core_dev_link_setup *link); /** * @s_ctrl: Sensor ctrl structure * @arg: Camera control command argument * * This API handles the camera control argument reached to sensor */ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, void *arg); #endif /* _CAM_SENSOR_CORE_H_ */
drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_dev.c 0 → 100644 +294 −0 Original line number Diff line number Diff line /* Copyright (c) 2017, 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. */ #include "cam_sensor_dev.h" #include "cam_req_mgr_dev.h" #include "cam_sensor_soc.h" #include "cam_sensor_core.h" static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int rc = 0; struct cam_sensor_ctrl_t *s_ctrl = v4l2_get_subdevdata(sd); switch (cmd) { case VIDIOC_CAM_CONTROL: rc = cam_sensor_driver_cmd(s_ctrl, arg); break; default: pr_err("%s:%d Invalid ioctl cmd: %d\n", __func__, __LINE__, cmd); rc = -EINVAL; break; } return rc; } static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int32_t rc = 0; struct cam_sensor_ctrl_t *s_ctrl; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s %s :Error: i2c_check_functionality failed\n", __func__, client->name); return -EFAULT; } /* Create sensor control structure */ s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL); if (!s_ctrl) return -ENOMEM; i2c_set_clientdata(client, s_ctrl); /* Initialize sensor device type */ s_ctrl->of_node = client->dev.of_node; s_ctrl->io_master_info.master_type = I2C_MASTER; rc = cam_sensor_parse_dt(s_ctrl); if (rc < 0) { pr_err("%s:%d :Error: cam_sensor_parse_dt rc %d", __func__, __LINE__, rc); goto free_s_ctrl; } return rc; free_s_ctrl: kfree(s_ctrl); return rc; } static int cam_sensor_platform_remove(struct platform_device *pdev) { struct cam_sensor_ctrl_t *s_ctrl; s_ctrl = platform_get_drvdata(pdev); if (!s_ctrl) { pr_err("%s: sensor device is NULL\n", __func__); return 0; } kfree(s_ctrl->i2c_data.per_frame); devm_kfree(&pdev->dev, s_ctrl); return 0; } static int cam_sensor_driver_i2c_remove(struct i2c_client *client) { struct cam_sensor_ctrl_t *s_ctrl = i2c_get_clientdata(client); if (!s_ctrl) { pr_err("%s: sensor device is NULL\n", __func__); return 0; } kfree(s_ctrl->i2c_data.per_frame); kfree(s_ctrl); return 0; } #ifdef CONFIG_COMPAT static long cam_sensor_init_subdev_do_ioctl(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg) { struct cam_control cmd_data; int32_t rc = 0; if (copy_from_user(&cmd_data, (void __user *)arg, sizeof(cmd_data))) { pr_err("Failed to copy from user_ptr=%pK size=%zu\n", (void __user *)arg, sizeof(cmd_data)); return -EFAULT; } switch (cmd) { case VIDIOC_CAM_CONTROL: rc = cam_sensor_subdev_ioctl(sd, cmd, &cmd_data); if (rc < 0) pr_err("%s:%d cam_sensor_subdev_ioctl failed\n", __func__, __LINE__); break; default: pr_err("%s:%d Invalid compat ioctl cmd_type: %d\n", __func__, __LINE__, cmd); rc = -EINVAL; } if (!rc) { if (copy_to_user((void __user *)arg, &cmd_data, sizeof(cmd_data))) { pr_err("Failed to copy to user_ptr=%pK size=%zu\n", (void __user *)arg, sizeof(cmd_data)); rc = -EFAULT; } } return rc; } #endif static struct v4l2_subdev_core_ops cam_sensor_subdev_core_ops = { .ioctl = cam_sensor_subdev_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = cam_sensor_init_subdev_do_ioctl, #endif .s_power = cam_sensor_power, }; static struct v4l2_subdev_ops cam_sensor_subdev_ops = { .core = &cam_sensor_subdev_core_ops, }; static const struct v4l2_subdev_internal_ops cam_sensor_internal_ops; static const struct of_device_id cam_sensor_driver_dt_match[] = { {.compatible = "qcom,cam-sensor"}, {} }; static int32_t cam_sensor_driver_platform_probe( struct platform_device *pdev) { int32_t rc = 0, i = 0; struct cam_sensor_ctrl_t *s_ctrl = NULL; /* Create sensor control structure */ s_ctrl = devm_kzalloc(&pdev->dev, sizeof(struct cam_sensor_ctrl_t), GFP_KERNEL); if (!s_ctrl) return -ENOMEM; /* Initialize sensor device type */ s_ctrl->of_node = pdev->dev.of_node; s_ctrl->is_probe_succeed = 0; /*fill in platform device*/ s_ctrl->pdev = pdev; s_ctrl->io_master_info.master_type = CCI_MASTER; rc = cam_sensor_parse_dt(s_ctrl); if (rc < 0) { pr_err("failed: cam_sensor_parse_dt rc %d", rc); goto free_s_ctrl; } /* Fill platform device id*/ pdev->id = s_ctrl->id; s_ctrl->v4l2_dev_str.internal_ops = &cam_sensor_internal_ops; s_ctrl->v4l2_dev_str.ops = &cam_sensor_subdev_ops; strlcpy(s_ctrl->device_name, CAMX_SENSOR_DEV_NAME, sizeof(s_ctrl->device_name)); s_ctrl->v4l2_dev_str.name = s_ctrl->device_name; s_ctrl->v4l2_dev_str.sd_flags = (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); s_ctrl->v4l2_dev_str.ent_function = CAM_SENSOR_DEVICE_TYPE; s_ctrl->v4l2_dev_str.token = s_ctrl; rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str)); if (rc < 0) { pr_err("%s:%d :ERROR: Fail with cam_register_subdev\n", __func__, __LINE__); goto free_s_ctrl; } s_ctrl->i2c_data.per_frame = (struct i2c_settings_array *) kzalloc(sizeof(struct i2c_settings_array) * MAX_PER_FRAME_ARRAY, GFP_KERNEL); if (s_ctrl->i2c_data.per_frame == NULL) { rc = -ENOMEM; goto free_s_ctrl; } INIT_LIST_HEAD(&(s_ctrl->i2c_data.init_settings.list_head)); for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head)); s_ctrl->bridge_intf.device_hdl = -1; s_ctrl->bridge_intf.ops.get_dev_info = cam_sensor_publish_dev_info; s_ctrl->bridge_intf.ops.link_setup = cam_sensor_establish_link; s_ctrl->bridge_intf.ops.apply_req = cam_sensor_apply_request; s_ctrl->sensordata->power_info.dev = &pdev->dev; platform_set_drvdata(pdev, s_ctrl); v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), s_ctrl); return rc; free_s_ctrl: devm_kfree(&pdev->dev, s_ctrl); return rc; } MODULE_DEVICE_TABLE(of, cam_sensor_driver_dt_match); static struct platform_driver cam_sensor_platform_driver = { .probe = cam_sensor_driver_platform_probe, .driver = { .name = "qcom,camera", .owner = THIS_MODULE, .of_match_table = cam_sensor_driver_dt_match, }, .remove = cam_sensor_platform_remove, }; static const struct i2c_device_id i2c_id[] = { {SENSOR_DRIVER_I2C, (kernel_ulong_t)NULL}, { } }; static struct i2c_driver cam_sensor_driver_i2c = { .id_table = i2c_id, .probe = cam_sensor_driver_i2c_probe, .remove = cam_sensor_driver_i2c_remove, .driver = { .name = SENSOR_DRIVER_I2C, }, }; static int __init cam_sensor_driver_init(void) { int32_t rc = 0; rc = platform_driver_register(&cam_sensor_platform_driver); if (rc) pr_err("%s platform_driver_register failed rc = %d", __func__, rc); rc = i2c_add_driver(&cam_sensor_driver_i2c); if (rc) pr_err("%s i2c_add_driver failed rc = %d", __func__, rc); return rc; } static void __exit cam_sensor_driver_exit(void) { platform_driver_unregister(&cam_sensor_platform_driver); i2c_del_driver(&cam_sensor_driver_i2c); } module_init(cam_sensor_driver_init); module_exit(cam_sensor_driver_exit); MODULE_DESCRIPTION("cam_sensor_driver"); MODULE_LICENSE("GPL v2");