Переглянути джерело

Merge "msm: camera: sensor: Add component support for i2c driver" into camera-kernel.lnx.5.0

Camera Software Integration 3 роки тому
батько
коміт
903a8b596d

+ 108 - 59
drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.c

@@ -160,26 +160,21 @@ static int cam_actuator_init_subdev(struct cam_actuator_ctrl_t *a_ctrl)
 	return rc;
 }
 
-static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
+static int cam_actuator_i2c_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	int32_t                         rc = 0;
-	int32_t                         i = 0;
+	int32_t                          rc = 0;
+	int32_t                          i = 0;
+	struct i2c_client               *client;
 	struct cam_actuator_ctrl_t      *a_ctrl;
 	struct cam_hw_soc_info          *soc_info = NULL;
 	struct cam_actuator_soc_private *soc_private = NULL;
 
-	if (client == NULL || id == NULL) {
-		CAM_ERR(CAM_ACTUATOR, "Invalid Args client: %pK id: %pK",
-			client, id);
-		return -EINVAL;
-	}
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CAM_ERR(CAM_ACTUATOR, "%s :: i2c_check_functionality failed",
-			 client->name);
-		rc = -EFAULT;
-		return rc;
+	client = container_of(dev, struct i2c_client, dev);
+	if (!client) {
+		CAM_ERR(CAM_ACTUATOR,
+			"Failed to get i2c client");
+		return -EFAULT;
 	}
 
 	/* Create sensor control structure */
@@ -252,7 +247,83 @@ free_ctrl:
 	return rc;
 }
 
