msm: camera: sensor: Add i3c bus support
Add i3c bus support for qup i3c based I3C target. CRs-Fixed: 3169593 Change-Id: I0209f799d800daf9afe7a846310a3d4f4f2ee420 Signed-off-by: Jigarkumar Zala <quic_jzala@quicinc.com> Signed-off-by: Jigar Agrawal <quic_jigar@quicinc.com>
This commit is contained in:

committed by
Camera Software Integration

parent
17e95f5f2f
commit
609d228234
1
Kbuild
1
Kbuild
@@ -231,6 +231,7 @@ camera-$(CONFIG_SPECTRA_SENSOR) += \
|
||||
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_io.o \
|
||||
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_cci_i2c.o \
|
||||
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.o \
|
||||
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i3c.o \
|
||||
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_spi.o \
|
||||
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.o \
|
||||
drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.o \
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
@@ -86,6 +87,7 @@ struct actuator_intf_params {
|
||||
* @cci_i2c_master: I2C structure
|
||||
* @io_master_info: Information about the communication master
|
||||
* @actuator_mutex: Actuator mutex
|
||||
* @is_i3c_device : A Flag to indicate whether this actuator is I3C device
|
||||
* @act_apply_state: Actuator settings aRegulator config
|
||||
* @id: Cell Index
|
||||
* @res_apply_state: Actuator settings apply state
|
||||
@@ -106,6 +108,7 @@ struct cam_actuator_ctrl_t {
|
||||
struct camera_io_master io_master_info;
|
||||
struct cam_hw_soc_info soc_info;
|
||||
struct mutex actuator_mutex;
|
||||
bool is_i3c_device;
|
||||
uint32_t id;
|
||||
enum cam_actuator_apply_state_t setting_apply_state;
|
||||
enum cam_actuator_state cam_act_state;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
@@ -34,6 +35,14 @@ int32_t cam_actuator_parse_dt(struct cam_actuator_ctrl_t *a_ctrl,
|
||||
|
||||
of_node = soc_info->dev->of_node;
|
||||
|
||||
rc = of_property_read_bool(of_node, "i3c-target");
|
||||
if (rc) {
|
||||
a_ctrl->is_i3c_device = true;
|
||||
a_ctrl->io_master_info.master_type = I3C_MASTER;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "I3C Target: %s", CAM_BOOL_TO_YESNO(a_ctrl->is_i3c_device));
|
||||
|
||||
if (a_ctrl->io_master_info.master_type == CCI_MASTER) {
|
||||
rc = of_property_read_u32(of_node, "cci-master",
|
||||
&(a_ctrl->cci_i2c_master));
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef _CAM_EEPROM_DEV_H_
|
||||
#define _CAM_EEPROM_DEV_H_
|
||||
@@ -164,6 +165,7 @@ struct eebin_info {
|
||||
* @gpio_num_info : gpio info
|
||||
* @cci_i2c_master : I2C structure
|
||||
* @v4l2_dev_str : V4L2 device structure
|
||||
* @is_i3c_device : A flag to indicate whether this eeprom is I3C device
|
||||
* @bridge_intf : bridge interface params
|
||||
* @cam_eeprom_state : eeprom_device_state
|
||||
* @userspace_probe : flag indicates userspace or kernel probe
|
||||
@@ -184,6 +186,7 @@ struct cam_eeprom_ctrl_t {
|
||||
enum cci_i2c_master_t cci_i2c_master;
|
||||
enum cci_device_num cci_num;
|
||||
struct cam_subdev v4l2_dev_str;
|
||||
bool is_i3c_device;
|
||||
struct cam_eeprom_intf_params bridge_intf;
|
||||
enum msm_camera_device_type_t eeprom_device_type;
|
||||
enum cam_eeprom_state cam_eeprom_state;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
@@ -304,6 +305,14 @@ int cam_eeprom_parse_dt(struct cam_eeprom_ctrl_t *e_ctrl)
|
||||
|
||||
of_node = soc_info->dev->of_node;
|
||||
|
||||
rc = of_property_read_bool(of_node, "i3c-target");
|
||||
if (rc) {
|
||||
e_ctrl->is_i3c_device = true;
|
||||
e_ctrl->io_master_info.master_type = I3C_MASTER;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "I3C Target: %s", CAM_BOOL_TO_YESNO(e_ctrl->is_i3c_device));
|
||||
|
||||
if (of_property_read_bool(of_node, "multimodule-support")) {
|
||||
CAM_DBG(CAM_UTIL, "Multi Module is Supported");
|
||||
e_ctrl->is_multimodule_mode = true;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef _CAM_OIS_DEV_H_
|
||||
#define _CAM_OIS_DEV_H_
|
||||
@@ -93,6 +94,7 @@ struct cam_ois_intf_params {
|
||||
* @io_master_info : Information about the communication master
|
||||
* @cci_i2c_master : I2C structure
|
||||
* @v4l2_dev_str : V4L2 device structure
|
||||
* @is_i3c_device : A Flag to indicate whether this OIS is I3C Device or not.
|
||||
* @bridge_intf : bridge interface params
|
||||
* @i2c_fwinit_data : ois i2c firmware init settings
|
||||
* @i2c_init_data : ois i2c init settings
|
||||
@@ -116,6 +118,7 @@ struct cam_ois_ctrl_t {
|
||||
enum cci_i2c_master_t cci_i2c_master;
|
||||
enum cci_device_num cci_num;
|
||||
struct cam_subdev v4l2_dev_str;
|
||||
bool is_i3c_device;
|
||||
struct cam_ois_intf_params bridge_intf;
|
||||
struct i2c_settings_array i2c_fwinit_data;
|
||||
struct i2c_settings_array i2c_init_data;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
@@ -41,6 +42,14 @@ static int cam_ois_get_dt_data(struct cam_ois_ctrl_t *o_ctrl)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = of_property_read_bool(of_node, "i3c-target");
|
||||
if (rc) {
|
||||
o_ctrl->is_i3c_device = true;
|
||||
o_ctrl->io_master_info.master_type = I3C_MASTER;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "I3C Target: %s", CAM_BOOL_TO_YESNO(o_ctrl->is_i3c_device));
|
||||
|
||||
/* Initialize regulators to default parameters */
|
||||
for (i = 0; i < soc_info->num_rgltr; i++) {
|
||||
soc_info->rgltr[i] = devm_regulator_get(soc_info->dev,
|
||||
@@ -126,7 +135,6 @@ int cam_ois_driver_soc_init(struct cam_ois_ctrl_t *o_ctrl)
|
||||
|
||||
o_ctrl->io_master_info.cci_client->cci_device = o_ctrl->cci_num;
|
||||
CAM_DBG(CAM_OIS, "cci-device %d", o_ctrl->cci_num, rc);
|
||||
|
||||
}
|
||||
|
||||
rc = cam_ois_get_dt_data(o_ctrl);
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "cam_common_util.h"
|
||||
#include "cam_packet_util.h"
|
||||
|
||||
extern struct completion *cam_sensor_get_i3c_completion(uint32_t index);
|
||||
|
||||
static int cam_sensor_update_req_mgr(
|
||||
struct cam_sensor_ctrl_t *s_ctrl,
|
||||
@@ -790,7 +791,9 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
||||
struct cam_sensor_power_ctrl_t *power_info =
|
||||
&s_ctrl->sensordata->power_info;
|
||||
struct timespec64 ts;
|
||||
struct completion *i3c_probe_completion;
|
||||
uint64_t ms, sec, min, hrs;
|
||||
long time_left;
|
||||
|
||||
if (!s_ctrl || !arg) {
|
||||
CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
|
||||
@@ -879,6 +882,21 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
|
||||
goto free_power_settings;
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
rc = cam_sensor_match_id(s_ctrl);
|
||||
if (rc < 0) {
|
||||
|
@@ -9,6 +9,17 @@
|
||||
#include "cam_sensor_soc.h"
|
||||
#include "cam_sensor_core.h"
|
||||
#include "camera_main.h"
|
||||
#include "cam_compat.h"
|
||||
|
||||
static struct cam_sensor_i3c_sensor_data {
|
||||
struct cam_sensor_ctrl_t *s_ctrl;
|
||||
struct completion probe_complete;
|
||||
} g_i3c_sensor_data[MAX_CAMERAS];
|
||||
|
||||
struct completion *cam_sensor_get_i3c_completion(uint32_t index)
|
||||
{
|
||||
return &g_i3c_sensor_data[index].probe_complete;
|
||||
}
|
||||
|
||||
static int cam_sensor_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
@@ -136,21 +147,14 @@ static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
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.internal_ops = &cam_sensor_internal_ops;
|
||||
s_ctrl->v4l2_dev_str.ops = &cam_sensor_subdev_ops;
|
||||
strscpy(s_ctrl->device_name, CAMX_SENSOR_DEV_NAME, CAM_CTX_DEV_NAME_MAX_LENGTH);
|
||||
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;
|
||||
s_ctrl->v4l2_dev_str.close_seq_prior =
|
||||
CAM_SD_CLOSE_MEDIUM_LOW_PRIORITY;
|
||||
s_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_LOW_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str));
|
||||
if (rc)
|
||||
@@ -159,6 +163,45 @@ static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_sensor_i3c_driver_probe(struct i3c_device *client)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
struct cam_sensor_ctrl_t *s_ctrl = NULL;
|
||||
uint32_t index;
|
||||
struct device *dev;
|
||||
|
||||
dev = i3cdev_to_dev(client);
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "Probe for I3C Slave %s", dev_name(dev));
|
||||
|
||||
rc = of_property_read_u32(dev->of_node, "cell-index", &index);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "device %s failed to read cell-index", dev_name(dev));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (index >= MAX_CAMERAS) {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s_ctrl = g_i3c_sensor_data[index].s_ctrl;
|
||||
if (!s_ctrl) {
|
||||
CAM_ERR(CAM_SENSOR, "S_ctrl is null. I3C Probe before platfom driver probe for %s",
|
||||
dev_name(dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
i3cdev_set_drvdata(client, s_ctrl);
|
||||
|
||||
s_ctrl->io_master_info.i3c_client = client;
|
||||
|
||||
complete_all(&g_i3c_sensor_data[index].probe_complete);
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "I3C Probe Finished for %s", dev_name(dev));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_sensor_i2c_component_bind(struct device *dev,
|
||||
struct device *master_dev, void *data)
|
||||
{
|
||||
@@ -358,6 +401,8 @@ static int cam_sensor_component_bind(struct device *dev,
|
||||
goto free_s_ctrl;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "Master Type: %u", s_ctrl->io_master_info.master_type);
|
||||
|
||||
/* Fill platform device id*/
|
||||
pdev->id = soc_info->index;
|
||||
|
||||
@@ -406,7 +451,10 @@ static int cam_sensor_component_bind(struct device *dev,
|
||||
s_ctrl->sensordata->power_info.dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, s_ctrl);
|
||||
s_ctrl->sensor_state = CAM_SENSOR_INIT;
|
||||
CAM_DBG(CAM_SENSOR, "Component bound successfully");
|
||||
CAM_DBG(CAM_SENSOR, "Component bound successfully for %s", pdev->name);
|
||||
|
||||
g_i3c_sensor_data[soc_info->index].s_ctrl = s_ctrl;
|
||||
init_completion(&g_i3c_sensor_data[soc_info->index].probe_complete);
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -464,13 +512,14 @@ static const struct of_device_id cam_sensor_driver_dt_match[] = {
|
||||
{.compatible = "qcom,cam-sensor"},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cam_sensor_driver_dt_match);
|
||||
|
||||
static int32_t cam_sensor_driver_platform_probe(
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "Adding Sensor component");
|
||||
CAM_DBG(CAM_SENSOR, "Adding Sensor component for %s", pdev->name);
|
||||
rc = component_add(&pdev->dev, &cam_sensor_component_ops);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR, "failed to add component rc: %d", rc);
|
||||
@@ -478,8 +527,6 @@ static int32_t cam_sensor_driver_platform_probe(
|
||||
return rc;
|
||||
}
|
||||
|
||||
MODULE_DEVICE_TABLE(of, cam_sensor_driver_dt_match);
|
||||
|
||||
struct platform_driver cam_sensor_platform_driver = {
|
||||
.probe = cam_sensor_driver_platform_probe,
|
||||
.driver = {
|
||||
@@ -495,7 +542,6 @@ 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[] = {
|
||||
@@ -515,20 +561,110 @@ struct i2c_driver cam_sensor_i2c_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct i3c_device_id sensor_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
|
||||
|
||||
static struct i3c_driver cam_sensor_i3c_driver = {
|
||||
.id_table = sensor_i3c_id,
|
||||
.probe = cam_sensor_i3c_driver_probe,
|
||||
.remove = cam_sensor_i3c_driver_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = SENSOR_DRIVER_I3C,
|
||||
.of_match_table = cam_sensor_driver_dt_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
||||
static int cam_sensor_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_SENSOR, "Couldnt Find the i3c-id-table dev node");
|
||||
return 0;
|
||||
}
|
||||
|
||||
num_entries = of_property_count_u32_elems(dev, "i3c-sensor-id-table");
|
||||
if (num_entries <= 0) {
|
||||
CAM_WARN(CAM_SENSOR, "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_SENSOR, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_index(dev, "i3c-sensor-id-table", i, &mid);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SENSOR, "Failed in reading the MID. rc: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
i++;
|
||||
|
||||
rc = of_property_read_u32_index(dev, "i3c-sensor-id-table", i, &pid);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SENSOR, "Failed in reading the PID. rc: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
i++;
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "PID: 0x%x, MID: 0x%x", pid, mid);
|
||||
|
||||
sensor_i3c_id[ent_num].manuf_id = mid;
|
||||
sensor_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
|
||||
sensor_i3c_id[ent_num].part_id = pid;
|
||||
sensor_i3c_id[ent_num].data = 0;
|
||||
|
||||
ent_num++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_sensor_driver_init(void)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
int rc;
|
||||
|
||||
rc = platform_driver_register(&cam_sensor_platform_driver);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR, "platform_driver_register Failed: rc = %d",
|
||||
rc);
|
||||
CAM_ERR(CAM_SENSOR, "platform_driver_register Failed: rc = %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = i2c_add_driver(&cam_sensor_i2c_driver);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SENSOR, "i2c_add_driver failed rc = %d", rc);
|
||||
goto i2c_register_err;
|
||||
}
|
||||
|
||||
memset(sensor_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
|
||||
|
||||
rc = cam_sensor_fill_i3c_device_id();
|
||||
if (rc)
|
||||
goto i3c_register_err;
|
||||
|
||||
rc = i3c_driver_register_with_owner(&cam_sensor_i3c_driver, THIS_MODULE);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SENSOR, "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:
|
||||
platform_driver_unregister(&cam_sensor_platform_driver);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -537,6 +673,7 @@ void cam_sensor_driver_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&cam_sensor_platform_driver);
|
||||
i2c_del_driver(&cam_sensor_i2c_driver);
|
||||
i3c_driver_unregister(&cam_sensor_i3c_driver);
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("cam_sensor_driver");
|
||||
|
@@ -28,16 +28,9 @@
|
||||
|
||||
#define NUM_MASTERS 2
|
||||
#define NUM_QUEUES 2
|
||||
|
||||
#undef CDBG
|
||||
#ifdef CAM_SENSOR_DEBUG
|
||||
#define CDBG(fmt, args...) pr_err(fmt, ##args)
|
||||
#else
|
||||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
#endif
|
||||
|
||||
#define SENSOR_DRIVER_I2C "cam-i2c-sensor"
|
||||
#define CAMX_SENSOR_DEV_NAME "cam-sensor-driver"
|
||||
#define SENSOR_DRIVER_I3C "i3c_camera_sensor"
|
||||
|
||||
enum cam_sensor_state_t {
|
||||
CAM_SENSOR_INIT,
|
||||
@@ -73,6 +66,7 @@ struct sensor_intf_params {
|
||||
* @sensor_state: Sensor states
|
||||
* @is_probe_succeed: Probe succeeded or not
|
||||
* @id: Cell Index
|
||||
* @is_i3c_device: A Flag to indicate whether this sensor is an I3C Device.
|
||||
* @of_node: Of node ptr
|
||||
* @v4l2_dev_str: V4L2 device structure
|
||||
* @sensor_probe_addr_type: Sensor probe address type
|
||||
@@ -90,8 +84,7 @@ struct sensor_intf_params {
|
||||
* @aon_camera_id: AON Camera ID associated with this sensor
|
||||
*/
|
||||
struct cam_sensor_ctrl_t {
|
||||
char device_name[
|
||||
CAM_CTX_DEV_NAME_MAX_LENGTH];
|
||||
char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
|
||||
struct platform_device *pdev;
|
||||
struct cam_hw_soc_info soc_info;
|
||||
struct mutex cam_sensor_mutex;
|
||||
@@ -102,6 +95,7 @@ struct cam_sensor_ctrl_t {
|
||||
enum cam_sensor_state_t sensor_state;
|
||||
uint8_t is_probe_succeed;
|
||||
uint32_t id;
|
||||
bool is_i3c_device;
|
||||
struct device_node *of_node;
|
||||
struct cam_subdev v4l2_dev_str;
|
||||
uint8_t sensor_probe_addr_type;
|
||||
|
@@ -110,14 +110,19 @@ static int32_t cam_sensor_init_bus_params(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
if (s_ctrl->io_master_info.master_type == CCI_MASTER) {
|
||||
s_ctrl->io_master_info.cci_client = kzalloc(sizeof(
|
||||
struct cam_sensor_cci_client), GFP_KERNEL);
|
||||
if (!(s_ctrl->io_master_info.cci_client))
|
||||
if (!(s_ctrl->io_master_info.cci_client)) {
|
||||
CAM_ERR(CAM_SENSOR, "Memory allocation failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else if (s_ctrl->io_master_info.master_type == I2C_MASTER) {
|
||||
if (!(s_ctrl->io_master_info.client))
|
||||
return -EINVAL;
|
||||
} else if (s_ctrl->io_master_info.master_type == I3C_MASTER) {
|
||||
CAM_DBG(CAM_SENSOR, "I3C Master Type");
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Invalid master / Master type Not supported");
|
||||
"Invalid master / Master type Not supported : %d",
|
||||
s_ctrl->io_master_info.master_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -161,6 +166,13 @@ static int32_t cam_sensor_driver_get_dt_data(struct cam_sensor_ctrl_t *s_ctrl)
|
||||
goto FREE_SENSOR_DATA;
|
||||
}
|
||||
|
||||
rc = of_property_read_bool(of_node, "i3c-target");
|
||||
if (rc) {
|
||||
CAM_INFO(CAM_SENSOR, "I3C Target");
|
||||
s_ctrl->is_i3c_device = true;
|
||||
s_ctrl->io_master_info.master_type = I3C_MASTER;
|
||||
}
|
||||
|
||||
/* Store the index of BoB regulator if it is available */
|
||||
for (i = 0; i < soc_info->num_rgltr; i++) {
|
||||
if (!strcmp(soc_info->rgltr_name[i],
|
||||
|
78
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_i3c.h
Normal file
78
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_i3c.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SENSOR_I3C_H_
|
||||
#define _CAM_SENSOR_I3C_H_
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/cam_sensor.h>
|
||||
#include "cam_sensor_io.h"
|
||||
|
||||
/**
|
||||
* cam_qup_i3c_read : This API handles QUP I3C read operations
|
||||
* @client : QUP IeC client structure
|
||||
* @data : I3C data
|
||||
* @addr_type : I3C address type
|
||||
* @data_type : I3C data type
|
||||
*/
|
||||
|
||||
int cam_qup_i3c_read(struct i3c_device *client,
|
||||
uint32_t addr, uint32_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type);
|
||||
|
||||
/**
|
||||
* cam_qup_i3c_read_seq : This API handles QUP I3C Sequential read operations
|
||||
* @client : QUP I3C client structure
|
||||
* @data : I3C data
|
||||
* @addr_type : I3C address type
|
||||
* @num_bytes : Number of bytes to read
|
||||
*/
|
||||
|
||||
int cam_qup_i3c_read_seq(struct i3c_device *client,
|
||||
uint32_t addr, uint8_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
uint32_t num_byte);
|
||||
|
||||
/**
|
||||
* cam_qup_i3c_poll : This API handles QUP based I3C poll operation
|
||||
* @client : QUP I3C client structure
|
||||
* @addr : I3C address
|
||||
* @data : I3C data
|
||||
* @data_mask : I3C data mask
|
||||
* @data_type : I3C data type
|
||||
* @addr_type : I3C addr type
|
||||
* @delay_ms : Delay in milli seconds
|
||||
*/
|
||||
|
||||
int cam_qup_i3c_poll(struct i3c_device *client,
|
||||
uint32_t addr, uint16_t data, uint16_t data_mask,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type,
|
||||
uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
* cam_qup_i3c_write_table : This API Handles QUP based I3C write random operations
|
||||
* @client : QUP I3C client structure
|
||||
* @write_setting : I3C register settings
|
||||
*/
|
||||
|
||||
int cam_qup_i3c_write_table(
|
||||
struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting);
|
||||
|
||||
/**
|
||||
* cam_qup_i3c_write_continuous_write: This API Handles QUP based I3C write continuous(Burst/Seq)
|
||||
* @client: QUP I3C client structure
|
||||
* @write_setting: I3C register setting
|
||||
* @cam_sensor_i3c_write_flag: burst or seq write
|
||||
*/
|
||||
int cam_qup_i3c_write_continuous_table(
|
||||
struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting,
|
||||
uint8_t cam_sensor_i3c_write_flag);
|
||||
|
||||
#endif /*_CAM_SENSOR_I3C_H_*/
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "cam_sensor_io.h"
|
||||
#include "cam_sensor_i2c.h"
|
||||
#include "cam_sensor_i3c.h"
|
||||
|
||||
int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
|
||||
uint32_t addr, uint16_t data, uint32_t data_mask,
|
||||
@@ -20,48 +21,49 @@ int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
switch (io_master_info->master_type) {
|
||||
case CCI_MASTER:
|
||||
return cam_cci_i2c_poll(io_master_info->cci_client,
|
||||
addr, data, mask, data_type, addr_type, delay_ms);
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
case I2C_MASTER:
|
||||
return cam_qup_i2c_poll(io_master_info->client,
|
||||
addr, data, data_mask, addr_type, data_type,
|
||||
delay_ms);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
addr, data, data_mask, addr_type, data_type, delay_ms);
|
||||
case I3C_MASTER:
|
||||
return cam_qup_i3c_poll(io_master_info->i3c_client,
|
||||
addr, data, data_mask, addr_type, data_type, delay_ms);
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type: %d", io_master_info->master_type);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_erase(struct camera_io_master *io_master_info,
|
||||
uint32_t addr, uint32_t size)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!io_master_info) {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return rc;
|
||||
return 0;
|
||||
|
||||
if (io_master_info->master_type == SPI_MASTER) {
|
||||
switch (io_master_info->master_type) {
|
||||
case SPI_MASTER:
|
||||
CAM_DBG(CAM_SENSOR, "Calling SPI Erase");
|
||||
return cam_spi_erase(io_master_info, addr,
|
||||
CAMERA_SENSOR_I2C_TYPE_WORD, size);
|
||||
} else if (io_master_info->master_type == I2C_MASTER ||
|
||||
io_master_info->master_type == CCI_MASTER) {
|
||||
CAM_ERR(CAM_SENSOR, "Erase not supported on master :%d",
|
||||
return cam_spi_erase(io_master_info, addr, CAMERA_SENSOR_I2C_TYPE_WORD, size);
|
||||
case I2C_MASTER:
|
||||
case CCI_MASTER:
|
||||
case I3C_MASTER:
|
||||
CAM_ERR(CAM_SENSOR, "Erase not supported on Master Type: %d",
|
||||
io_master_info->master_type);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
rc = -EINVAL;
|
||||
return -EINVAL;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type: %d", io_master_info->master_type);
|
||||
}
|
||||
return rc;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_read(struct camera_io_master *io_master_info,
|
||||
@@ -75,21 +77,23 @@ int32_t camera_io_dev_read(struct camera_io_master *io_master_info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
return cam_cci_i2c_read(io_master_info->cci_client,
|
||||
addr, data, addr_type, data_type, is_probing);
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
switch (io_master_info->master_type) {
|
||||
case SPI_MASTER:
|
||||
return cam_spi_read(io_master_info, addr, data, addr_type, data_type);
|
||||
case I2C_MASTER:
|
||||
return cam_qup_i2c_read(io_master_info->client,
|
||||
addr, data, addr_type, data_type);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_read(io_master_info,
|
||||
case CCI_MASTER:
|
||||
return cam_cci_i2c_read(io_master_info->cci_client,
|
||||
addr, data, addr_type, data_type, is_probing);
|
||||
case I3C_MASTER:
|
||||
return cam_qup_i3c_read(io_master_info->i3c_client,
|
||||
addr, data, addr_type, data_type);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type: %d", io_master_info->master_type);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info,
|
||||
@@ -97,24 +101,23 @@ int32_t camera_io_dev_read_seq(struct camera_io_master *io_master_info,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type, int32_t num_bytes)
|
||||
{
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
switch (io_master_info->master_type) {
|
||||
case CCI_MASTER:
|
||||
return cam_camera_cci_i2c_read_seq(io_master_info->cci_client,
|
||||
addr, data, addr_type, data_type, num_bytes);
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
case I2C_MASTER:
|
||||
return cam_qup_i2c_read_seq(io_master_info->client,
|
||||
addr, data, addr_type, num_bytes);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_read_seq(io_master_info,
|
||||
case SPI_MASTER:
|
||||
return cam_spi_read_seq(io_master_info, addr, data, addr_type, num_bytes);
|
||||
case I3C_MASTER:
|
||||
return cam_qup_i3c_read_seq(io_master_info->i3c_client,
|
||||
addr, data, addr_type, num_bytes);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_write_seq(io_master_info,
|
||||
addr, data, addr_type, num_bytes);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type: %d", io_master_info->master_type);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_write(struct camera_io_master *io_master_info,
|
||||
@@ -132,20 +135,20 @@ int32_t camera_io_dev_write(struct camera_io_master *io_master_info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
return cam_cci_i2c_write_table(io_master_info,
|
||||
write_setting);
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
return cam_qup_i2c_write_table(io_master_info,
|
||||
write_setting);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_write_table(io_master_info,
|
||||
write_setting);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
switch (io_master_info->master_type) {
|
||||
case CCI_MASTER:
|
||||
return cam_cci_i2c_write_table(io_master_info, write_setting);
|
||||
case I2C_MASTER:
|
||||
return cam_qup_i2c_write_table(io_master_info, write_setting);
|
||||
case SPI_MASTER:
|
||||
return cam_spi_write_table(io_master_info, write_setting);
|
||||
case I3C_MASTER:
|
||||
return cam_qup_i3c_write_table(io_master_info, write_setting);
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type:%d", io_master_info->master_type);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int32_t camera_io_dev_write_continuous(struct camera_io_master *io_master_info,
|
||||
@@ -164,20 +167,23 @@ int32_t camera_io_dev_write_continuous(struct camera_io_master *io_master_info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
switch (io_master_info->master_type) {
|
||||
case CCI_MASTER:
|
||||
return cam_cci_i2c_write_continuous_table(io_master_info,
|
||||
write_setting, cam_sensor_i2c_write_flag);
|
||||
} else if (io_master_info->master_type == I2C_MASTER) {
|
||||
case I2C_MASTER:
|
||||
return cam_qup_i2c_write_continuous_table(io_master_info,
|
||||
write_setting, cam_sensor_i2c_write_flag);
|
||||
} else if (io_master_info->master_type == SPI_MASTER) {
|
||||
return cam_spi_write_table(io_master_info,
|
||||
write_setting);
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Comm. Master:%d",
|
||||
io_master_info->master_type);
|
||||
return -EINVAL;
|
||||
case SPI_MASTER:
|
||||
return cam_spi_write_table(io_master_info, write_setting);
|
||||
case I3C_MASTER:
|
||||
return cam_qup_i3c_write_continuous_table(io_master_info,
|
||||
write_setting, cam_sensor_i2c_write_flag);
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type:%d", io_master_info->master_type);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int32_t camera_io_init(struct camera_io_master *io_master_info)
|
||||
@@ -187,14 +193,16 @@ int32_t camera_io_init(struct camera_io_master *io_master_info)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
io_master_info->cci_client->cci_subdev =
|
||||
cam_cci_get_subdev(io_master_info->cci_client->cci_device);
|
||||
return cam_sensor_cci_i2c_util(io_master_info->cci_client,
|
||||
MSM_CCI_INIT);
|
||||
} else if ((io_master_info->master_type == I2C_MASTER) ||
|
||||
(io_master_info->master_type == SPI_MASTER)) {
|
||||
return 0;
|
||||
switch (io_master_info->master_type) {
|
||||
case CCI_MASTER:
|
||||
io_master_info->cci_client->cci_subdev = cam_cci_get_subdev(
|
||||
io_master_info->cci_client->cci_device);
|
||||
return cam_sensor_cci_i2c_util(io_master_info->cci_client, MSM_CCI_INIT);
|
||||
case I2C_MASTER:
|
||||
case SPI_MASTER:
|
||||
case I3C_MASTER: return 0;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type:%d", io_master_info->master_type);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
@@ -207,12 +215,14 @@ int32_t camera_io_release(struct camera_io_master *io_master_info)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (io_master_info->master_type == CCI_MASTER) {
|
||||
return cam_sensor_cci_i2c_util(io_master_info->cci_client,
|
||||
MSM_CCI_RELEASE);
|
||||
} else if ((io_master_info->master_type == I2C_MASTER) ||
|
||||
(io_master_info->master_type == SPI_MASTER)) {
|
||||
return 0;
|
||||
switch (io_master_info->master_type) {
|
||||
case CCI_MASTER:
|
||||
return cam_sensor_cci_i2c_util(io_master_info->cci_client, MSM_CCI_RELEASE);
|
||||
case I2C_MASTER:
|
||||
case SPI_MASTER:
|
||||
case I3C_MASTER: return 0;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Master Type:%d", io_master_info->master_type);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
@@ -8,22 +8,25 @@
|
||||
#define _CAM_SENSOR_IO_H_
|
||||
|
||||
#include <media/cam_sensor.h>
|
||||
|
||||
#include "cam_sensor_cmn_header.h"
|
||||
|
||||
/* Master Types */
|
||||
#define CCI_MASTER 1
|
||||
#define I2C_MASTER 2
|
||||
#define SPI_MASTER 3
|
||||
#define I3C_MASTER 4
|
||||
|
||||
/**
|
||||
* @master_type: CCI master type
|
||||
* @client: I2C client information structure
|
||||
* @i2c_client: I2C client information structure
|
||||
* @i3c_client: I3C client information structure
|
||||
* @cci_client: CCI client information structure
|
||||
* @spi_client: SPI client information structure
|
||||
*/
|
||||
struct camera_io_master {
|
||||
int master_type;
|
||||
struct i2c_client *client;
|
||||
struct i3c_device *i3c_client;
|
||||
struct cam_sensor_cci_client *cci_client;
|
||||
struct cam_sensor_spi_client *spi_client;
|
||||
};
|
||||
@@ -116,4 +119,6 @@ int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
|
||||
|
||||
#include "cam_sensor_i2c.h"
|
||||
#include "cam_sensor_spi.h"
|
||||
#include "cam_sensor_i3c.h"
|
||||
|
||||
#endif /* _CAM_SENSOR_IO_H_ */
|
||||
|
517
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i3c.c
Normal file
517
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i3c.c
Normal file
@@ -0,0 +1,517 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_sensor_i3c.h"
|
||||
#include "cam_sensor_io.h"
|
||||
|
||||
#define I3C_REG_MAX_BUF_SIZE 8
|
||||
|
||||
static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxdata,
|
||||
enum camera_sensor_i2c_type addr_type, int data_length)
|
||||
{
|
||||
int rc;
|
||||
struct i3c_priv_xfer read_buf[2] = {
|
||||
{
|
||||
.rnw = 0,
|
||||
.len = addr_type,
|
||||
.data.out = rxdata,
|
||||
},
|
||||
{
|
||||
.rnw = 1,
|
||||
.len = data_length,
|
||||
.data.in = rxdata,
|
||||
},
|
||||
};
|
||||
|
||||
rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR, "Failed with i3c_read: rc = %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char *txdata,
|
||||
int length)
|
||||
{
|
||||
int rc;
|
||||
struct i3c_priv_xfer write_buf = {
|
||||
.rnw = 0,
|
||||
.len = length,
|
||||
.data.out = txdata,
|
||||
};
|
||||
|
||||
rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR, "Failed with i3c_write: rc = %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_qup_i3c_read(struct i3c_device *client, uint32_t addr, uint32_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf;
|
||||
|
||||
if ((addr_type <= CAMERA_SENSOR_I2C_TYPE_INVALID)
|
||||
|| (addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX)
|
||||
|| (data_type <= CAMERA_SENSOR_I2C_TYPE_INVALID)
|
||||
|| (data_type >= CAMERA_SENSOR_I2C_TYPE_MAX)) {
|
||||
CAM_ERR(CAM_SENSOR, "Failed with addr/data_type verfication");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf = kzalloc(addr_type + data_type, GFP_DMA | GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (addr_type == CAMERA_SENSOR_I2C_TYPE_BYTE) {
|
||||
buf[0] = addr;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_WORD) {
|
||||
buf[0] = addr >> 8;
|
||||
buf[1] = addr;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_3B) {
|
||||
buf[0] = addr >> 16;
|
||||
buf[1] = addr >> 8;
|
||||
buf[2] = addr;
|
||||
} else {
|
||||
buf[0] = addr >> 24;
|
||||
buf[1] = addr >> 16;
|
||||
buf[2] = addr >> 8;
|
||||
buf[3] = addr;
|
||||
}
|
||||
|
||||
rc = cam_qup_i3c_rxdata(client, buf, addr_type, data_type);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SENSOR, "failed rc: %d", rc);
|
||||
goto read_fail;
|
||||
}
|
||||
|
||||
if (data_type == CAMERA_SENSOR_I2C_TYPE_BYTE)
|
||||
*data = buf[0];
|
||||
else if (data_type == CAMERA_SENSOR_I2C_TYPE_WORD)
|
||||
*data = (buf[0] << 8) | buf[1];
|
||||
else if (data_type == CAMERA_SENSOR_I2C_TYPE_3B)
|
||||
*data = (buf[0] << 16) | (buf[1] << 8) | buf[2];
|
||||
else
|
||||
*data = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "addr = 0x%x data: 0x%x", addr, *data);
|
||||
read_fail:
|
||||
kfree(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_qup_i3c_read_seq(struct i3c_device *client,
|
||||
uint32_t addr, uint8_t *data,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
uint32_t num_byte)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf;
|
||||
int i;
|
||||
|
||||
if (addr_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX) {
|
||||
CAM_ERR(CAM_SENSOR, "Failed with addr_type verification");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if ((num_byte == 0) || (num_byte > I2C_REG_DATA_MAX)) {
|
||||
CAM_ERR(CAM_SENSOR, "num_byte:0x%x max supported:0x%x",
|
||||
num_byte, I2C_REG_DATA_MAX);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
buf = kzalloc(addr_type + num_byte, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (addr_type == CAMERA_SENSOR_I2C_TYPE_BYTE) {
|
||||
buf[0] = addr;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_WORD) {
|
||||
buf[0] = addr >> BITS_PER_BYTE;
|
||||
buf[1] = addr;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_3B) {
|
||||
buf[0] = addr >> 16;
|
||||
buf[1] = addr >> 8;
|
||||
buf[2] = addr;
|
||||
} else {
|
||||
buf[0] = addr >> 24;
|
||||
buf[1] = addr >> 16;
|
||||
buf[2] = addr >> 8;
|
||||
buf[3] = addr;
|
||||
}
|
||||
|
||||
rc = cam_qup_i3c_rxdata(client, buf, addr_type, num_byte);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_SENSOR, "failed rc: %d", rc);
|
||||
goto read_seq_fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_byte; i++)
|
||||
data[i] = buf[i];
|
||||
|
||||
read_seq_fail:
|
||||
kfree(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_qup_i3c_compare(struct i3c_device *client,
|
||||
uint32_t addr, uint32_t data, uint16_t data_mask,
|
||||
enum camera_sensor_i2c_type data_type,
|
||||
enum camera_sensor_i2c_type addr_type)
|
||||
{
|
||||
int rc;
|
||||
uint32_t reg_data;
|
||||
|
||||
rc = cam_qup_i3c_read(client, addr, ®_data,
|
||||
addr_type, data_type);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
reg_data = reg_data & 0xFFFF;
|
||||
if (data != (reg_data & ~data_mask))
|
||||
return I2C_COMPARE_MISMATCH;
|
||||
|
||||
return I2C_COMPARE_MATCH;
|
||||
}
|
||||
|
||||
int cam_qup_i3c_poll(struct i3c_device *client,
|
||||
uint32_t addr, uint16_t data, uint16_t data_mask,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type,
|
||||
uint32_t delay_ms)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
if ((delay_ms > MAX_POLL_DELAY_MS) || (delay_ms == 0)) {
|
||||
CAM_ERR(CAM_SENSOR, "invalid delay = %d max_delay = %d",
|
||||
delay_ms, MAX_POLL_DELAY_MS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((addr_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX
|
||||
|| data_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| data_type >= CAMERA_SENSOR_I2C_TYPE_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < delay_ms; i++) {
|
||||
rc = cam_qup_i3c_compare(client,
|
||||
addr, data, data_mask, data_type, addr_type);
|
||||
if (rc == I2C_COMPARE_MATCH)
|
||||
return rc;
|
||||
|
||||
usleep_range(1000, 1010);
|
||||
}
|
||||
/* If rc is MISMATCH then read is successful but poll is failure */
|
||||
if (rc == I2C_COMPARE_MISMATCH)
|
||||
CAM_ERR(CAM_SENSOR, "poll failed rc=%d(non-fatal)", rc);
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_SENSOR, "poll failed rc=%d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_qup_i3c_write(struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_array *reg_setting,
|
||||
enum camera_sensor_i2c_type addr_type,
|
||||
enum camera_sensor_i2c_type data_type)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf = NULL;
|
||||
uint8_t len = 0;
|
||||
|
||||
buf = kzalloc(I3C_REG_MAX_BUF_SIZE, GFP_KERNEL | GFP_DMA);
|
||||
if (!buf) {
|
||||
CAM_ERR(CAM_SENSOR, "Buffer memory allocation failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "reg addr = 0x%x data type: %d",
|
||||
reg_setting->reg_addr, data_type);
|
||||
if (addr_type == CAMERA_SENSOR_I2C_TYPE_INVALID) {
|
||||
buf[0] = reg_setting->reg_addr;
|
||||
CAM_DBG(CAM_SENSOR, "byte %d: 0x%x", len, buf[len]);
|
||||
len = 1;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_WORD) {
|
||||
buf[0] = reg_setting->reg_addr >> 8;
|
||||
buf[1] = reg_setting->reg_addr;
|
||||
CAM_DBG(CAM_SENSOR, "byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR, "byte %d: 0x%x", len+1, buf[len+1]);
|
||||
len = 2;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_3B) {
|
||||
buf[0] = reg_setting->reg_addr >> 16;
|
||||
buf[1] = reg_setting->reg_addr >> 8;
|
||||
buf[2] = reg_setting->reg_addr;
|
||||
len = 3;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_DWORD) {
|
||||
buf[0] = reg_setting->reg_addr >> 24;
|
||||
buf[1] = reg_setting->reg_addr >> 16;
|
||||
buf[2] = reg_setting->reg_addr >> 8;
|
||||
buf[3] = reg_setting->reg_addr;
|
||||
len = 4;
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid I2C addr type");
|
||||
rc = -EINVAL;
|
||||
goto deallocate_buffer;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "Data: 0x%x", reg_setting->reg_data);
|
||||
if (data_type == CAMERA_SENSOR_I2C_TYPE_BYTE) {
|
||||
buf[len] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len, buf[len]);
|
||||
len += 1;
|
||||
} else if (data_type == CAMERA_SENSOR_I2C_TYPE_WORD) {
|
||||
buf[len] = reg_setting->reg_data >> 8;
|
||||
buf[len+1] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len+1, buf[len+1]);
|
||||
len += 2;
|
||||
} else if (data_type == CAMERA_SENSOR_I2C_TYPE_3B) {
|
||||
buf[len] = reg_setting->reg_data >> 16;
|
||||
buf[len + 1] = reg_setting->reg_data >> 8;
|
||||
buf[len + 2] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len+1, buf[len+1]);
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len+2, buf[len+2]);
|
||||
len += 3;
|
||||
} else if (data_type == CAMERA_SENSOR_I2C_TYPE_DWORD) {
|
||||
buf[len] = reg_setting->reg_data >> 24;
|
||||
buf[len + 1] = reg_setting->reg_data >> 16;
|
||||
buf[len + 2] = reg_setting->reg_data >> 8;
|
||||
buf[len + 3] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len+1, buf[len+1]);
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len+2, buf[len+2]);
|
||||
CAM_DBG(CAM_SENSOR, "Byte %d: 0x%x", len+3, buf[len+3]);
|
||||
len += 4;
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Data Type");
|
||||
rc = -EINVAL;
|
||||
goto deallocate_buffer;
|
||||
}
|
||||
|
||||
rc = cam_qup_i3c_txdata(client, buf, len);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR, "failed rc: %d", rc);
|
||||
|
||||
deallocate_buffer:
|
||||
kfree(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_qup_i3c_write_table(struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting)
|
||||
{
|
||||
int i;
|
||||
int rc = -EINVAL;
|
||||
struct cam_sensor_i2c_reg_array *reg_setting;
|
||||
|
||||
if (!client || !write_setting)
|
||||
return -EINVAL;
|
||||
|
||||
if ((write_setting->addr_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| write_setting->addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX
|
||||
|| (write_setting->data_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| write_setting->data_type >= CAMERA_SENSOR_I2C_TYPE_MAX)))
|
||||
return -EINVAL;
|
||||
|
||||
reg_setting = write_setting->reg_setting;
|
||||
|
||||
for (i = 0; i < write_setting->size; i++) {
|
||||
CAM_DBG(CAM_SENSOR, "addr 0x%x data 0x%x",
|
||||
reg_setting->reg_addr, reg_setting->reg_data);
|
||||
|
||||
rc = cam_qup_i3c_write(client, reg_setting,
|
||||
write_setting->addr_type, write_setting->data_type);
|
||||
if (rc < 0)
|
||||
break;
|
||||
reg_setting++;
|
||||
}
|
||||
|
||||
if (write_setting->delay > 20)
|
||||
msleep(write_setting->delay);
|
||||
else if (write_setting->delay)
|
||||
usleep_range(write_setting->delay * 1000, (write_setting->delay
|
||||
* 1000) + 1000);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_qup_i3c_write_seq(struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting)
|
||||
{
|
||||
int i;
|
||||
int rc = 0;
|
||||
struct cam_sensor_i2c_reg_array *reg_setting;
|
||||
|
||||
reg_setting = write_setting->reg_setting;
|
||||
|
||||
for (i = 0; i < write_setting->size; i++) {
|
||||
reg_setting->reg_addr += i;
|
||||
rc = cam_qup_i3c_write(client, reg_setting,
|
||||
write_setting->addr_type, write_setting->data_type);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Sequential i2c write failed: rc: %d", rc);
|
||||
break;
|
||||
}
|
||||
reg_setting++;
|
||||
}
|
||||
|
||||
if (write_setting->delay > 20)
|
||||
msleep(write_setting->delay);
|
||||
else if (write_setting->delay)
|
||||
usleep_range(write_setting->delay * 1000, (write_setting->delay
|
||||
* 1000) + 1000);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_qup_i3c_write_burst(struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_setting)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
uint32_t len = 0;
|
||||
unsigned char *buf;
|
||||
struct cam_sensor_i2c_reg_array *reg_setting;
|
||||
enum camera_sensor_i2c_type addr_type;
|
||||
enum camera_sensor_i2c_type data_type;
|
||||
|
||||
buf = kzalloc((write_setting->addr_type +
|
||||
(write_setting->size * write_setting->data_type)),
|
||||
GFP_DMA | GFP_KERNEL);
|
||||
|
||||
if (!buf) {
|
||||
CAM_ERR(CAM_SENSOR, "BUF is NULL");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
reg_setting = write_setting->reg_setting;
|
||||
addr_type = write_setting->addr_type;
|
||||
data_type = write_setting->data_type;
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "reg addr = 0x%x data type: %d",
|
||||
reg_setting->reg_addr, data_type);
|
||||
if (addr_type == CAMERA_SENSOR_I2C_TYPE_BYTE) {
|
||||
buf[0] = reg_setting->reg_addr;
|
||||
CAM_DBG(CAM_SENSOR, "byte %d: 0x%x", len, buf[len]);
|
||||
len = 1;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_WORD) {
|
||||
buf[0] = reg_setting->reg_addr >> 8;
|
||||
buf[1] = reg_setting->reg_addr;
|
||||
CAM_DBG(CAM_SENSOR, "byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR, "byte %d: 0x%x", len+1, buf[len+1]);
|
||||
len = 2;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_3B) {
|
||||
buf[0] = reg_setting->reg_addr >> 16;
|
||||
buf[1] = reg_setting->reg_addr >> 8;
|
||||
buf[2] = reg_setting->reg_addr;
|
||||
len = 3;
|
||||
} else if (addr_type == CAMERA_SENSOR_I2C_TYPE_DWORD) {
|
||||
buf[0] = reg_setting->reg_addr >> 24;
|
||||
buf[1] = reg_setting->reg_addr >> 16;
|
||||
buf[2] = reg_setting->reg_addr >> 8;
|
||||
buf[3] = reg_setting->reg_addr;
|
||||
len = 4;
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid I2C addr type");
|
||||
rc = -EINVAL;
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
for (i = 0; i < write_setting->size; i++) {
|
||||
if (data_type == CAMERA_SENSOR_I2C_TYPE_BYTE) {
|
||||
buf[len] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len, buf[len]);
|
||||
len += 1;
|
||||
} else if (data_type == CAMERA_SENSOR_I2C_TYPE_WORD) {
|
||||
buf[len] = reg_setting->reg_data >> 8;
|
||||
buf[len+1] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len+1, buf[len+1]);
|
||||
len += 2;
|
||||
} else if (data_type == CAMERA_SENSOR_I2C_TYPE_3B) {
|
||||
buf[len] = reg_setting->reg_data >> 16;
|
||||
buf[len + 1] = reg_setting->reg_data >> 8;
|
||||
buf[len + 2] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len+1, buf[len+1]);
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len+2, buf[len+2]);
|
||||
len += 3;
|
||||
} else if (data_type == CAMERA_SENSOR_I2C_TYPE_DWORD) {
|
||||
buf[len] = reg_setting->reg_data >> 24;
|
||||
buf[len + 1] = reg_setting->reg_data >> 16;
|
||||
buf[len + 2] = reg_setting->reg_data >> 8;
|
||||
buf[len + 3] = reg_setting->reg_data;
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len, buf[len]);
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len+1, buf[len+1]);
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len+2, buf[len+2]);
|
||||
CAM_DBG(CAM_SENSOR,
|
||||
"Byte %d: 0x%x", len+3, buf[len+3]);
|
||||
len += 4;
|
||||
} else {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Data Type");
|
||||
rc = -EINVAL;
|
||||
goto free_res;
|
||||
}
|
||||
reg_setting++;
|
||||
}
|
||||
|
||||
if (len > (write_setting->addr_type +
|
||||
(write_setting->size * write_setting->data_type))) {
|
||||
CAM_ERR(CAM_SENSOR, "Invalid Length: %u | Expected length: %u",
|
||||
len, (write_setting->addr_type +
|
||||
(write_setting->size * write_setting->data_type)));
|
||||
rc = -EINVAL;
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
rc = cam_qup_i3c_txdata(client, buf, len);
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_SENSOR, "failed rc: %d", rc);
|
||||
|
||||
free_res:
|
||||
kfree(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_qup_i3c_write_continuous_table(struct camera_io_master *client,
|
||||
struct cam_sensor_i2c_reg_setting *write_settings,
|
||||
uint8_t cam_sensor_i2c_write_flag)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!client || !write_settings)
|
||||
return -EINVAL;
|
||||
|
||||
if ((write_settings->addr_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| write_settings->addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX
|
||||
|| (write_settings->data_type <= CAMERA_SENSOR_I2C_TYPE_INVALID
|
||||
|| write_settings->data_type >= CAMERA_SENSOR_I2C_TYPE_MAX)))
|
||||
return -EINVAL;
|
||||
|
||||
if (cam_sensor_i2c_write_flag == CAM_SENSOR_I2C_WRITE_BURST)
|
||||
rc = cam_qup_i3c_write_burst(client, write_settings);
|
||||
else if (cam_sensor_i2c_write_flag == CAM_SENSOR_I2C_WRITE_SEQ)
|
||||
rc = cam_qup_i3c_write_seq(client, write_settings);
|
||||
|
||||
return rc;
|
||||
}
|
@@ -8,6 +8,7 @@
|
||||
#define _CAM_SENSOR_CMN_HEADER_
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i3c/master.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -20,9 +21,11 @@
|
||||
#include <media/cam_req_mgr.h>
|
||||
|
||||
#define MAX_POWER_CONFIG 12
|
||||
|
||||
#define MAX_PER_FRAME_ARRAY 32
|
||||
#define BATCH_SIZE_MAX 16
|
||||
#define CAM_SENSOR_I3C_PROBE_TIMEOUT_MS 10
|
||||
#define I3C_SENSOR_DEV_ID_DT_PATH "/soc/qcom,cam-i3c-id-table"
|
||||
#define MAX_I3C_DEVICE_ID_ENTRIES MAX_CAMERAS
|
||||
|
||||
#define CAM_SENSOR_NAME "cam-sensor"
|
||||
#define CAM_ACTUATOR_NAME "cam-actuator"
|
||||
|
@@ -364,6 +364,12 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
|
||||
|
||||
dma_buf_vunmap(dmabuf, &mapping);
|
||||
}
|
||||
|
||||
void cam_sensor_i3c_driver_remove(struct i3c_device *client)
|
||||
{
|
||||
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s", dev_name(i3cdev_to_dev(client)));
|
||||
}
|
||||
|
||||
#else
|
||||
void cam_smmu_util_iommu_custom(struct device *dev,
|
||||
dma_addr_t discard_start, size_t discard_length)
|
||||
@@ -402,4 +408,10 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
|
||||
{
|
||||
dma_buf_vunmap(dmabuf, vaddr);
|
||||
}
|
||||
|
||||
int cam_sensor_i3c_driver_remove(struct i3c_device *client)
|
||||
{
|
||||
CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s", dev_name(i3cdev_to_dev(client)));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@@ -58,9 +58,11 @@ void cam_smmu_util_iommu_custom(struct device *dev,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
|
||||
int cam_req_mgr_ordered_list_cmp(void *priv,
|
||||
const struct list_head *head_1, const struct list_head *head_2);
|
||||
void cam_sensor_i3c_driver_remove(struct i3c_device *client);
|
||||
#else
|
||||
int cam_req_mgr_ordered_list_cmp(void *priv,
|
||||
struct list_head *head_1, struct list_head *head_2);
|
||||
int cam_sensor_i3c_driver_remove(struct i3c_device *client);
|
||||
#endif
|
||||
|
||||
#endif /* _CAM_COMPAT_H_ */
|
||||
|
Reference in New Issue
Block a user