msm: camera: common: Add I3C Driver support
Add I3C driver Support for eeprom, actuator and OIS modules. CRs-Fixed: 3204977 Change-Id: Ic96d1edc787efcf3069935fc53fc799e786a95a7 Signed-off-by: Jigar Agrawal <quic_jigar@quicinc.com>
This commit is contained in:

committed by
Camera Software Integration

parent
8f297a31ea
commit
57c67da8f3
@@ -54,10 +54,10 @@ free_power_settings:
|
|||||||
static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
|
static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct cam_hw_soc_info *soc_info =
|
struct cam_hw_soc_info *soc_info = &a_ctrl->soc_info;
|
||||||
&a_ctrl->soc_info;
|
struct cam_actuator_soc_private *soc_private;
|
||||||
struct cam_actuator_soc_private *soc_private;
|
struct cam_sensor_power_ctrl_t *power_info;
|
||||||
struct cam_sensor_power_ctrl_t *power_info;
|
struct completion *i3c_probe_completion = NULL;
|
||||||
|
|
||||||
soc_private =
|
soc_private =
|
||||||
(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
|
(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
|
||||||
@@ -99,7 +99,10 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
|
|||||||
|
|
||||||
power_info->dev = soc_info->dev;
|
power_info->dev = soc_info->dev;
|
||||||
|
|
||||||
rc = cam_sensor_core_power_up(power_info, soc_info);
|
if (a_ctrl->io_master_info.master_type == I3C_MASTER)
|
||||||
|
i3c_probe_completion = cam_actuator_get_i3c_completion(a_ctrl->soc_info.index);
|
||||||
|
|
||||||
|
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_ACTUATOR,
|
CAM_ERR(CAM_ACTUATOR,
|
||||||
"failed in actuator power up rc %d", rc);
|
"failed in actuator power up rc %d", rc);
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_ACTUATOR_CORE_H_
|
#ifndef _CAM_ACTUATOR_CORE_H_
|
||||||
@@ -63,4 +64,6 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, void *arg);
|
|||||||
*/
|
*/
|
||||||
void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl);
|
void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl);
|
||||||
|
|
||||||
|
struct completion *cam_actuator_get_i3c_completion(uint32_t index);
|
||||||
|
|
||||||
#endif /* _CAM_ACTUATOR_CORE_H_ */
|
#endif /* _CAM_ACTUATOR_CORE_H_ */
|
||||||
|
@@ -10,6 +10,17 @@
|
|||||||
#include "cam_actuator_core.h"
|
#include "cam_actuator_core.h"
|
||||||
#include "cam_trace.h"
|
#include "cam_trace.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
#include "cam_compat.h"
|
||||||
|
|
||||||
|
static struct cam_i3c_actuator_data {
|
||||||
|
struct cam_actuator_ctrl_t *a_ctrl;
|
||||||
|
struct completion probe_complete;
|
||||||
|
} g_i3c_actuator_data[MAX_CAMERAS];
|
||||||
|
|
||||||
|
struct completion *cam_actuator_get_i3c_completion(uint32_t index)
|
||||||
|
{
|
||||||
|
return &g_i3c_actuator_data[index].probe_complete;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
|
static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
@@ -411,6 +422,9 @@ static int cam_actuator_platform_component_bind(struct device *dev,
|
|||||||
CAM_DBG(CAM_ACTUATOR, "Component bound successfully %d",
|
CAM_DBG(CAM_ACTUATOR, "Component bound successfully %d",
|
||||||
a_ctrl->soc_info.index);
|
a_ctrl->soc_info.index);
|
||||||
|
|
||||||
|
g_i3c_actuator_data[a_ctrl->soc_info.index].a_ctrl = a_ctrl;
|
||||||
|
init_completion(&g_i3c_actuator_data[a_ctrl->soc_info.index].probe_complete);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
free_mem:
|
free_mem:
|
||||||
@@ -525,6 +539,120 @@ struct i2c_driver cam_actuator_i2c_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct i3c_device_id actuator_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
|
||||||
|
|
||||||
|
static int cam_actuator_i3c_driver_probe(struct i3c_device *client)
|
||||||
|
{
|
||||||
|
int32_t rc = 0;
|
||||||
|
struct cam_actuator_ctrl_t *a_ctrl = NULL;
|
||||||
|
uint32_t index;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
CAM_INFO(CAM_ACTUATOR, "Null Client pointer");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = &client->dev;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ACTUATOR, "Probe for I3C Slave %s", dev_name(dev));
|
||||||
|
|
||||||
|
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR, "device %s failed to read cell-index", dev_name(dev));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= MAX_CAMERAS) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_ctrl = g_i3c_actuator_data[index].a_ctrl;
|
||||||
|
if (!a_ctrl) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR,
|
||||||
|
"a_ctrl is null. I3C Probe before platfom driver probe for %s",
|
||||||
|
dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_ctrl->io_master_info.i3c_client = client;
|
||||||
|
|
||||||
|
complete_all(&g_i3c_actuator_data[index].probe_complete);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ACTUATOR, "I3C Probe Finished for %s", dev_name(dev));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct i3c_driver cam_actuator_i3c_driver = {
|
||||||
|
.id_table = actuator_i3c_id,
|
||||||
|
.probe = cam_actuator_i3c_driver_probe,
|
||||||
|
.remove = cam_i3c_driver_remove,
|
||||||
|
.driver = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.name = ACTUATOR_DRIVER_I3C,
|
||||||
|
.of_match_table = cam_actuator_driver_dt_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cam_actuator_fill_i3c_device_id(void)
|
||||||
|
{
|
||||||
|
struct device_node *dev;
|
||||||
|
int num_entries;
|
||||||
|
int i = 0;
|
||||||
|
uint8_t ent_num = 0;
|
||||||
|
uint32_t mid;
|
||||||
|
uint32_t pid;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
|
||||||
|
if (!dev) {
|
||||||
|
CAM_WARN(CAM_ACTUATOR, "Couldnt Find the i3c-id-table dev node");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_entries = of_property_count_u32_elems(dev, "i3c-actuator-id-table");
|
||||||
|
if (num_entries <= 0) {
|
||||||
|
CAM_WARN(CAM_ACTUATOR, "Failed while reading the property. num_entries:%d",
|
||||||
|
num_entries);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < num_entries) {
|
||||||
|
if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
|
||||||
|
CAM_WARN(CAM_ACTUATOR,
|
||||||
|
"Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = of_property_read_u32_index(dev, "i3c-actuator-id-table", i, &mid);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR, "Failed in reading the MID. rc: %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
rc = of_property_read_u32_index(dev, "i3c-actuator-id-table", i, &pid);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR, "Failed in reading the PID. rc: %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ACTUATOR, "PID: 0x%x, MID: 0x%x", pid, mid);
|
||||||
|
|
||||||
|
actuator_i3c_id[ent_num].manuf_id = mid;
|
||||||
|
actuator_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
|
||||||
|
actuator_i3c_id[ent_num].part_id = pid;
|
||||||
|
actuator_i3c_id[ent_num].data = 0;
|
||||||
|
|
||||||
|
ent_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cam_actuator_driver_init(void)
|
int cam_actuator_driver_init(void)
|
||||||
{
|
{
|
||||||
int32_t rc = 0;
|
int32_t rc = 0;
|
||||||
@@ -535,9 +663,30 @@ int cam_actuator_driver_init(void)
|
|||||||
"platform_driver_register failed rc = %d", rc);
|
"platform_driver_register failed rc = %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = i2c_add_driver(&cam_actuator_i2c_driver);
|
rc = i2c_add_driver(&cam_actuator_i2c_driver);
|
||||||
if (rc)
|
if (rc) {
|
||||||
CAM_ERR(CAM_ACTUATOR, "i2c_add_driver failed rc = %d", rc);
|
CAM_ERR(CAM_ACTUATOR, "i2c_add_driver failed rc = %d", rc);
|
||||||
|
goto i2c_register_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(actuator_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
|
||||||
|
rc = cam_actuator_fill_i3c_device_id();
|
||||||
|
if (rc)
|
||||||
|
goto i3c_register_err;
|
||||||
|
|
||||||
|
rc = i3c_driver_register_with_owner(&cam_actuator_i3c_driver, THIS_MODULE);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ACTUATOR, "i3c_driver registration failed, rc: %d", rc);
|
||||||
|
goto i3c_register_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
i3c_register_err:
|
||||||
|
i2c_del_driver(&cam_actuator_i2c_driver);
|
||||||
|
i2c_register_err:
|
||||||
|
platform_driver_unregister(&cam_actuator_platform_driver);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -546,6 +695,7 @@ void cam_actuator_driver_exit(void)
|
|||||||
{
|
{
|
||||||
platform_driver_unregister(&cam_actuator_platform_driver);
|
platform_driver_unregister(&cam_actuator_platform_driver);
|
||||||
i2c_del_driver(&cam_actuator_i2c_driver);
|
i2c_del_driver(&cam_actuator_i2c_driver);
|
||||||
|
i3c_driver_unregister(&cam_actuator_i3c_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_DESCRIPTION("cam_actuator_driver");
|
MODULE_DESCRIPTION("cam_actuator_driver");
|
||||||
|
@@ -31,8 +31,10 @@
|
|||||||
#define NUM_MASTERS 2
|
#define NUM_MASTERS 2
|
||||||
#define NUM_QUEUES 2
|
#define NUM_QUEUES 2
|
||||||
|
|
||||||
#define ACTUATOR_DRIVER_I2C "cam-i2c-actuator"
|
#define ACTUATOR_DRIVER_I2C "cam-i2c-actuator"
|
||||||
#define CAMX_ACTUATOR_DEV_NAME "cam-actuator-driver"
|
#define CAMX_ACTUATOR_DEV_NAME "cam-actuator-driver"
|
||||||
|
#define ACTUATOR_DRIVER_I3C "i3c_camera_actuator"
|
||||||
|
|
||||||
|
|
||||||
#define MSM_ACTUATOR_MAX_VREGS (10)
|
#define MSM_ACTUATOR_MAX_VREGS (10)
|
||||||
#define ACTUATOR_MAX_POLL_COUNT 10
|
#define ACTUATOR_MAX_POLL_COUNT 10
|
||||||
|
@@ -148,9 +148,9 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
|
static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
|
||||||
struct cam_sensor_power_ctrl_t *power_info)
|
struct cam_sensor_power_ctrl_t *power_info)
|
||||||
{
|
{
|
||||||
int32_t rc = 0;
|
int32_t rc = 0;
|
||||||
struct cam_hw_soc_info *soc_info =
|
struct cam_hw_soc_info *soc_info = &e_ctrl->soc_info;
|
||||||
&e_ctrl->soc_info;
|
struct completion *i3c_probe_completion = NULL;
|
||||||
|
|
||||||
/* Parse and fill vreg params for power up settings */
|
/* Parse and fill vreg params for power up settings */
|
||||||
rc = msm_camera_fill_vreg_params(
|
rc = msm_camera_fill_vreg_params(
|
||||||
@@ -176,7 +176,10 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
|
|
||||||
power_info->dev = soc_info->dev;
|
power_info->dev = soc_info->dev;
|
||||||
|
|
||||||
rc = cam_sensor_core_power_up(power_info, soc_info);
|
if (e_ctrl->io_master_info.master_type == I3C_MASTER)
|
||||||
|
i3c_probe_completion = cam_eeprom_get_i3c_completion(e_ctrl->soc_info.index);
|
||||||
|
|
||||||
|
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_EEPROM, "failed in eeprom power up rc %d", rc);
|
CAM_ERR(CAM_EEPROM, "failed in eeprom power up rc %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -189,6 +192,7 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
|
|||||||
goto cci_failure;
|
goto cci_failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
cci_failure:
|
cci_failure:
|
||||||
if (cam_sensor_util_power_down(power_info, soc_info))
|
if (cam_sensor_util_power_down(power_info, soc_info))
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef _CAM_EEPROM_CORE_H_
|
#ifndef _CAM_EEPROM_CORE_H_
|
||||||
#define _CAM_EEPROM_CORE_H_
|
#define _CAM_EEPROM_CORE_H_
|
||||||
@@ -17,5 +18,7 @@ int32_t cam_eeprom_parse_read_memory_map(struct device_node *of_node,
|
|||||||
*/
|
*/
|
||||||
void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl);
|
void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl);
|
||||||
|
|
||||||
|
struct completion *cam_eeprom_get_i3c_completion(uint32_t index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* _CAM_EEPROM_CORE_H_ */
|
/* _CAM_EEPROM_CORE_H_ */
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cam_eeprom_dev.h"
|
#include "cam_eeprom_dev.h"
|
||||||
@@ -9,6 +10,17 @@
|
|||||||
#include "cam_eeprom_core.h"
|
#include "cam_eeprom_core.h"
|
||||||
#include "cam_debug_util.h"
|
#include "cam_debug_util.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
#include "cam_compat.h"
|
||||||
|
|
||||||
|
static struct cam_i3c_eeprom_data {
|
||||||
|
struct cam_eeprom_ctrl_t *e_ctrl;
|
||||||
|
struct completion probe_complete;
|
||||||
|
} g_i3c_eeprom_data[MAX_CAMERAS];
|
||||||
|
|
||||||
|
struct completion *cam_eeprom_get_i3c_completion(uint32_t index)
|
||||||
|
{
|
||||||
|
return &g_i3c_eeprom_data[index].probe_complete;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
|
static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
@@ -546,6 +558,9 @@ static int cam_eeprom_component_bind(struct device *dev,
|
|||||||
e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
|
e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
|
||||||
CAM_DBG(CAM_EEPROM, "Component bound successfully");
|
CAM_DBG(CAM_EEPROM, "Component bound successfully");
|
||||||
|
|
||||||
|
g_i3c_eeprom_data[e_ctrl->soc_info.index].e_ctrl = e_ctrl;
|
||||||
|
init_completion(&g_i3c_eeprom_data[e_ctrl->soc_info.index].probe_complete);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
free_soc:
|
free_soc:
|
||||||
kfree(soc_private);
|
kfree(soc_private);
|
||||||
@@ -665,6 +680,119 @@ static struct spi_driver cam_eeprom_spi_driver = {
|
|||||||
.probe = cam_eeprom_spi_driver_probe,
|
.probe = cam_eeprom_spi_driver_probe,
|
||||||
.remove = cam_eeprom_spi_driver_remove,
|
.remove = cam_eeprom_spi_driver_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct i3c_device_id eeprom_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
|
||||||
|
|
||||||
|
static int cam_eeprom_i3c_driver_probe(struct i3c_device *client)
|
||||||
|
{
|
||||||
|
int32_t rc = 0;
|
||||||
|
struct cam_eeprom_ctrl_t *e_ctrl = NULL;
|
||||||
|
uint32_t index;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
CAM_INFO(CAM_EEPROM, "Null Client pointer");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = &client->dev;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_EEPROM, "Probe for I3C Slave %s", dev_name(dev));
|
||||||
|
|
||||||
|
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_EEPROM, "device %s failed to read cell-index", dev_name(dev));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= MAX_CAMERAS) {
|
||||||
|
CAM_ERR(CAM_EEPROM, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_ctrl = g_i3c_eeprom_data[index].e_ctrl;
|
||||||
|
if (!e_ctrl) {
|
||||||
|
CAM_ERR(CAM_EEPROM, "e_ctrl is null. I3C Probe before platfom driver probe for %s",
|
||||||
|
dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
e_ctrl->io_master_info.i3c_client = client;
|
||||||
|
|
||||||
|
complete_all(&g_i3c_eeprom_data[index].probe_complete);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_EEPROM, "I3C Probe Finished for %s", dev_name(dev));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct i3c_driver cam_eeprom_i3c_driver = {
|
||||||
|
.id_table = eeprom_i3c_id,
|
||||||
|
.probe = cam_eeprom_i3c_driver_probe,
|
||||||
|
.remove = cam_i3c_driver_remove,
|
||||||
|
.driver = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.name = EEPROM_DRIVER_I3C,
|
||||||
|
.of_match_table = cam_eeprom_dt_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cam_eeprom_fill_i3c_device_id(void)
|
||||||
|
{
|
||||||
|
struct device_node *dev;
|
||||||
|
int num_entries;
|
||||||
|
int i = 0;
|
||||||
|
uint8_t ent_num = 0;
|
||||||
|
uint32_t mid;
|
||||||
|
uint32_t pid;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
|
||||||
|
if (!dev) {
|
||||||
|
CAM_WARN(CAM_EEPROM, "Couldnt Find the i3c-id-table dev node");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_entries = of_property_count_u32_elems(dev, "i3c-eeprom-id-table");
|
||||||
|
if (num_entries <= 0) {
|
||||||
|
CAM_WARN(CAM_EEPROM, "Failed while reading the property. num_entries:%d",
|
||||||
|
num_entries);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < num_entries) {
|
||||||
|
if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
|
||||||
|
CAM_WARN(CAM_EEPROM, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = of_property_read_u32_index(dev, "i3c-eeprom-id-table", i, &mid);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_EEPROM, "Failed in reading the MID. rc: %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
rc = of_property_read_u32_index(dev, "i3c-eeprom-id-table", i, &pid);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_EEPROM, "Failed in reading the PID. rc: %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_EEPROM, "PID: 0x%x, MID: 0x%x", pid, mid);
|
||||||
|
|
||||||
|
eeprom_i3c_id[ent_num].manuf_id = mid;
|
||||||
|
eeprom_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
|
||||||
|
eeprom_i3c_id[ent_num].part_id = pid;
|
||||||
|
eeprom_i3c_id[ent_num].data = 0;
|
||||||
|
|
||||||
|
ent_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cam_eeprom_driver_init(void)
|
int cam_eeprom_driver_init(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -679,15 +807,35 @@ int cam_eeprom_driver_init(void)
|
|||||||
rc = spi_register_driver(&cam_eeprom_spi_driver);
|
rc = spi_register_driver(&cam_eeprom_spi_driver);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_ERR(CAM_EEPROM, "spi_register_driver failed rc = %d", rc);
|
CAM_ERR(CAM_EEPROM, "spi_register_driver failed rc = %d", rc);
|
||||||
return rc;
|
goto spi_register_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = i2c_add_driver(&cam_eeprom_i2c_driver);
|
rc = i2c_add_driver(&cam_eeprom_i2c_driver);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_ERR(CAM_EEPROM, "i2c_add_driver failed rc = %d", rc);
|
CAM_ERR(CAM_EEPROM, "i2c_add_driver failed rc = %d", rc);
|
||||||
return rc;
|
goto i2c_register_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(eeprom_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
|
||||||
|
|
||||||
|
rc = cam_eeprom_fill_i3c_device_id();
|
||||||
|
if (rc)
|
||||||
|
goto i3c_register_err;
|
||||||
|
|
||||||
|
rc = i3c_driver_register_with_owner(&cam_eeprom_i3c_driver, THIS_MODULE);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_EEPROM, "i3c_driver registration failed, rc: %d", rc);
|
||||||
|
goto i3c_register_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
i3c_register_err:
|
||||||
|
i2c_del_driver(&cam_sensor_i2c_driver);
|
||||||
|
i2c_register_err:
|
||||||
|
spi_unregister_driver(&cam_eeprom_spi_driver);
|
||||||
|
spi_register_err:
|
||||||
|
platform_driver_unregister(&cam_sensor_platform_driver);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,6 +844,7 @@ void cam_eeprom_driver_exit(void)
|
|||||||
platform_driver_unregister(&cam_eeprom_platform_driver);
|
platform_driver_unregister(&cam_eeprom_platform_driver);
|
||||||
spi_unregister_driver(&cam_eeprom_spi_driver);
|
spi_unregister_driver(&cam_eeprom_spi_driver);
|
||||||
i2c_del_driver(&cam_eeprom_i2c_driver);
|
i2c_del_driver(&cam_eeprom_i2c_driver);
|
||||||
|
i3c_driver_unregister(&cam_eeprom_i3c_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_DESCRIPTION("CAM EEPROM driver");
|
MODULE_DESCRIPTION("CAM EEPROM driver");
|
||||||
|
@@ -34,7 +34,9 @@
|
|||||||
#define MSM_EEPROM_MAX_MEM_MAP_CNT 100
|
#define MSM_EEPROM_MAX_MEM_MAP_CNT 100
|
||||||
#define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT 8
|
#define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT 8
|
||||||
|
|
||||||
#define EEPROM_DRIVER_I2C "cam-i2c-eeprom"
|
#define EEPROM_DRIVER_I2C "cam-i2c-eeprom"
|
||||||
|
#define EEPROM_DRIVER_I3C "i3c_camera_eeprom"
|
||||||
|
|
||||||
|
|
||||||
enum cam_eeprom_state {
|
enum cam_eeprom_state {
|
||||||
CAM_EEPROM_INIT,
|
CAM_EEPROM_INIT,
|
||||||
|
@@ -169,7 +169,7 @@ int cam_flash_i2c_power_ops(struct cam_flash_ctrl *fctrl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = cam_sensor_core_power_up(power_info, soc_info);
|
rc = cam_sensor_core_power_up(power_info, soc_info, NULL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_FLASH, "power up the core is failed:%d",
|
CAM_ERR(CAM_FLASH, "power up the core is failed:%d",
|
||||||
rc);
|
rc);
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
|
||||||
#include <cam_sensor_cmn_header.h>
|
#include "cam_sensor_cmn_header.h"
|
||||||
#include "cam_ois_core.h"
|
#include "cam_ois_core.h"
|
||||||
#include "cam_ois_soc.h"
|
#include "cam_ois_soc.h"
|
||||||
#include "cam_sensor_util.h"
|
#include "cam_sensor_util.h"
|
||||||
@@ -105,14 +105,13 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl,
|
|||||||
|
|
||||||
static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
|
static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct cam_hw_soc_info *soc_info =
|
struct cam_hw_soc_info *soc_info = &o_ctrl->soc_info;
|
||||||
&o_ctrl->soc_info;
|
struct cam_ois_soc_private *soc_private;
|
||||||
struct cam_ois_soc_private *soc_private;
|
struct cam_sensor_power_ctrl_t *power_info;
|
||||||
struct cam_sensor_power_ctrl_t *power_info;
|
struct completion *i3c_probe_completion = NULL;
|
||||||
|
|
||||||
soc_private =
|
soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
|
||||||
(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
|
|
||||||
power_info = &soc_private->power_info;
|
power_info = &soc_private->power_info;
|
||||||
|
|
||||||
if ((power_info->power_setting == NULL) &&
|
if ((power_info->power_setting == NULL) &&
|
||||||
@@ -151,7 +150,10 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
|
|||||||
|
|
||||||
power_info->dev = soc_info->dev;
|
power_info->dev = soc_info->dev;
|
||||||
|
|
||||||
rc = cam_sensor_core_power_up(power_info, soc_info);
|
if (o_ctrl->io_master_info.master_type == I3C_MASTER)
|
||||||
|
i3c_probe_completion = cam_ois_get_i3c_completion(o_ctrl->soc_info.index);
|
||||||
|
|
||||||
|
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_OIS, "failed in ois power up rc %d", rc);
|
CAM_ERR(CAM_OIS, "failed in ois power up rc %d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef _CAM_OIS_CORE_H_
|
#ifndef _CAM_OIS_CORE_H_
|
||||||
#define _CAM_OIS_CORE_H_
|
#define _CAM_OIS_CORE_H_
|
||||||
@@ -30,5 +31,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *e_ctrl, void *arg);
|
|||||||
*/
|
*/
|
||||||
void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl);
|
void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl);
|
||||||
|
|
||||||
|
struct completion *cam_ois_get_i3c_completion(uint32_t index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* _CAM_OIS_CORE_H_ */
|
/* _CAM_OIS_CORE_H_ */
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cam_ois_dev.h"
|
#include "cam_ois_dev.h"
|
||||||
@@ -9,6 +10,17 @@
|
|||||||
#include "cam_ois_core.h"
|
#include "cam_ois_core.h"
|
||||||
#include "cam_debug_util.h"
|
#include "cam_debug_util.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
#include "cam_compat.h"
|
||||||
|
|
||||||
|
static struct cam_i3c_ois_data {
|
||||||
|
struct cam_ois_ctrl_t *o_ctrl;
|
||||||
|
struct completion probe_complete;
|
||||||
|
} g_i3c_ois_data[MAX_CAMERAS];
|
||||||
|
|
||||||
|
struct completion *cam_ois_get_i3c_completion(uint32_t index)
|
||||||
|
{
|
||||||
|
return &g_i3c_ois_data[index].probe_complete;
|
||||||
|
}
|
||||||
|
|
||||||
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
|
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_fh *fh)
|
struct v4l2_subdev_fh *fh)
|
||||||
@@ -372,6 +384,10 @@ static int cam_ois_component_bind(struct device *dev,
|
|||||||
|
|
||||||
platform_set_drvdata(pdev, o_ctrl);
|
platform_set_drvdata(pdev, o_ctrl);
|
||||||
o_ctrl->cam_ois_state = CAM_OIS_INIT;
|
o_ctrl->cam_ois_state = CAM_OIS_INIT;
|
||||||
|
|
||||||
|
g_i3c_ois_data[o_ctrl->soc_info.index].o_ctrl = o_ctrl;
|
||||||
|
init_completion(&g_i3c_ois_data[o_ctrl->soc_info.index].probe_complete);
|
||||||
|
|
||||||
CAM_DBG(CAM_OIS, "Component bound successfully");
|
CAM_DBG(CAM_OIS, "Component bound successfully");
|
||||||
return rc;
|
return rc;
|
||||||
unreg_subdev:
|
unreg_subdev:
|
||||||
@@ -485,8 +501,117 @@ struct i2c_driver cam_ois_i2c_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cam_ois_registered_driver_t registered_driver = {
|
static struct i3c_device_id ois_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
|
||||||
0, 0};
|
|
||||||
|
static int cam_ois_i3c_driver_probe(struct i3c_device *client)
|
||||||
|
{
|
||||||
|
int32_t rc = 0;
|
||||||
|
struct cam_ois_ctrl_t *o_ctrl = NULL;
|
||||||
|
uint32_t index;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
CAM_INFO(CAM_OIS, "Null Client pointer");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = &client->dev;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_OIS, "Probe for I3C Slave %s", dev_name(dev));
|
||||||
|
|
||||||
|
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_OIS, "device %s failed to read cell-index", dev_name(dev));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= MAX_CAMERAS) {
|
||||||
|
CAM_ERR(CAM_OIS, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
o_ctrl = g_i3c_ois_data[index].o_ctrl;
|
||||||
|
if (!o_ctrl) {
|
||||||
|
CAM_ERR(CAM_OIS, "o_ctrl is null. I3C Probe before platfom driver probe for %s",
|
||||||
|
dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
o_ctrl->io_master_info.i3c_client = client;
|
||||||
|
|
||||||
|
complete_all(&g_i3c_ois_data[index].probe_complete);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_OIS, "I3C Probe Finished for %s", dev_name(dev));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct i3c_driver cam_ois_i3c_driver = {
|
||||||
|
.id_table = ois_i3c_id,
|
||||||
|
.probe = cam_ois_i3c_driver_probe,
|
||||||
|
.remove = cam_i3c_driver_remove,
|
||||||
|
.driver = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.name = OIS_DRIVER_I3C,
|
||||||
|
.of_match_table = cam_ois_dt_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cam_ois_fill_i3c_device_id(void)
|
||||||
|
{
|
||||||
|
struct device_node *dev;
|
||||||
|
int num_entries;
|
||||||
|
int i = 0;
|
||||||
|
uint8_t ent_num = 0;
|
||||||
|
uint32_t mid;
|
||||||
|
uint32_t pid;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
|
||||||
|
if (!dev) {
|
||||||
|
CAM_WARN(CAM_OIS, "Couldnt Find the i3c-id-table dev node");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_entries = of_property_count_u32_elems(dev, "i3c-ois-id-table");
|
||||||
|
if (num_entries <= 0) {
|
||||||
|
CAM_WARN(CAM_OIS, "Failed while reading the property. num_entries:%d",
|
||||||
|
num_entries);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < num_entries) {
|
||||||
|
if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
|
||||||
|
CAM_WARN(CAM_OIS, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = of_property_read_u32_index(dev, "i3c-ois-id-table", i, &mid);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_OIS, "Failed in reading the MID. rc: %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
rc = of_property_read_u32_index(dev, "i3c-ois-id-table", i, &pid);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_OIS, "Failed in reading the PID. rc: %d", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_OIS, "PID: 0x%x, MID: 0x%x", pid, mid);
|
||||||
|
|
||||||
|
ois_i3c_id[ent_num].manuf_id = mid;
|
||||||
|
ois_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
|
||||||
|
ois_i3c_id[ent_num].part_id = pid;
|
||||||
|
ois_i3c_id[ent_num].data = 0;
|
||||||
|
|
||||||
|
ent_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cam_ois_driver_init(void)
|
int cam_ois_driver_init(void)
|
||||||
{
|
{
|
||||||
@@ -494,30 +619,42 @@ int cam_ois_driver_init(void)
|
|||||||
|
|
||||||
rc = platform_driver_register(&cam_ois_platform_driver);
|
rc = platform_driver_register(&cam_ois_platform_driver);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_OIS, "platform_driver_register failed rc = %d",
|
CAM_ERR(CAM_OIS, "platform_driver_register failed rc = %d", rc);
|
||||||
rc);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
registered_driver.platform_driver = 1;
|
|
||||||
|
|
||||||
rc = i2c_add_driver(&cam_ois_i2c_driver);
|
rc = i2c_add_driver(&cam_ois_i2c_driver);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR(CAM_OIS, "i2c_add_driver failed rc = %d", rc);
|
CAM_ERR(CAM_OIS, "i2c_add_driver failed rc = %d", rc);
|
||||||
return rc;
|
goto i2c_register_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
registered_driver.i2c_driver = 1;
|
memset(ois_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
|
||||||
|
rc = cam_ois_fill_i3c_device_id();
|
||||||
|
if (rc)
|
||||||
|
goto i3c_register_err;
|
||||||
|
|
||||||
|
rc = i3c_driver_register_with_owner(&cam_ois_i3c_driver, THIS_MODULE);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_OIS, "i3c_driver registration failed, rc: %d", rc);
|
||||||
|
goto i3c_register_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
i3c_register_err:
|
||||||
|
i2c_del_driver(&cam_ois_i2c_driver);
|
||||||
|
i2c_register_err:
|
||||||
|
platform_driver_unregister(&cam_ois_platform_driver);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cam_ois_driver_exit(void)
|
void cam_ois_driver_exit(void)
|
||||||
{
|
{
|
||||||
if (registered_driver.platform_driver)
|
platform_driver_unregister(&cam_ois_platform_driver);
|
||||||
platform_driver_unregister(&cam_ois_platform_driver);
|
i2c_del_driver(&cam_ois_i2c_driver);
|
||||||
|
i3c_driver_unregister(&cam_ois_i3c_driver);
|
||||||
if (registered_driver.i2c_driver)
|
|
||||||
i2c_del_driver(&cam_ois_i2c_driver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_DESCRIPTION("CAM OIS driver");
|
MODULE_DESCRIPTION("CAM OIS driver");
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
|
static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
|
||||||
|
|
||||||
#define OIS_DRIVER_I2C "cam-i2c-ois"
|
#define OIS_DRIVER_I2C "cam-i2c-ois"
|
||||||
|
#define OIS_DRIVER_I3C "i3c_camera_ois"
|
||||||
|
|
||||||
enum cam_ois_state {
|
enum cam_ois_state {
|
||||||
CAM_OIS_INIT,
|
CAM_OIS_INIT,
|
||||||
@@ -35,17 +36,6 @@ enum cam_ois_state {
|
|||||||
CAM_OIS_START,
|
CAM_OIS_START,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct cam_ois_registered_driver_t - registered driver info
|
|
||||||
* @platform_driver : flag indicates if platform driver is registered
|
|
||||||
* @i2c_driver : flag indicates if i2c driver is registered
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct cam_ois_registered_driver_t {
|
|
||||||
bool platform_driver;
|
|
||||||
bool i2c_driver;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct cam_ois_i2c_info_t - I2C info
|
* struct cam_ois_i2c_info_t - I2C info
|
||||||
* @slave_addr : slave address
|
* @slave_addr : slave address
|
||||||
|
@@ -866,9 +866,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||||||
struct cam_sensor_power_ctrl_t *power_info =
|
struct cam_sensor_power_ctrl_t *power_info =
|
||||||
&s_ctrl->sensordata->power_info;
|
&s_ctrl->sensordata->power_info;
|
||||||
struct timespec64 ts;
|
struct timespec64 ts;
|
||||||
struct completion *i3c_probe_completion;
|
|
||||||
uint64_t ms, sec, min, hrs;
|
uint64_t ms, sec, min, hrs;
|
||||||
long time_left;
|
|
||||||
|
|
||||||
if (!s_ctrl || !arg) {
|
if (!s_ctrl || !arg) {
|
||||||
CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
|
CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
|
||||||
@@ -943,6 +941,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||||||
);
|
);
|
||||||
goto free_power_settings;
|
goto free_power_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_ctrl->i2c_data.reg_bank_unlock_settings.is_settings_valid) {
|
if (s_ctrl->i2c_data.reg_bank_unlock_settings.is_settings_valid) {
|
||||||
rc = cam_sensor_apply_settings(s_ctrl, 0,
|
rc = cam_sensor_apply_settings(s_ctrl, 0,
|
||||||
CAM_SENSOR_PACKET_OPCODE_SENSOR_REG_BANK_UNLOCK);
|
CAM_SENSOR_PACKET_OPCODE_SENSOR_REG_BANK_UNLOCK);
|
||||||
@@ -958,20 +957,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_ctrl->io_master_info.master_type == I3C_MASTER) {
|
|
||||||
i3c_probe_completion =
|
|
||||||
cam_sensor_get_i3c_completion(s_ctrl->soc_info.index);
|
|
||||||
|
|
||||||
time_left = cam_common_wait_for_completion_timeout(
|
|
||||||
i3c_probe_completion,
|
|
||||||
msecs_to_jiffies(CAM_SENSOR_I3C_PROBE_TIMEOUT_MS));
|
|
||||||
if (!time_left) {
|
|
||||||
CAM_ERR(CAM_SENSOR, "Wait for I3C probe timedout for %s",
|
|
||||||
s_ctrl->sensor_name);
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Match sensor ID */
|
/* Match sensor ID */
|
||||||
rc = cam_sensor_match_id(s_ctrl);
|
rc = cam_sensor_match_id(s_ctrl);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -1428,9 +1413,9 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct cam_sensor_power_ctrl_t *power_info;
|
struct cam_sensor_power_ctrl_t *power_info;
|
||||||
struct cam_camera_slave_info *slave_info;
|
struct cam_camera_slave_info *slave_info;
|
||||||
struct cam_hw_soc_info *soc_info =
|
struct cam_hw_soc_info *soc_info = &s_ctrl->soc_info;
|
||||||
&s_ctrl->soc_info;
|
struct completion *i3c_probe_completion = NULL;
|
||||||
|
|
||||||
if (!s_ctrl) {
|
if (!s_ctrl) {
|
||||||
CAM_ERR(CAM_SENSOR, "failed: %pK", s_ctrl);
|
CAM_ERR(CAM_SENSOR, "failed: %pK", s_ctrl);
|
||||||
@@ -1469,7 +1454,10 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = cam_sensor_core_power_up(power_info, soc_info);
|
if (s_ctrl->io_master_info.master_type == I3C_MASTER)
|
||||||
|
i3c_probe_completion = cam_sensor_get_i3c_completion(s_ctrl->soc_info.index);
|
||||||
|
|
||||||
|
rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
CAM_ERR(CAM_SENSOR, "core power up failed:%d", rc);
|
CAM_ERR(CAM_SENSOR, "core power up failed:%d", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -572,7 +572,7 @@ static struct i3c_device_id sensor_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
|
|||||||
static struct i3c_driver cam_sensor_i3c_driver = {
|
static struct i3c_driver cam_sensor_i3c_driver = {
|
||||||
.id_table = sensor_i3c_id,
|
.id_table = sensor_i3c_id,
|
||||||
.probe = cam_sensor_i3c_driver_probe,
|
.probe = cam_sensor_i3c_driver_probe,
|
||||||
.remove = cam_sensor_i3c_driver_remove,
|
.remove = cam_i3c_driver_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = SENSOR_DRIVER_I3C,
|
.name = SENSOR_DRIVER_I3C,
|
||||||
|
@@ -12,6 +12,7 @@ static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxda
|
|||||||
enum camera_sensor_i2c_type addr_type, int data_length)
|
enum camera_sensor_i2c_type addr_type, int data_length)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
uint32_t us = 0;
|
||||||
struct i3c_priv_xfer read_buf[2] = {
|
struct i3c_priv_xfer read_buf[2] = {
|
||||||
{
|
{
|
||||||
.rnw = 0,
|
.rnw = 0,
|
||||||
@@ -26,7 +27,18 @@ static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxda
|
|||||||
};
|
};
|
||||||
|
|
||||||
rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
|
rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
|
||||||
if (rc)
|
if (rc == -ENOTCONN) {
|
||||||
|
while (us < CAM_I3C_DEV_PROBE_TIMEOUT_US) {
|
||||||
|
usleep_range(1000, 1005);
|
||||||
|
rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
|
||||||
|
if (rc != -ENOTCONN)
|
||||||
|
break;
|
||||||
|
us += 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_SENSOR, "Retry Failed i3c_read: rc = %d, us = %d", rc, us);
|
||||||
|
} else if (rc)
|
||||||
CAM_ERR(CAM_SENSOR, "Failed with i3c_read: rc = %d", rc);
|
CAM_ERR(CAM_SENSOR, "Failed with i3c_read: rc = %d", rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -37,6 +49,7 @@ static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char
|
|||||||
int length)
|
int length)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
uint32_t us = 0;
|
||||||
struct i3c_priv_xfer write_buf = {
|
struct i3c_priv_xfer write_buf = {
|
||||||
.rnw = 0,
|
.rnw = 0,
|
||||||
.len = length,
|
.len = length,
|
||||||
@@ -44,7 +57,18 @@ static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char
|
|||||||
};
|
};
|
||||||
|
|
||||||
rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
|
rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
|
||||||
if (rc)
|
if (rc == -ENOTCONN) {
|
||||||
|
while (us < CAM_I3C_DEV_PROBE_TIMEOUT_US) {
|
||||||
|
usleep_range(1000, 1005);
|
||||||
|
rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
|
||||||
|
if (rc != -ENOTCONN)
|
||||||
|
break;
|
||||||
|
us += 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_SENSOR, "Retry Failed i3c_write: rc = %d, us = %d", rc, us);
|
||||||
|
} else if (rc)
|
||||||
CAM_ERR(CAM_SENSOR, "Failed with i3c_write: rc = %d", rc);
|
CAM_ERR(CAM_SENSOR, "Failed with i3c_write: rc = %d", rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -23,7 +23,8 @@
|
|||||||
#define MAX_POWER_CONFIG 12
|
#define MAX_POWER_CONFIG 12
|
||||||
#define MAX_PER_FRAME_ARRAY 32
|
#define MAX_PER_FRAME_ARRAY 32
|
||||||
#define BATCH_SIZE_MAX 16
|
#define BATCH_SIZE_MAX 16
|
||||||
#define CAM_SENSOR_I3C_PROBE_TIMEOUT_MS 10
|
#define CAM_I3C_DEV_PROBE_TIMEOUT_MS 10
|
||||||
|
#define CAM_I3C_DEV_PROBE_TIMEOUT_US (CAM_I3C_DEV_PROBE_TIMEOUT_MS * 1000)
|
||||||
#define I3C_SENSOR_DEV_ID_DT_PATH "/soc/qcom,cam-i3c-id-table"
|
#define I3C_SENSOR_DEV_ID_DT_PATH "/soc/qcom,cam-i3c-id-table"
|
||||||
#define MAX_I3C_DEVICE_ID_ENTRIES MAX_CAMERAS
|
#define MAX_I3C_DEVICE_ID_ENTRIES MAX_CAMERAS
|
||||||
|
|
||||||
|
@@ -1977,12 +1977,13 @@ static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
|
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
|
||||||
struct cam_hw_soc_info *soc_info)
|
struct cam_hw_soc_info *soc_info, struct completion *i3c_probe_status)
|
||||||
{
|
{
|
||||||
int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0, i = 0;
|
int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0, i = 0;
|
||||||
int32_t vreg_idx = -1;
|
int32_t vreg_idx = -1;
|
||||||
struct cam_sensor_power_setting *power_setting = NULL;
|
struct cam_sensor_power_setting *power_setting = NULL;
|
||||||
struct msm_camera_gpio_num_info *gpio_num_info = NULL;
|
struct msm_camera_gpio_num_info *gpio_num_info = NULL;
|
||||||
|
long time_left;
|
||||||
|
|
||||||
CAM_DBG(CAM_SENSOR, "Enter");
|
CAM_DBG(CAM_SENSOR, "Enter");
|
||||||
if (!ctrl) {
|
if (!ctrl) {
|
||||||
@@ -2195,6 +2196,17 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
|
|||||||
(power_setting->delay * 1000) + 1000);
|
(power_setting->delay * 1000) + 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i3c_probe_status) {
|
||||||
|
time_left = cam_common_wait_for_completion_timeout(
|
||||||
|
i3c_probe_status,
|
||||||
|
msecs_to_jiffies(CAM_I3C_DEV_PROBE_TIMEOUT_MS));
|
||||||
|
if (!time_left) {
|
||||||
|
CAM_ERR(CAM_SENSOR, "Wait for I3C probe timedout");
|
||||||
|
rc = -ETIMEDOUT;
|
||||||
|
goto power_up_failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
power_up_failed:
|
power_up_failed:
|
||||||
CAM_ERR(CAM_SENSOR, "failed. rc:%d", rc);
|
CAM_ERR(CAM_SENSOR, "failed. rc:%d", rc);
|
||||||
|
@@ -66,7 +66,7 @@ int cam_sensor_util_init_gpio_pin_tbl(
|
|||||||
struct cam_hw_soc_info *soc_info,
|
struct cam_hw_soc_info *soc_info,
|
||||||
struct msm_camera_gpio_num_info **pgpio_num_info);
|
struct msm_camera_gpio_num_info **pgpio_num_info);
|
||||||
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
|
int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
|
||||||
struct cam_hw_soc_info *soc_info);
|
struct cam_hw_soc_info *soc_info, struct completion *i3c_probe_status);
|
||||||
|
|
||||||
int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
|
int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
|
||||||
struct cam_hw_soc_info *soc_info);
|
struct cam_hw_soc_info *soc_info);
|
||||||
|
@@ -366,7 +366,7 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
|
|||||||
dma_buf_vunmap(dmabuf, &mapping);
|
dma_buf_vunmap(dmabuf, &mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cam_sensor_i3c_driver_remove(struct i3c_device *client)
|
void cam_i3c_driver_remove(struct i3c_device *client)
|
||||||
{
|
{
|
||||||
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
|
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
|
||||||
(client ? dev_name(&client->dev) : "none"));
|
(client ? dev_name(&client->dev) : "none"));
|
||||||
@@ -411,7 +411,7 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
|
|||||||
dma_buf_vunmap(dmabuf, vaddr);
|
dma_buf_vunmap(dmabuf, vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cam_sensor_i3c_driver_remove(struct i3c_device *client)
|
int cam_i3c_driver_remove(struct i3c_device *client)
|
||||||
{
|
{
|
||||||
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
|
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
|
||||||
(client ? dev_name(&client->dev) : "none"));
|
(client ? dev_name(&client->dev) : "none"));
|
||||||
|
@@ -58,11 +58,11 @@ void cam_smmu_util_iommu_custom(struct device *dev,
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||||
int cam_req_mgr_ordered_list_cmp(void *priv,
|
int cam_req_mgr_ordered_list_cmp(void *priv,
|
||||||
const struct list_head *head_1, const struct list_head *head_2);
|
const struct list_head *head_1, const struct list_head *head_2);
|
||||||
void cam_sensor_i3c_driver_remove(struct i3c_device *client);
|
void cam_i3c_driver_remove(struct i3c_device *client);
|
||||||
#else
|
#else
|
||||||
int cam_req_mgr_ordered_list_cmp(void *priv,
|
int cam_req_mgr_ordered_list_cmp(void *priv,
|
||||||
struct list_head *head_1, struct list_head *head_2);
|
struct list_head *head_1, struct list_head *head_2);
|
||||||
int cam_sensor_i3c_driver_remove(struct i3c_device *client);
|
int cam_i3c_driver_remove(struct i3c_device *client);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
long cam_dma_buf_set_name(struct dma_buf *dmabuf, const char *name);
|
long cam_dma_buf_set_name(struct dma_buf *dmabuf, const char *name);
|
||||||
|
Reference in New Issue
Block a user