-static int cam_actuator_component_bind(struct device *dev,
+static void cam_actuator_i2c_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct i2c_client               *client = NULL;
+	struct cam_actuator_ctrl_t      *a_ctrl = NULL;
+	struct cam_actuator_soc_private *soc_private;
+	struct cam_sensor_power_ctrl_t  *power_info;
+
+	client = container_of(dev, struct i2c_client, dev);
+	if (!client) {
+		CAM_ERR(CAM_ACTUATOR,
+			"Failed to get i2c client");
+		return;
+	}
+
+	a_ctrl = i2c_get_clientdata(client);
+	/* Handle I2C Devices */
+	if (!a_ctrl) {
+		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
+		return;
+	}
+
+	CAM_INFO(CAM_ACTUATOR, "i2c remove invoked");
+	mutex_lock(&(a_ctrl->actuator_mutex));
+	cam_actuator_shutdown(a_ctrl);
+	mutex_unlock(&(a_ctrl->actuator_mutex));
+	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
+	soc_private =
+		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
+	power_info = &soc_private->power_info;
+
+	/*Free Allocated Mem */
+	kfree(a_ctrl->i2c_data.per_frame);
+	a_ctrl->i2c_data.per_frame = NULL;
+	a_ctrl->soc_info.soc_private = NULL;
+	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, NULL);
+	kfree(a_ctrl);
+}
+
+const static struct component_ops cam_actuator_i2c_component_ops = {
+	.bind = cam_actuator_i2c_component_bind,
+	.unbind = cam_actuator_i2c_component_unbind,
+};
+
+static int32_t cam_actuator_driver_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+
+	if (client == NULL || id == NULL) {
+		CAM_ERR(CAM_ACTUATOR, "Invalid Args client: %pK id: %pK",
+			client, id);
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CAM_ERR(CAM_ACTUATOR, "%s :: i2c_check_functionality failed",
+			 client->name);
+		return -EFAULT;
+	}
+
+	CAM_DBG(CAM_ACTUATOR, "Adding sensor actuator component");
+	rc = component_add(&client->dev, &cam_actuator_i2c_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ACTUATOR, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int32_t cam_actuator_driver_i2c_remove(
+	struct i2c_client *client)
+{
+	component_del(&client->dev, &cam_actuator_i2c_component_ops);
+	return 0;
+}
+
+static int cam_actuator_platform_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
 	int32_t                          rc = 0;
@@ -330,7 +401,8 @@ static int cam_actuator_component_bind(struct device *dev,
 
 	platform_set_drvdata(pdev, a_ctrl);
 	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;
-	CAM_DBG(CAM_ACTUATOR, "Component bound successfully");
+	CAM_DBG(CAM_ACTUATOR, "Component bound successfully %d",
+		a_ctrl->soc_info.index);
 
 	return rc;
 
@@ -345,7 +417,7 @@ free_ctrl:
 	return rc;
 }
 
-static void cam_actuator_component_unbind(struct device *dev,
+static void cam_actuator_platform_component_unbind(struct device *dev,
 	struct device *master_dev, void *data)
 {
 	struct cam_actuator_ctrl_t      *a_ctrl;
@@ -380,47 +452,15 @@ static void cam_actuator_component_unbind(struct device *dev,
 	CAM_INFO(CAM_ACTUATOR, "Actuator component unbinded");
 }
 
-const static struct component_ops cam_actuator_component_ops = {
-	.bind = cam_actuator_component_bind,
-	.unbind = cam_actuator_component_unbind,
+const static struct component_ops cam_actuator_platform_component_ops = {
+	.bind = cam_actuator_platform_component_bind,
+	.unbind = cam_actuator_platform_component_unbind,
 };
 
 static int32_t cam_actuator_platform_remove(
 	struct platform_device *pdev)
 {
-	component_del(&pdev->dev, &cam_actuator_component_ops);
-	return 0;
-}
-
-static int32_t cam_actuator_driver_i2c_remove(struct i2c_client *client)
-{
-	struct cam_actuator_ctrl_t      *a_ctrl =
-		i2c_get_clientdata(client);
-	struct cam_actuator_soc_private *soc_private;
-	struct cam_sensor_power_ctrl_t  *power_info;
-
-	/* Handle I2C Devices */
-	if (!a_ctrl) {
-		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
-		return -EINVAL;
-	}
-
-	CAM_INFO(CAM_ACTUATOR, "i2c remove invoked");
-	mutex_lock(&(a_ctrl->actuator_mutex));
-	cam_actuator_shutdown(a_ctrl);
-	mutex_unlock(&(a_ctrl->actuator_mutex));
-	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
-	soc_private =
-		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
-	power_info = &soc_private->power_info;
-
-	/*Free Allocated Mem */
-	kfree(a_ctrl->i2c_data.per_frame);
-	a_ctrl->i2c_data.per_frame = NULL;
-	a_ctrl->soc_info.soc_private = NULL;
-	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, NULL);
-	kfree(a_ctrl);
-
+	component_del(&pdev->dev, &cam_actuator_platform_component_ops);
 	return 0;
 }
 
@@ -435,9 +475,9 @@ static int32_t cam_actuator_driver_platform_probe(
 	int rc = 0;
 
 	CAM_DBG(CAM_ACTUATOR, "Adding sensor actuator component");
-	rc = component_add(&pdev->dev, &cam_actuator_component_ops);
+	rc = component_add(&pdev->dev, &cam_actuator_platform_component_ops);
 	if (rc)
-		CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc);
+		CAM_ERR(CAM_ACTUATOR, "failed to add component rc: %d", rc);
 
 	return rc;
 }
@@ -460,12 +500,21 @@ static const struct i2c_device_id i2c_id[] = {
 	{ }
 };
 
-static struct i2c_driver cam_actuator_driver_i2c = {
+static const struct of_device_id cam_actuator_i2c_driver_dt_match[] = {
+	{.compatible = "qcom,cam-i2c-actuator"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, cam_actuator_i2c_driver_dt_match);
+
+struct i2c_driver cam_actuator_i2c_driver = {
 	.id_table = i2c_id,
 	.probe  = cam_actuator_driver_i2c_probe,
 	.remove = cam_actuator_driver_i2c_remove,
 	.driver = {
+		.of_match_table = cam_actuator_i2c_driver_dt_match,
+		.owner = THIS_MODULE,
 		.name = ACTUATOR_DRIVER_I2C,
+		.suppress_bind_attrs = true,
 	},
 };
 
@@ -479,7 +528,7 @@ int cam_actuator_driver_init(void)
 			"platform_driver_register failed rc = %d", rc);
 		return rc;
 	}
-	rc = i2c_add_driver(&cam_actuator_driver_i2c);
+	rc = i2c_add_driver(&cam_actuator_i2c_driver);
 	if (rc)
 		CAM_ERR(CAM_ACTUATOR, "i2c_add_driver failed rc = %d", rc);
 
@@ -489,7 +538,7 @@ int cam_actuator_driver_init(void)
 void cam_actuator_driver_exit(void)
 {
 	platform_driver_unregister(&cam_actuator_platform_driver);
-	i2c_del_driver(&cam_actuator_driver_i2c);
+	i2c_del_driver(&cam_actuator_i2c_driver);
 }
 
 MODULE_DESCRIPTION("cam_actuator_driver");

+ 2 - 2
drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
  */
 
 
@@ -30,7 +30,7 @@
 #define NUM_MASTERS 2
 #define NUM_QUEUES 2
 
-#define ACTUATOR_DRIVER_I2C "i2c_actuator"
+#define ACTUATOR_DRIVER_I2C "cam-i2c-actuator"
 #define CAMX_ACTUATOR_DEV_NAME "cam-actuator-driver"
 
 #define MSM_ACTUATOR_MAX_VREGS (10)

+ 70 - 12
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c

@@ -177,17 +177,20 @@ static int cam_eeprom_init_subdev(struct cam_eeprom_ctrl_t *e_ctrl)
 	return rc;
 }
 
-static int cam_eeprom_i2c_driver_probe(struct i2c_client *client,
-	 const struct i2c_device_id *id)
+static int cam_eeprom_i2c_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int                             rc = 0;
+	struct i2c_client              *client = NULL;
 	struct cam_eeprom_ctrl_t       *e_ctrl = NULL;
 	struct cam_eeprom_soc_private  *soc_private = NULL;
 	struct cam_hw_soc_info         *soc_info = NULL;
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CAM_ERR(CAM_EEPROM, "i2c_check_functionality failed");
-		goto probe_failure;
+	client = container_of(dev, struct i2c_client, dev);
+	if (client == NULL) {
+		CAM_ERR(CAM_OIS, "Invalid Args client: %pK",
+			client);
+		return -EINVAL;
 	}
 
 	e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
@@ -253,30 +256,40 @@ probe_failure:
 	return rc;
 }
 
-static int cam_eeprom_i2c_driver_remove(struct i2c_client *client)
+static void cam_eeprom_i2c_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int                             i;
+	struct i2c_client              *client = NULL;
 	struct v4l2_subdev             *sd = i2c_get_clientdata(client);
 	struct cam_eeprom_ctrl_t       *e_ctrl;
 	struct cam_eeprom_soc_private  *soc_private;
 	struct cam_hw_soc_info         *soc_info;
 
+	client = container_of(dev, struct i2c_client, dev);
+	if (!client) {
+		CAM_ERR(CAM_EEPROM,
+			"Failed to get i2c client");
+		return;
+	}
+
+	sd = i2c_get_clientdata(client);
 	if (!sd) {
 		CAM_ERR(CAM_EEPROM, "Subdevice is NULL");
-		return -EINVAL;
+		return;
 	}
 
 	e_ctrl = (struct cam_eeprom_ctrl_t *)v4l2_get_subdevdata(sd);
 	if (!e_ctrl) {
 		CAM_ERR(CAM_EEPROM, "eeprom device is NULL");
-		return -EINVAL;
+		return;
 	}
 
 	soc_private =
 		(struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
 	if (!soc_private) {
 		CAM_ERR(CAM_EEPROM, "soc_info.soc_private is NULL");
-		return -EINVAL;
+		return;
 	}
 
 	CAM_INFO(CAM_EEPROM, "i2c driver remove invoked");
@@ -292,6 +305,41 @@ static int cam_eeprom_i2c_driver_remove(struct i2c_client *client)
 	kfree(soc_private);
 	v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
 	kfree(e_ctrl);
+}
+
+const static struct component_ops cam_eeprom_i2c_component_ops = {
+	.bind = cam_eeprom_i2c_component_bind,
+	.unbind = cam_eeprom_i2c_component_unbind,
+};
+
+static int cam_eeprom_i2c_driver_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+
+	if (client == NULL || id == NULL) {
+		CAM_ERR(CAM_EEPROM, "Invalid Args client: %pK id: %pK",
+			client, id);
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CAM_ERR(CAM_EEPROM, "%s :: i2c_check_functionality failed",
+			client->name);
+		return -EFAULT;
+	}
+
+	CAM_DBG(CAM_EEPROM, "Adding sensor eeprom component");
+	rc = component_add(&client->dev, &cam_eeprom_i2c_component_ops);
+	if (rc)
+		CAM_ERR(CAM_EEPROM, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_eeprom_i2c_driver_remove(struct i2c_client *client)
+{
+	component_del(&client->dev, &cam_eeprom_i2c_component_ops);
 
 	return 0;
 }
@@ -585,16 +633,26 @@ struct platform_driver cam_eeprom_platform_driver = {
 };
 
 static const struct i2c_device_id cam_eeprom_i2c_id[] = {
-	{ "msm_eeprom", (kernel_ulong_t)NULL},
+	{ EEPROM_DRIVER_I2C, (kernel_ulong_t)NULL},
 	{ }
 };
 
-static struct i2c_driver cam_eeprom_i2c_driver = {
+static const struct of_device_id cam_eeprom_i2c_dt_match[] = {
+	{ .compatible = "qcom,cam-i2c-eeprom" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, cam_eeprom_i2c_dt_match);
+
+struct i2c_driver cam_eeprom_i2c_driver = {
 	.id_table = cam_eeprom_i2c_id,
 	.probe  = cam_eeprom_i2c_driver_probe,
 	.remove = cam_eeprom_i2c_driver_remove,
 	.driver = {
-		.name = "msm_eeprom",
+		.name = EEPROM_DRIVER_I2C,
+		.owner = THIS_MODULE,
+		.of_match_table = cam_eeprom_i2c_dt_match,
+		.suppress_bind_attrs = true,
 	},
 };
 

+ 3 - 1
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
  */
 #ifndef _CAM_EEPROM_DEV_H_
 #define _CAM_EEPROM_DEV_H_
@@ -33,6 +33,8 @@
 #define MSM_EEPROM_MAX_MEM_MAP_CNT             100
 #define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT      8
 
+#define EEPROM_DRIVER_I2C "cam-i2c-eeprom"
+
 enum cam_eeprom_state {
 	CAM_EEPROM_INIT,
 	CAM_EEPROM_ACQUIRE,

+ 79 - 33
drivers/cam_sensor_module/cam_flash/cam_flash_dev.c

@@ -353,24 +353,6 @@ static long cam_flash_subdev_do_ioctl(struct v4l2_subdev *sd,
 }
 #endif
 
-static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
-{
-	int32_t rc = 0;
-	struct cam_flash_ctrl *fctrl = i2c_get_clientdata(client);
-	/* Handle I2C Devices */
-	if (!fctrl) {
-		CAM_ERR(CAM_FLASH, "Flash device is NULL");
-		return -EINVAL;
-	}
-
-	CAM_INFO(CAM_FLASH, "i2c driver remove invoked");
-	/*Free Allocated Mem */
-	kfree(fctrl->i2c_data.per_frame);
-	fctrl->i2c_data.per_frame = NULL;
-	kfree(fctrl);
-	return rc;
-}
-
 static struct v4l2_subdev_core_ops cam_flash_subdev_core_ops = {
 	.ioctl = cam_flash_subdev_ioctl,
 #ifdef CONFIG_COMPAT
@@ -581,29 +563,21 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
 	return rc;
 }
 
-static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
+static int cam_flash_i2c_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int32_t rc = 0, i = 0;
-	struct cam_flash_ctrl *fctrl;
+	struct i2c_client      *client = NULL;
+	struct cam_flash_ctrl  *fctrl = NULL;
 	struct cam_hw_soc_info *soc_info = NULL;
 
+	client = container_of(dev, struct i2c_client, dev);
 	if (client == NULL) {
 		CAM_ERR(CAM_FLASH, "Invalid Args client: %pK",
 			client);
 		return -EINVAL;
 	}
 
-	if (id == NULL) {
-		CAM_DBG(CAM_FLASH, "device id is Null");
-	}
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed",
-			 client->name);
-		return -EFAULT;
-	}
-
 	/* Create sensor control structure */
 	fctrl = kzalloc(sizeof(*fctrl), GFP_KERNEL);
 	if (!fctrl)
@@ -708,6 +682,70 @@ free_ctrl:
 	return rc;
 }
 
+static void cam_flash_i2c_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct i2c_client     *client = NULL;
+	struct cam_flash_ctrl *fctrl = NULL;
+
+	client = container_of(dev, struct i2c_client, dev);
+	if (!client) {
+		CAM_ERR(CAM_FLASH,
+			"Failed to get i2c client");
+		return;
+	}
+
+	fctrl = i2c_get_clientdata(client);
+	/* Handle I2C Devices */
+	if (!fctrl) {
+		CAM_ERR(CAM_FLASH, "Flash device is NULL");
+		return;
+	}
+
+	CAM_INFO(CAM_FLASH, "i2c driver remove invoked");
+	/*Free Allocated Mem */
+	kfree(fctrl->i2c_data.per_frame);
+	fctrl->i2c_data.per_frame = NULL;
+	kfree(fctrl);
+}
+
+const static struct component_ops cam_flash_i2c_component_ops = {
+	.bind = cam_flash_i2c_component_bind,
+	.unbind = cam_flash_i2c_component_unbind,
+};
+
+static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+
+	if (client == NULL || id == NULL) {
+		CAM_ERR(CAM_FLASH, "Invalid Args client: %pK id: %pK",
+			client, id);
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed",
+			client->name);
+		return -EFAULT;
+	}
+
+	CAM_DBG(CAM_FLASH, "Adding sensor flash component");
+	rc = component_add(&client->dev, &cam_flash_i2c_component_ops);
+	if (rc)
+		CAM_ERR(CAM_FLASH, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
+{
+	component_del(&client->dev, &cam_flash_i2c_component_ops);
+
+	return 0;
+}
+
 MODULE_DEVICE_TABLE(of, cam_flash_dt_match);
 
 struct platform_driver cam_flash_platform_driver = {
@@ -721,18 +759,26 @@ struct platform_driver cam_flash_platform_driver = {
 	},
 };
 
+static const struct of_device_id cam_flash_i2c_dt_match[] = {
+	{.compatible = "qcom,cam-i2c-flash", .data = NULL},
+	{}
+};
+MODULE_DEVICE_TABLE(of, cam_flash_i2c_dt_match);
+
 static const struct i2c_device_id i2c_id[] = {
 	{FLASH_DRIVER_I2C, (kernel_ulong_t)NULL},
 	{ }
 };
 
-static struct i2c_driver cam_flash_i2c_driver = {
+struct i2c_driver cam_flash_i2c_driver = {
 	.id_table = i2c_id,
 	.probe  = cam_flash_i2c_driver_probe,
 	.remove = cam_flash_i2c_driver_remove,
 	.driver = {
+		.owner = THIS_MODULE,
 		.name = FLASH_DRIVER_I2C,
-		.of_match_table = cam_flash_dt_match,
+		.of_match_table = cam_flash_i2c_dt_match,
+		.suppress_bind_attrs = true,
 	},
 };
 

+ 1 - 1
drivers/cam_sensor_module/cam_flash/cam_flash_dev.h

@@ -40,7 +40,7 @@
 
 #define CAM_FLASH_PIPELINE_DELAY 1
 
-#define FLASH_DRIVER_I2C "i2c_flash"
+#define FLASH_DRIVER_I2C "cam-i2c-flash"
 
 #define CAM_FLASH_PACKET_OPCODE_INIT                 0
 #define CAM_FLASH_PACKET_OPCODE_SET_OPS              1

+ 66 - 16
drivers/cam_sensor_module/cam_ois/cam_ois_dev.c

@@ -173,24 +173,21 @@ static int cam_ois_init_subdev_param(struct cam_ois_ctrl_t *o_ctrl)
 	return rc;
 }
 
-static int cam_ois_i2c_driver_probe(struct i2c_client *client,
-	 const struct i2c_device_id *id)
+static int cam_ois_i2c_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int                          rc = 0;
+	struct i2c_client           *client = NULL;
 	struct cam_ois_ctrl_t       *o_ctrl = NULL;
 	struct cam_ois_soc_private  *soc_private = NULL;
 
-	if (client == NULL || id == NULL) {
-		CAM_ERR(CAM_OIS, "Invalid Args client: %pK id: %pK",
-			client, id);
+	client = container_of(dev, struct i2c_client, dev);
+	if (client == NULL) {
+		CAM_ERR(CAM_OIS, "Invalid Args client: %pK",
+			client);
 		return -EINVAL;
 	}
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CAM_ERR(CAM_OIS, "i2c_check_functionality failed");
-		goto probe_failure;
-	}
-
 	o_ctrl = kzalloc(sizeof(*o_ctrl), GFP_KERNEL);
 	if (!o_ctrl) {
 		CAM_ERR(CAM_OIS, "kzalloc failed");
@@ -236,17 +233,27 @@ probe_failure:
 	return rc;
 }
 
-static int cam_ois_i2c_driver_remove(struct i2c_client *client)
+static void cam_ois_i2c_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int                             i;
-	struct cam_ois_ctrl_t          *o_ctrl = i2c_get_clientdata(client);
+	struct i2c_client              *client = NULL;
+	struct cam_ois_ctrl_t          *o_ctrl = NULL;
 	struct cam_hw_soc_info         *soc_info;
 	struct cam_ois_soc_private     *soc_private;
 	struct cam_sensor_power_ctrl_t *power_info;
 
+	client = container_of(dev, struct i2c_client, dev);
+	if (!client) {
+		CAM_ERR(CAM_OIS,
+			"Failed to get i2c client");
+		return;
+	}
+
+	o_ctrl = i2c_get_clientdata(client);
 	if (!o_ctrl) {
 		CAM_ERR(CAM_OIS, "ois device is NULL");
-		return -EINVAL;
+		return;
 	}
 
 	CAM_INFO(CAM_OIS, "i2c driver remove invoked");
@@ -267,6 +274,41 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client)
 	kfree(o_ctrl->soc_info.soc_private);
 	v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, NULL);
 	kfree(o_ctrl);
+}
+
+const static struct component_ops cam_ois_i2c_component_ops = {
+	.bind = cam_ois_i2c_component_bind,
+	.unbind = cam_ois_i2c_component_unbind,
+};
+
+static int cam_ois_i2c_driver_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+
+	if (client == NULL || id == NULL) {
+		CAM_ERR(CAM_OIS, "Invalid Args client: %pK id: %pK",
+			client, id);
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CAM_ERR(CAM_OIS, "%s :: i2c_check_functionality failed",
+			client->name);
+		return -EFAULT;
+	}
+
+	CAM_DBG(CAM_OIS, "Adding sensor ois component");
+	rc = component_add(&client->dev, &cam_ois_i2c_component_ops);
+	if (rc)
+		CAM_ERR(CAM_OIS, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_ois_i2c_driver_remove(struct i2c_client *client)
+{
+	component_del(&client->dev, &cam_ois_i2c_component_ops);
 
 	return 0;
 }
@@ -409,8 +451,13 @@ static const struct of_device_id cam_ois_dt_match[] = {
 	{ }
 };
 
+static const struct of_device_id cam_ois_i2c_dt_match[] = {
+	{ .compatible = "qcom,cam-i2c-ois" },
+	{ }
+};
 
 MODULE_DEVICE_TABLE(of, cam_ois_dt_match);
+MODULE_DEVICE_TABLE(of, cam_ois_i2c_dt_match);
 
 struct platform_driver cam_ois_platform_driver = {
 	.driver = {
@@ -422,16 +469,19 @@ struct platform_driver cam_ois_platform_driver = {
 	.remove = cam_ois_platform_driver_remove,
 };
 static const struct i2c_device_id cam_ois_i2c_id[] = {
-	{ "msm_ois", (kernel_ulong_t)NULL},
+	{ OIS_DRIVER_I2C, (kernel_ulong_t)NULL},
 	{ }
 };
 
-static struct i2c_driver cam_ois_i2c_driver = {
+struct i2c_driver cam_ois_i2c_driver = {
 	.id_table = cam_ois_i2c_id,
 	.probe  = cam_ois_i2c_driver_probe,
 	.remove = cam_ois_i2c_driver_remove,
 	.driver = {
-		.name = "msm_ois",
+		.name = OIS_DRIVER_I2C,
+		.owner = THIS_MODULE,
+		.of_match_table = cam_ois_i2c_dt_match,
+		.suppress_bind_attrs = true,
 	},
 };
 

+ 3 - 1
drivers/cam_sensor_module/cam_ois/cam_ois_dev.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 #ifndef _CAM_OIS_DEV_H_
 #define _CAM_OIS_DEV_H_
@@ -25,6 +25,8 @@
 #define DEFINE_MSM_MUTEX(mutexname) \
 	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
 
+#define OIS_DRIVER_I2C "cam-i2c-ois"
+
 enum cam_ois_state {
 	CAM_OIS_INIT,
 	CAM_OIS_ACQUIRE,

+ 95 - 41
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c

@@ -153,18 +153,20 @@ static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl)
 	return rc;
 }
 
-static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
+static int cam_sensor_i2c_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	int32_t rc = 0;
-	int i = 0;
+	int32_t                   rc = 0;
+	int                       i = 0;
+	struct i2c_client        *client = NULL;
 	struct cam_sensor_ctrl_t *s_ctrl = NULL;
 	struct cam_hw_soc_info   *soc_info = NULL;
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		CAM_ERR(CAM_SENSOR,
-			"%s :i2c_check_functionality failed", client->name);
-		return -EFAULT;
+	client = container_of(dev, struct i2c_client, dev);
+	if (client == NULL) {
+		CAM_ERR(CAM_SENSOR, "Invalid Args client: %pK",
+			client);
+		return -EINVAL;
 	}
 
 	/* Create sensor control structure */
@@ -243,6 +245,76 @@ free_s_ctrl:
 	return rc;
 }
 
+static void cam_sensor_i2c_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct i2c_client         *client = NULL;
+	struct cam_sensor_ctrl_t  *s_ctrl = NULL;
+	struct cam_hw_soc_info    *soc_info = NULL;
+
+	client = container_of(dev, struct i2c_client, dev);
+	if (!client) {
+		CAM_ERR(CAM_SENSOR,
+			"Failed to get i2c client");
+		return;
+	}
+
+	s_ctrl = i2c_get_clientdata(client);
+	if (!s_ctrl) {
+		CAM_ERR(CAM_SENSOR, "sensor device is NULL");
+		return;
+	}
+
+	CAM_DBG(CAM_SENSOR, "i2c remove invoked");
+	mutex_lock(&(s_ctrl->cam_sensor_mutex));
+	cam_sensor_shutdown(s_ctrl);
+	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
+	cam_unregister_subdev(&(s_ctrl->v4l2_dev_str));
+	soc_info = &s_ctrl->soc_info;
+
+	kfree(s_ctrl->i2c_data.per_frame);
+	kfree(s_ctrl->i2c_data.frame_skip);
+	v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), NULL);
+	kfree(s_ctrl);
+}
+
+const static struct component_ops cam_sensor_i2c_component_ops = {
+	.bind = cam_sensor_i2c_component_bind,
+	.unbind = cam_sensor_i2c_component_unbind,
+};
+
+static int cam_sensor_i2c_driver_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+
+	if (client == NULL || id == NULL) {
+		CAM_ERR(CAM_SENSOR, "Invalid Args client: %pK id: %pK",
+			client, id);
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CAM_ERR(CAM_SENSOR, "%s :: i2c_check_functionality failed",
+			client->name);
+		return -EFAULT;
+	}
+
+	CAM_DBG(CAM_SENSOR, "Adding sensor component");
+	rc = component_add(&client->dev, &cam_sensor_i2c_component_ops);
+	if (rc)
+		CAM_ERR(CAM_SENSOR, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_sensor_i2c_driver_remove(struct i2c_client *client)
+{
+	component_del(&client->dev, &cam_sensor_i2c_component_ops);
+
+	return 0;
+}
+
 static int cam_sensor_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
@@ -378,34 +450,6 @@ static int cam_sensor_platform_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static int cam_sensor_driver_i2c_remove(struct i2c_client *client)
-{
-	int                        i;
-	struct cam_sensor_ctrl_t  *s_ctrl = i2c_get_clientdata(client);
-	struct cam_hw_soc_info    *soc_info;
-
-	if (!s_ctrl) {
-		CAM_ERR(CAM_SENSOR, "sensor device is NULL");
-		return 0;
-	}
-
-	CAM_DBG(CAM_SENSOR, "i2c remove invoked");
-	mutex_lock(&(s_ctrl->cam_sensor_mutex));
-	cam_sensor_shutdown(s_ctrl);
-	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
-	cam_unregister_subdev(&(s_ctrl->v4l2_dev_str));
-	soc_info = &s_ctrl->soc_info;
-	for (i = 0; i < soc_info->num_clk; i++)
-		devm_clk_put(soc_info->dev, soc_info->clk[i]);
-
-	kfree(s_ctrl->i2c_data.per_frame);
-	kfree(s_ctrl->i2c_data.frame_skip);
-	v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), NULL);
-	kfree(s_ctrl);
-
-	return 0;
-}
-
 static const struct of_device_id cam_sensor_driver_dt_match[] = {
 	{.compatible = "qcom,cam-sensor"},
 	{}
@@ -437,17 +481,27 @@ struct platform_driver cam_sensor_platform_driver = {
 	.remove = cam_sensor_platform_remove,
 };
 
+static const struct of_device_id cam_sensor_i2c_driver_dt_match[] = {
+	{.compatible = "qcom,cam-i2c-sensor"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, cam_sensor_i2c_driver_dt_match);
+
 static const struct i2c_device_id i2c_id[] = {
 	{SENSOR_DRIVER_I2C, (kernel_ulong_t)NULL},
 	{ }
 };
 
-static struct i2c_driver cam_sensor_driver_i2c = {
+struct i2c_driver cam_sensor_i2c_driver = {
 	.id_table = i2c_id,
-	.probe = cam_sensor_driver_i2c_probe,
-	.remove = cam_sensor_driver_i2c_remove,
+	.probe = cam_sensor_i2c_driver_probe,
+	.remove = cam_sensor_i2c_driver_remove,
 	.driver = {
 		.name = SENSOR_DRIVER_I2C,
+		.owner = THIS_MODULE,
+		.of_match_table = cam_sensor_i2c_driver_dt_match,
+		.suppress_bind_attrs = true,
 	},
 };
 
@@ -462,7 +516,7 @@ int cam_sensor_driver_init(void)
 		return rc;
 	}
 
-	rc = i2c_add_driver(&cam_sensor_driver_i2c);
+	rc = i2c_add_driver(&cam_sensor_i2c_driver);
 	if (rc)
 		CAM_ERR(CAM_SENSOR, "i2c_add_driver failed rc = %d", rc);
 
@@ -472,7 +526,7 @@ int cam_sensor_driver_init(void)
 void cam_sensor_driver_exit(void)
 {
 	platform_driver_unregister(&cam_sensor_platform_driver);
-	i2c_del_driver(&cam_sensor_driver_i2c);
+	i2c_del_driver(&cam_sensor_i2c_driver);
 }
 
 MODULE_DESCRIPTION("cam_sensor_driver");

+ 1 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h

@@ -35,7 +35,7 @@
 #define CDBG(fmt, args...) pr_debug(fmt, ##args)
 #endif
 
-#define SENSOR_DRIVER_I2C "i2c_camera"
+#define SENSOR_DRIVER_I2C "cam-i2c-sensor"
 #define CAMX_SENSOR_DEV_NAME "cam-sensor-driver"
 
 enum cam_sensor_state_t {

+ 3 - 3
drivers/cam_sensor_module/cam_tpg/cam_tpg_dev.c

@@ -314,6 +314,8 @@ static int cam_tpg_component_bind(struct device *dev,
 		goto release_subdev;
 	}
 
+	platform_set_drvdata(pdev, tpg_dev);
+
 	return rc;
 
 release_subdev:
@@ -327,9 +329,7 @@ static void cam_tpg_component_unbind(struct device *dev,
 	struct device *master_dev, void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-
-	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
-	struct cam_tpg_device *tpg_dev = v4l2_get_subdevdata(subdev);
+	struct cam_tpg_device  *tpg_dev = platform_get_drvdata(pdev);
 
 	CAM_INFO(CAM_TPG, "Unbind TPG component");
 	cam_cpas_unregister_client(tpg_dev->cpas_handle);

+ 37 - 4
drivers/cam_utils/cam_compat.c

@@ -104,6 +104,11 @@ static int camera_platform_compare_dev(struct device *dev, const void *data)
 {
 	return platform_bus_type.match(dev, (struct device_driver *) data);
 }
+
+static int camera_i2c_compare_dev(struct device *dev, const void *data)
+{
+	return i2c_bus_type.match(dev, (struct device_driver *) data);
+}
 #else
 int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length)
 {
@@ -188,6 +193,11 @@ static int camera_platform_compare_dev(struct device *dev, void *data)
 {
 	return platform_bus_type.match(dev, (struct device_driver *) data);
 }
+
+static int camera_i2c_compare_dev(struct device *dev, void *data)
+{
+	return i2c_bus_type.match(dev, (struct device_driver *) data);
+}
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
@@ -214,6 +224,7 @@ int camera_component_match_add_drivers(struct device *master_dev,
 {
 	int i, rc = 0;
 	struct platform_device *pdev = NULL;
+	struct i2c_client *client = NULL;
 	struct device *start_dev = NULL, *match_dev = NULL;
 
 	if (!master_dev || !match_list) {
@@ -222,13 +233,13 @@ int camera_component_match_add_drivers(struct device *master_dev,
 		goto end;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(cam_component_drivers); i++) {
+	for (i = 0; i < ARRAY_SIZE(cam_component_platform_drivers); i++) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
 		struct device_driver const *drv =
-			&cam_component_drivers[i]->driver;
+			&cam_component_platform_drivers[i]->driver;
 		const void *drv_ptr = (const void *)drv;
 #else
-		struct device_driver *drv = &cam_component_drivers[i]->driver;
+		struct device_driver *drv = &cam_component_platform_drivers[i]->driver;
 		void *drv_ptr = (void *)drv;
 #endif
 		start_dev = NULL;
@@ -244,6 +255,28 @@ int camera_component_match_add_drivers(struct device *master_dev,
 		put_device(start_dev);
 	}
 
+	for (i = 0; i < ARRAY_SIZE(cam_component_i2c_drivers); i++) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+		struct device_driver const *drv =
+			&cam_component_i2c_drivers[i]->driver;
+		const void *drv_ptr = (const void *)drv;
+#else
+		struct device_driver *drv = &cam_component_i2c_drivers[i]->driver;
+		void *drv_ptr = (void *)drv;
+#endif
+		start_dev = NULL;
+		while ((match_dev = bus_find_device(&i2c_bus_type,
+			start_dev, drv_ptr, &camera_i2c_compare_dev))) {
+			put_device(start_dev);
+			client = to_i2c_client(match_dev);
+			CAM_DBG(CAM_UTIL, "Adding matched component:%s", client->name);
+			component_match_add(master_dev, match_list,
+				camera_component_compare_dev, match_dev);
+			start_dev = match_dev;
+		}
+		put_device(start_dev);
+	}
+
 end:
 	return rc;
 }
@@ -366,4 +399,4 @@ int cam_get_ddr_type(void)
 {
 	return of_fdt_get_ddrtype();
 }
-#endif
+#endif

+ 18 - 1
drivers/camera_main.h

@@ -7,6 +7,7 @@
 #define CAMERA_MAIN_H
 
 #include <linux/platform_device.h>
+#include <linux/i2c.h>
 #include <linux/component.h>
 
 extern struct platform_driver cam_sync_driver;
@@ -35,6 +36,11 @@ extern struct platform_driver cam_sensor_platform_driver;
 extern struct platform_driver cam_eeprom_platform_driver;
 extern struct platform_driver cam_ois_platform_driver;
 extern struct platform_driver cam_tpg_driver;
+extern struct i2c_driver cam_actuator_i2c_driver;
+extern struct i2c_driver cam_flash_i2c_driver;
+extern struct i2c_driver cam_ois_i2c_driver;
+extern struct i2c_driver cam_eeprom_i2c_driver;
+extern struct i2c_driver cam_sensor_i2c_driver;
 #if IS_REACHABLE(CONFIG_LEDS_QPNP_FLASH_V2) || \
 	IS_REACHABLE(CONFIG_LEDS_QTI_FLASH)
 extern struct platform_driver cam_flash_platform_driver;
@@ -78,7 +84,7 @@ extern struct platform_driver custom_driver;
  * Drivers to be bound by component framework in this order with
  * CRM as master
  */
-static struct platform_driver *const cam_component_drivers[] = {
+static struct platform_driver *const cam_component_platform_drivers[] = {
 /* BASE */
 	&cam_sync_driver,
 	&cam_smmu_driver,
@@ -146,4 +152,15 @@ static struct platform_driver *const cam_component_drivers[] = {
 #endif
 };
 
+
+static struct i2c_driver *const cam_component_i2c_drivers[] = {
+#ifdef CONFIG_SPECTRA_SENSOR
+	&cam_actuator_i2c_driver,
+	&cam_flash_i2c_driver,
+	&cam_ois_i2c_driver,
+	&cam_eeprom_i2c_driver,
+	&cam_sensor_i2c_driver,
+#endif
+};
+
 #endif /* CAMERA_MAIN_H */