mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
Merge e40030134a on remote branch
Change-Id: I61a691b1a48beb1b0c29c6e32201ff910bcec383
This commit is contained in:
commit
f873ee2ea4
66 changed files with 1624 additions and 216 deletions
18
Makefile
18
Makefile
|
|
@ -14,6 +14,10 @@ ifeq ($(CONFIG_ARCH_BENGAL), y)
|
|||
include $(srctree)/techpack/camera/config/bengalcamera.conf
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_MONACO), y)
|
||||
include $(srctree)/techpack/camera/config/monacocamera.conf
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_LAHAINA), y)
|
||||
include $(srctree)/techpack/camera/config/lahainacamera.conf
|
||||
endif
|
||||
|
|
@ -22,6 +26,10 @@ ifeq ($(CONFIG_ARCH_HOLI), y)
|
|||
include $(srctree)/techpack/camera/config/holicamera.conf
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_BLAIR), y)
|
||||
include $(srctree)/techpack/camera/config/blaircamera.conf
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SHIMA), y)
|
||||
include $(srctree)/techpack/camera/config/shimacamera.conf
|
||||
endif
|
||||
|
|
@ -45,6 +53,11 @@ LINUXINCLUDE += \
|
|||
-include $(srctree)/techpack/camera/config/bengalcameraconf.h
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_MONACO), y)
|
||||
LINUXINCLUDE += \
|
||||
-include $(srctree)/techpack/camera/config/monacocameraconf.h
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_LAHAINA), y)
|
||||
LINUXINCLUDE += \
|
||||
-include $(srctree)/techpack/camera/config/lahainacameraconf.h
|
||||
|
|
@ -55,6 +68,11 @@ LINUXINCLUDE += \
|
|||
-include $(srctree)/techpack/camera/config/holicameraconf.h
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_BLAIR), y)
|
||||
LINUXINCLUDE += \
|
||||
-include $(srctree)/techpack/camera/config/blaircameraconf.h
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SHIMA), y)
|
||||
LINUXINCLUDE += \
|
||||
-include $(srctree)/techpack/camera/config/shimacameraconf.h
|
||||
|
|
|
|||
17
config/blaircamera.conf
Normal file
17
config/blaircamera.conf
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
|
||||
ifeq ($(CONFIG_QGKI),y)
|
||||
export CONFIG_SPECTRA_CAMERA=m
|
||||
$(info "SPECTRA_CAMERA IS STATIC")
|
||||
else
|
||||
$(info "SPECTRA_CAMERA IS MODULAR")
|
||||
export CONFIG_SPECTRA_CAMERA=m
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m))
|
||||
export CONFIG_SPECTRA_ISP=y
|
||||
export CONFIG_SPECTRA_OPE=y
|
||||
export CONFIG_SPECTRA_TFE=y
|
||||
export CONFIG_SPECTRA_SENSOR=y
|
||||
endif
|
||||
10
config/blaircameraconf.h
Normal file
10
config/blaircameraconf.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define CONFIG_SPECTRA_CAMERA 1
|
||||
#define CONFIG_SPECTRA_ISP 1
|
||||
#define CONFIG_SPECTRA_OPE 1
|
||||
#define CONFIG_SPECTRA_TFE 1
|
||||
#define CONFIG_SPECTRA_SENSOR 1
|
||||
8
config/monacocamera.conf
Normal file
8
config/monacocamera.conf
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# Copyright (c) 2019,2021 The Linux Foundation. All rights reserved.
|
||||
|
||||
export CONFIG_SPECTRA_CAMERA=y
|
||||
export CONFIG_SPECTRA_TFE=y
|
||||
export CONFIG_SPECTRA_ISP=y
|
||||
export CONFIG_SPECTRA_SENSOR=y
|
||||
export CONFIG_SPECTRA_OPE=y
|
||||
11
config/monacocameraconf.h
Normal file
11
config/monacocameraconf.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define CONFIG_SPECTRA_CAMERA 1
|
||||
#define CONFIG_SPECTRA_TFE 1
|
||||
#define CONFIG_SPECTRA_ISP 1
|
||||
#define CONFIG_SPECTRA_SENSOR 1
|
||||
#define CONFIG_SPECTRA_OPE 1
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -583,6 +583,31 @@ int cam_context_handle_stop_dev(struct cam_context *ctx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
|
||||
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!ctx || !ctx->state_machine) {
|
||||
CAM_ERR(CAM_CORE, "Context is not ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cmd) {
|
||||
CAM_ERR(CAM_CORE, "Invalid stop device command payload");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev)
|
||||
rc = ctx->state_machine[ctx->state].ioctl_ops.shutdown_dev(
|
||||
(struct v4l2_subdev *)cmd->handle, fh);
|
||||
else
|
||||
CAM_WARN(CAM_CORE, "No shutdown device in dev %d, state %d",
|
||||
ctx->dev_hdl, ctx->state);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_context_handle_info_dump(void *context,
|
||||
enum cam_context_dump_id id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CONTEXT_H_
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/kref.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include "cam_req_mgr_interface.h"
|
||||
#include "cam_hw_mgr_intf.h"
|
||||
#include "cam_smmu_api.h"
|
||||
|
|
@ -95,6 +96,7 @@ struct cam_ctx_request {
|
|||
* @acquire_hw: Function pointer for acquire hw
|
||||
* @release_hw: Function pointer for release hw
|
||||
* @dump_dev: Function pointer for dump dev
|
||||
* @shutdown_dev: Function pointer for shutdown dev
|
||||
*
|
||||
*/
|
||||
struct cam_ctx_ioctl_ops {
|
||||
|
|
@ -114,6 +116,8 @@ struct cam_ctx_ioctl_ops {
|
|||
int (*release_hw)(struct cam_context *ctx, void *args);
|
||||
int (*dump_dev)(struct cam_context *ctx,
|
||||
struct cam_dump_req_cmd *cmd);
|
||||
int (*shutdown_dev)(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -479,6 +483,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
|
|||
int cam_context_handle_stop_dev(struct cam_context *ctx,
|
||||
struct cam_start_stop_dev_cmd *cmd);
|
||||
|
||||
/**
|
||||
* cam_context_handle_shutdown_dev()
|
||||
*
|
||||
* @brief: Handle shutdown device command
|
||||
*
|
||||
* @ctx: Object pointer for cam_context
|
||||
* @cmd: Shutdown device command payload
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*
|
||||
*/
|
||||
int cam_context_handle_shutdown_dev(struct cam_context *ctx,
|
||||
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
|
||||
|
||||
/**
|
||||
* cam_context_handle_dump_dev()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
|
@ -297,6 +297,27 @@ static int __cam_node_handle_stop_dev(struct cam_node *node,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_node_handle_shutdown_dev(struct cam_node *node,
|
||||
struct cam_control *cmd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_context *ctx = NULL;
|
||||
int32_t dev_index = -1;
|
||||
int rc = 0, ret = 0;
|
||||
|
||||
while ((dev_index = cam_get_dev_handle_info(cmd->handle,
|
||||
&ctx, dev_index)) < CAM_REQ_MGR_MAX_HANDLES_V2) {
|
||||
ret = cam_context_handle_shutdown_dev(ctx, cmd, fh);
|
||||
if (ret) {
|
||||
rc = ret;
|
||||
CAM_ERR(CAM_CORE, "Shutdown failure for node %s",
|
||||
node->name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_node_handle_config_dev(struct cam_node *node,
|
||||
struct cam_config_dev_cmd *config)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -100,4 +100,30 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
|
|||
*/
|
||||
void cam_node_put_ctxt_to_free_list(struct kref *ref);
|
||||
|
||||
/**
|
||||
* cam_get_dev_handle_info()
|
||||
*
|
||||
* @brief: provides the active dev index.
|
||||
*
|
||||
* @handle: pointer to struct v4l2_dev
|
||||
* @ctx: pointer to struct cam_context
|
||||
* @dev_index: dev index
|
||||
*
|
||||
*/
|
||||
int32_t cam_get_dev_handle_info(uint64_t handle,
|
||||
struct cam_context **ctx, int32_t dev_index);
|
||||
|
||||
/**
|
||||
* cam_node_handle_shutdown_dev()
|
||||
*
|
||||
* @brief: Shutdowns all the active devices.
|
||||
*
|
||||
* @node: pointer to struct node
|
||||
* @cmd: pointer to struct cmd
|
||||
* @fh: pointer to struct v4l2_subdev_fh
|
||||
*
|
||||
*/
|
||||
int cam_node_handle_shutdown_dev(struct cam_node *node,
|
||||
struct cam_control *cmd, struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* _CAM_NODE_H_ */
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
|
|||
long rc;
|
||||
struct cam_node *node =
|
||||
(struct cam_node *) v4l2_get_subdevdata(sd);
|
||||
struct v4l2_subdev_fh *fh = (struct v4l2_subdev_fh *)arg;
|
||||
struct cam_control cntrl_cmd;
|
||||
|
||||
if (!node || node->state == CAM_NODE_STATE_UNINIT) {
|
||||
rc = -EINVAL;
|
||||
|
|
@ -56,6 +58,19 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,
|
|||
rc = cam_node_handle_ioctl(node,
|
||||
(struct cam_control *) arg);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_WARN(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cntrl_cmd.op_code = CAM_SD_SHUTDOWN;
|
||||
cntrl_cmd.handle = (uint64_t)sd;
|
||||
rc = cam_node_handle_shutdown_dev(node, &cntrl_cmd, fh);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CORE, "shutdown device failed(rc = %d)",
|
||||
rc);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
|
||||
node->name);
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ static int cam_cpas_subdev_open(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
||||
static int __cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_cpas_intf *cpas_intf = v4l2_get_subdevdata(sd);
|
||||
|
|
@ -702,6 +702,11 @@ static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
mutex_lock(&cpas_intf->intf_lock);
|
||||
if (cpas_intf->open_cnt <= 0) {
|
||||
CAM_WARN(CAM_CPAS, "device already closed, open_cnt: %d", cpas_intf->open_cnt);
|
||||
mutex_unlock(&cpas_intf->intf_lock);
|
||||
return 0;
|
||||
}
|
||||
cpas_intf->open_cnt--;
|
||||
CAM_DBG(CAM_CPAS, "CPAS Subdev close count %d", cpas_intf->open_cnt);
|
||||
mutex_unlock(&cpas_intf->intf_lock);
|
||||
|
|
@ -709,6 +714,19 @@ static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_cpas_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_CPAS);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_CPAS, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __cam_cpas_subdev_close(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
|
|
@ -724,6 +742,9 @@ static long cam_cpas_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_cpas_subdev_cmd(cpas_intf, (struct cam_control *) arg);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
rc = __cam_cpas_subdev_close(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CPAS, "Invalid command %d for CPAS!", cmd);
|
||||
rc = -EINVAL;
|
||||
|
|
@ -811,6 +832,7 @@ static int cam_cpas_subdev_register(struct platform_device *pdev)
|
|||
subdev->sd_flags =
|
||||
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
subdev->ent_function = CAM_CPAS_DEVICE_TYPE;
|
||||
subdev->close_seq_prior = CAM_SD_CLOSE_LOW_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(subdev);
|
||||
if (rc) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include "cpastop_v540_100.h"
|
||||
#include "cpastop_v520_100.h"
|
||||
#include "cpastop_v545_100.h"
|
||||
#include "cpastop_v545_110.h"
|
||||
#include "cpastop_v570_200.h"
|
||||
#include "cpastop_v680_100.h"
|
||||
#include "cpastop_v165_100.h"
|
||||
|
|
@ -119,7 +120,7 @@ static const uint32_t cam_cpas_hw_version_map
|
|||
{
|
||||
CAM_CPAS_TITAN_545_V100,
|
||||
0,
|
||||
0,
|
||||
CAM_CPAS_TITAN_545_V110,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -934,6 +935,10 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
|
|||
camnoc_info = &cam545_cpas100_camnoc_info;
|
||||
qchannel_info = &cam545_cpas100_qchannel_info;
|
||||
break;
|
||||
case CAM_CPAS_TITAN_545_V110:
|
||||
camnoc_info = &cam545_cpas110_camnoc_info;
|
||||
qchannel_info = &cam545_cpas110_qchannel_info;
|
||||
break;
|
||||
case CAM_CPAS_TITAN_570_V200:
|
||||
camnoc_info = &cam570_cpas200_camnoc_info;
|
||||
qchannel_info = &cam570_cpas200_qchannel_info;
|
||||
|
|
|
|||
|
|
@ -289,6 +289,27 @@ static struct cam_camnoc_specific
|
|||
*/
|
||||
.enable = false,
|
||||
},
|
||||
.qosgen_mainctl = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4808, /* IFE01234_RDI_QOSGEN_MAINCTL */
|
||||
.value = 0x2,
|
||||
},
|
||||
.qosgen_shaping_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4820, /* IFE01234_RDI_QOSGEN_SHAPING_LOW */
|
||||
.value = 0x07070707,
|
||||
},
|
||||
.qosgen_shaping_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4824, /* IFE01234_RDI_QOSGEN_SHAPING_HIGH */
|
||||
.value = 0x07070707,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_IFE01_NRDI_WRITE,
|
||||
|
|
@ -343,6 +364,27 @@ static struct cam_camnoc_specific
|
|||
.offset = 0x3B88, /* IFE01_NRDI_ENCCTL_LOW */
|
||||
.value = 1,
|
||||
},
|
||||
.qosgen_mainctl = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4708, /* IFE01_NRDI_QOSGEN_MAINCTL */
|
||||
.value = 0x2,
|
||||
},
|
||||
.qosgen_shaping_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4720, /* IFE01_NRDI_QOSGEN_SHAPING_LOW */
|
||||
.value = 0x07070707,
|
||||
},
|
||||
.qosgen_shaping_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4724, /* IFE01_NRDI_QOSGEN_SHAPING_HIGH */
|
||||
.value = 0x07070707,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_IFE2_NRDI_WRITE,
|
||||
|
|
@ -397,6 +439,27 @@ static struct cam_camnoc_specific
|
|||
.offset = 0x5588, /* IFE2_NRDI_ENCCTL_LOW */
|
||||
.value = 0,
|
||||
},
|
||||
.qosgen_mainctl = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x5188, /* IFE2_NRDI_QOSGEN_MAINCTL */
|
||||
.value = 0x2,
|
||||
},
|
||||
.qosgen_shaping_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x51A0, /* IFE2_NRDI_QOSGEN_SHAPING_LOW */
|
||||
.value = 0x07070707,
|
||||
},
|
||||
.qosgen_shaping_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x51A4, /* IFE2_NRDI_QOSGEN_SHAPING_HIGH */
|
||||
.value = 0x07070707,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
|
||||
|
|
|
|||
322
drivers/cam_cpas/cpas_top/cpastop_v545_110.h
Normal file
322
drivers/cam_cpas/cpas_top/cpastop_v545_110.h
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CPASTOP_V545_110_H_
|
||||
#define _CPASTOP_V545_110_H_
|
||||
|
||||
#define TEST_IRQ_ENABLE 0
|
||||
|
||||
static struct cam_camnoc_irq_sbm cam_cpas_v545_110_irq_sbm = {
|
||||
.sbm_enable = {
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xA40, /* SBM_FAULTINEN0_LOW */
|
||||
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
|
||||
(TEST_IRQ_ENABLE ?
|
||||
0x2 : /* SBM_FAULTINEN0_LOW_PORT6_MASK */
|
||||
0x0) /* SBM_FAULTINEN0_LOW_PORT1_MASK */,
|
||||
},
|
||||
.sbm_status = {
|
||||
.access_type = CAM_REG_TYPE_READ,
|
||||
.enable = true,
|
||||
.offset = 0xA48, /* SBM_FAULTINSTATUS0_LOW */
|
||||
},
|
||||
.sbm_clear = {
|
||||
.access_type = CAM_REG_TYPE_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xA80, /* SBM_FLAGOUTCLR0_LOW */
|
||||
.value = TEST_IRQ_ENABLE ? 0x3 : 0x1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct cam_camnoc_irq_err
|
||||
cam_cpas_v545_110_irq_err[] = {
|
||||
{
|
||||
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
|
||||
.enable = true,
|
||||
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
|
||||
.err_enable = {
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xD08, /* ERRORLOGGER_MAINCTL_LOW */
|
||||
.value = 1,
|
||||
},
|
||||
.err_status = {
|
||||
.access_type = CAM_REG_TYPE_READ,
|
||||
.enable = true,
|
||||
.offset = 0xD10, /* ERRORLOGGER_ERRVLD_LOW */
|
||||
},
|
||||
.err_clear = {
|
||||
.access_type = CAM_REG_TYPE_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xD18, /* ERRORLOGGER_ERRCLR_LOW */
|
||||
.value = 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
|
||||
.enable = TEST_IRQ_ENABLE ? true : false,
|
||||
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
|
||||
.err_enable = {
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xA88, /* SBM_FLAGOUTSET0_LOW */
|
||||
.value = 0x1,
|
||||
},
|
||||
.err_status = {
|
||||
.access_type = CAM_REG_TYPE_READ,
|
||||
.enable = true,
|
||||
.offset = 0xA90, /* SBM_FLAGOUTSTATUS0_LOW */
|
||||
},
|
||||
.err_clear = {
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct cam_camnoc_specific
|
||||
cam_cpas_v545_110_camnoc_specific[] = {
|
||||
{
|
||||
.port_type = CAM_CAMNOC_CDM,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE30, /* CDM_PRIORITYLUT_LOW */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE34, /* CDM_PRIORITYLUT_HIGH */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE38, /* CDM_URGENCY_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE40, /* CDM_DANGERLUT_LOW */
|
||||
.value = 0x0,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE48, /* CDM_SAFELUT_LOW */
|
||||
.value = 0x0,
|
||||
},
|
||||
.ubwc_ctl = {
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_TFE,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_LOW */
|
||||
.offset = 0x30,
|
||||
.value = 0x55554433,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_HIGH */
|
||||
.offset = 0x34,
|
||||
.value = 0x66666655,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x38, /* TFE_URGENCY_LOW */
|
||||
.value = 0x00001030,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x40, /* TFE_DANGERLUT_LOW */
|
||||
.value = 0xffff0000,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x48, /* TFE_SAFELUT_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
.ubwc_ctl = {
|
||||
/*
|
||||
* Do not explicitly set ubwc config register.
|
||||
* Power on default values are taking care of required
|
||||
* register settings.
|
||||
*/
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_TFE_1,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_LOW */
|
||||
.offset = 0x4030,
|
||||
.value = 0x55554433,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_HIGH */
|
||||
.offset = 0x4034,
|
||||
.value = 0x66666655,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4038, /* TFE_URGENCY_LOW */
|
||||
.value = 0x00001030,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x4040, /* TFE_DANGERLUT_LOW */
|
||||
.value = 0xffff0000,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x4048, /* TFE_SAFELUT_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_TFE_2,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_LOW */
|
||||
.offset = 0x5030,
|
||||
.value = 0x55554433,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_HIGH */
|
||||
.offset = 0x5034,
|
||||
.value = 0x66666655,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x5038, /* TFE_URGENCY_LOW */
|
||||
.value = 0x00001030,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x5040, /* TFE_DANGERLUT_LOW */
|
||||
.value = 0xffff0000,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x5048, /* TFE_SAFELUT_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_OPE,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x430, /* OPE_PRIORITYLUT_LOW */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x434, /* OPE_PRIORITYLUT_HIGH */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x438, /* OPE_URGENCY_LOW */
|
||||
.value = 0x00000033,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x440, /* OPE_DANGERLUT_LOW */
|
||||
.value = 0xFFFFFF00,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x448, /* OPE_SAFELUT_LOW */
|
||||
.value = 0xF,
|
||||
},
|
||||
.ubwc_ctl = {
|
||||
/*
|
||||
* Do not explicitly set ubwc config register.
|
||||
* Power on default values are taking care of required
|
||||
* register settings.
|
||||
*/
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct cam_camnoc_err_logger_info cam545_cpas110_err_logger_offsets = {
|
||||
.mainctrl = 0xD08, /* ERRLOGGER_MAINCTL_LOW */
|
||||
.errvld = 0xD10, /* ERRLOGGER_ERRVLD_LOW */
|
||||
.errlog0_low = 0xD20, /* ERRLOGGER_ERRLOG0_LOW */
|
||||
.errlog0_high = 0xD24, /* ERRLOGGER_ERRLOG0_HIGH */
|
||||
.errlog1_low = 0xD28, /* ERRLOGGER_ERRLOG1_LOW */
|
||||
.errlog1_high = 0xD2C, /* ERRLOGGER_ERRLOG1_HIGH */
|
||||
.errlog2_low = 0xD30, /* ERRLOGGER_ERRLOG2_LOW */
|
||||
.errlog2_high = 0xD34, /* ERRLOGGER_ERRLOG2_HIGH */
|
||||
.errlog3_low = 0xD38, /* ERRLOGGER_ERRLOG3_LOW */
|
||||
.errlog3_high = 0xD3C, /* ERRLOGGER_ERRLOG3_HIGH */
|
||||
};
|
||||
|
||||
static struct cam_camnoc_info cam545_cpas110_camnoc_info = {
|
||||
.specific = &cam_cpas_v545_110_camnoc_specific[0],
|
||||
.specific_size = ARRAY_SIZE(cam_cpas_v545_110_camnoc_specific),
|
||||
.irq_sbm = &cam_cpas_v545_110_irq_sbm,
|
||||
.irq_err = &cam_cpas_v545_110_irq_err[0],
|
||||
.irq_err_size = ARRAY_SIZE(cam_cpas_v545_110_irq_err),
|
||||
.err_logger = &cam545_cpas110_err_logger_offsets,
|
||||
.errata_wa_list = NULL,
|
||||
};
|
||||
|
||||
static struct cam_cpas_camnoc_qchannel cam545_cpas110_qchannel_info = {
|
||||
.qchannel_ctrl = 0x14,
|
||||
.qchannel_status = 0x18,
|
||||
};
|
||||
#endif /* _CPASTOP_V545_110_H_ */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CPAS_API_H_
|
||||
|
|
@ -139,6 +139,7 @@ enum cam_cpas_hw_version {
|
|||
CAM_CPAS_TITAN_540_V100 = 0x540100,
|
||||
CAM_CPAS_TITAN_520_V100 = 0x520100,
|
||||
CAM_CPAS_TITAN_545_V100 = 0x545100,
|
||||
CAM_CPAS_TITAN_545_V110 = 0x545110,
|
||||
CAM_CPAS_TITAN_570_V200 = 0x570200,
|
||||
CAM_CPAS_TITAN_680_V100 = 0x680100,
|
||||
CAM_CPAS_TITAN_MAX
|
||||
|
|
|
|||
|
|
@ -1604,6 +1604,19 @@ static int __cam_custom_ctx_apply_default_req(
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_custom_ctx_shutdown_dev(
|
||||
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!sd || !fh) {
|
||||
CAM_ERR(CAM_CUSTOM, "Invalid input pointer");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return cam_custom_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
/* top state machine */
|
||||
static struct cam_ctx_ops
|
||||
cam_custom_dev_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
|
|
@ -1618,6 +1631,7 @@ static struct cam_ctx_ops
|
|||
.ioctl_ops = {
|
||||
.acquire_dev =
|
||||
__cam_custom_ctx_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -1629,6 +1643,7 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_custom_release_dev_in_acquired,
|
||||
.config_dev = __cam_custom_ctx_config_dev_in_acquired,
|
||||
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
|
||||
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.link = __cam_custom_ctx_link_in_acquired,
|
||||
|
|
@ -1647,6 +1662,7 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_custom_release_dev_in_acquired,
|
||||
.config_dev = __cam_custom_ctx_config_dev,
|
||||
.release_hw = __cam_custom_ctx_release_hw_in_top_state,
|
||||
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.unlink = __cam_custom_ctx_unlink_in_ready,
|
||||
|
|
@ -1664,6 +1680,7 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_custom_ctx_config_dev_in_flushed,
|
||||
.release_hw =
|
||||
__cam_custom_ctx_release_hw_in_activated_state,
|
||||
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.unlink = __cam_custom_ctx_unlink_in_ready,
|
||||
|
|
@ -1680,6 +1697,7 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_custom_ctx_config_dev,
|
||||
.release_hw =
|
||||
__cam_custom_ctx_release_hw_in_activated_state,
|
||||
.shutdown_dev = __cam_custom_ctx_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.unlink = __cam_custom_ctx_unlink_in_activated,
|
||||
|
|
|
|||
|
|
@ -150,4 +150,16 @@ int cam_custom_dev_context_init(struct cam_custom_context *ctx,
|
|||
*/
|
||||
int cam_custom_dev_context_deinit(struct cam_custom_context *ctx);
|
||||
|
||||
/**
|
||||
* cam_custom_subdev_close_internal()
|
||||
*
|
||||
* @brief: Close function for the Custom context
|
||||
*
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*
|
||||
*/
|
||||
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* _CAM_CUSTOM_CONTEXT_H_ */
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ static int cam_custom_subdev_open(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
|
||||
int cam_custom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -86,6 +86,19 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_custom_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_CUSTOM);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_CUSTOM, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_custom_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops cam_custom_subdev_internal_ops = {
|
||||
.close = cam_custom_subdev_close,
|
||||
.open = cam_custom_subdev_open,
|
||||
|
|
@ -102,6 +115,7 @@ static int cam_custom_component_bind(struct device *dev,
|
|||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
g_custom_dev.sd.internal_ops = &cam_custom_subdev_internal_ops;
|
||||
g_custom_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
|
||||
|
||||
rc = cam_subdev_probe(&g_custom_dev.sd, pdev, CAM_CUSTOM_DEV_NAME,
|
||||
CAM_CUSTOM_DEVICE_TYPE);
|
||||
|
|
|
|||
|
|
@ -169,6 +169,19 @@ static int __cam_fd_ctx_handle_irq_in_activated(void *context,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_fd_shutdown_dev(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!sd || !fh) {
|
||||
CAM_ERR(CAM_FD, "Invalid input pointer");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return cam_fd_dev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
/* top state machine */
|
||||
static struct cam_ctx_ops
|
||||
cam_fd_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
|
|
@ -182,6 +195,7 @@ static struct cam_ctx_ops
|
|||
{
|
||||
.ioctl_ops = {
|
||||
.acquire_dev = __cam_fd_ctx_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -192,18 +206,25 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_fd_ctx_release_dev_in_acquired,
|
||||
.config_dev = __cam_fd_ctx_config_dev_in_acquired,
|
||||
.start_dev = __cam_fd_ctx_start_dev_in_acquired,
|
||||
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
/* Ready */
|
||||
{
|
||||
.ioctl_ops = { },
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
/* Flushed */
|
||||
{},
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||
},
|
||||
},
|
||||
/* Activated */
|
||||
{
|
||||
.ioctl_ops = {
|
||||
|
|
@ -212,6 +233,7 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_fd_ctx_config_dev_in_activated,
|
||||
.flush_dev = __cam_fd_ctx_flush_dev_in_activated,
|
||||
.dump_dev = __cam_fd_ctx_dump_dev_in_activated,
|
||||
.shutdown_dev = __cam_fd_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = __cam_fd_ctx_handle_irq_in_activated,
|
||||
|
|
|
|||
|
|
@ -27,4 +27,15 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx,
|
|||
uint32_t ctx_id);
|
||||
int cam_fd_context_deinit(struct cam_fd_context *ctx);
|
||||
|
||||
/**
|
||||
* cam_fd_dev_close_internal()
|
||||
*
|
||||
* @brief: Close function for the fd dev
|
||||
*
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*/
|
||||
int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* _CAM_FD_CONTEXT_H_ */
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
||||
static int cam_fd_dev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_fd_dev *fd_dev = &g_fd_dev;
|
||||
|
|
@ -69,6 +69,11 @@ static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
mutex_lock(&fd_dev->lock);
|
||||
if (fd_dev->open_cnt == 0) {
|
||||
CAM_WARN(CAM_FD, "device already closed");
|
||||
mutex_unlock(&fd_dev->lock);
|
||||
return 0;
|
||||
}
|
||||
fd_dev->open_cnt--;
|
||||
CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
|
||||
mutex_unlock(&fd_dev->lock);
|
||||
|
|
@ -83,6 +88,19 @@ static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_fd_dev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_FD);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_FD, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_fd_dev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops cam_fd_subdev_internal_ops = {
|
||||
.open = cam_fd_dev_open,
|
||||
.close = cam_fd_dev_close,
|
||||
|
|
@ -98,6 +116,7 @@ static int cam_fd_dev_component_bind(struct device *dev,
|
|||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
g_fd_dev.sd.internal_ops = &cam_fd_subdev_internal_ops;
|
||||
g_fd_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
/* Initialize the v4l2 subdevice first. (create cam_node) */
|
||||
rc = cam_subdev_probe(&g_fd_dev.sd, pdev, CAM_FD_DEV_NAME,
|
||||
|
|
|
|||
|
|
@ -221,6 +221,12 @@ static int __cam_icp_handle_buf_done_in_ready(void *ctx,
|
|||
return cam_context_buf_done_from_hw(ctx, done, evt_id);
|
||||
}
|
||||
|
||||
static int __cam_icp_shutdown_dev(
|
||||
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
return cam_icp_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static struct cam_ctx_ops
|
||||
cam_icp_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
/* Uninit */
|
||||
|
|
@ -233,6 +239,7 @@ static struct cam_ctx_ops
|
|||
{
|
||||
.ioctl_ops = {
|
||||
.acquire_dev = __cam_icp_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -245,6 +252,7 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_icp_config_dev_in_ready,
|
||||
.flush_dev = __cam_icp_flush_dev_in_ready,
|
||||
.dump_dev = __cam_icp_dump_dev_in_ready,
|
||||
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = __cam_icp_handle_buf_done_in_ready,
|
||||
|
|
@ -258,16 +266,23 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_icp_config_dev_in_ready,
|
||||
.flush_dev = __cam_icp_flush_dev_in_ready,
|
||||
.dump_dev = __cam_icp_dump_dev_in_ready,
|
||||
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = __cam_icp_handle_buf_done_in_ready,
|
||||
.pagefault_ops = cam_icp_context_dump_active_request,
|
||||
},
|
||||
/* Flushed */
|
||||
{},
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||
},
|
||||
},
|
||||
/* Activated */
|
||||
{
|
||||
.ioctl_ops = {},
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_icp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
.pagefault_ops = cam_icp_context_dump_active_request,
|
||||
|
|
|
|||
|
|
@ -39,4 +39,12 @@ int cam_icp_context_init(struct cam_icp_context *ctx,
|
|||
*/
|
||||
int cam_icp_context_deinit(struct cam_icp_context *ctx);
|
||||
|
||||
/**
|
||||
* cam_icp_subdev_close_internal() - Close function for the icp dev
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*/
|
||||
int cam_icp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* _CAM_ICP_CONTEXT_H_ */
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
||||
int cam_icp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -108,7 +108,6 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
|||
mutex_lock(&g_icp_dev.icp_lock);
|
||||
if (g_icp_dev.open_cnt <= 0) {
|
||||
CAM_DBG(CAM_ICP, "ICP subdev is already closed");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
g_icp_dev.open_cnt--;
|
||||
|
|
@ -133,7 +132,20 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
|||
|
||||
end:
|
||||
mutex_unlock(&g_icp_dev.icp_lock);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_icp_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_ICP);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_ICP, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_icp_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
|
||||
|
|
@ -157,6 +169,7 @@ static int cam_icp_component_bind(struct device *dev,
|
|||
|
||||
g_icp_dev.sd.pdev = pdev;
|
||||
g_icp_dev.sd.internal_ops = &cam_icp_subdev_internal_ops;
|
||||
g_icp_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
rc = cam_subdev_probe(&g_icp_dev.sd, pdev, CAM_ICP_DEV_NAME,
|
||||
CAM_ICP_DEVICE_TYPE);
|
||||
if (rc) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
|
@ -1062,8 +1062,7 @@ static bool cam_icp_update_clk_free(struct cam_icp_hw_mgr *hw_mgr,
|
|||
|
||||
static bool cam_icp_debug_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
|
||||
{
|
||||
if (icp_hw_mgr.icp_debug_clk < ICP_CLK_TURBO_HZ &&
|
||||
icp_hw_mgr.icp_debug_clk &&
|
||||
if (icp_hw_mgr.icp_debug_clk &&
|
||||
icp_hw_mgr.icp_debug_clk != hw_mgr_clk_info->curr_clk) {
|
||||
hw_mgr_clk_info->base_clk = icp_hw_mgr.icp_debug_clk;
|
||||
hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_debug_clk;
|
||||
|
|
|
|||
|
|
@ -864,6 +864,18 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list(
|
|||
list_add_tail(&req->list, &ctx->free_req_list);
|
||||
req_isp->reapply = false;
|
||||
req_isp->cdm_reset_before_apply = false;
|
||||
req_isp->num_acked = 0;
|
||||
req_isp->num_deferred_acks = 0;
|
||||
req_isp->bubble_detected = false;
|
||||
/*
|
||||
* Only update the process_bubble and bubble_frame_cnt
|
||||
* when bubble is detected on this req, in case the other
|
||||
* request is processing bubble.
|
||||
*/
|
||||
if (req_isp->bubble_detected) {
|
||||
atomic_set(&ctx_isp->process_bubble, 0);
|
||||
ctx_isp->bubble_frame_cnt = 0;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Move active request %lld to free list(cnt = %d) [all fences done], ctx %u",
|
||||
|
|
@ -1863,7 +1875,6 @@ notify_only:
|
|||
if ((!req_isp->bubble_detected) &&
|
||||
(req->request_id > ctx_isp->reported_req_id)) {
|
||||
request_id = req->request_id;
|
||||
ctx_isp->reported_req_id = request_id;
|
||||
__cam_isp_ctx_update_event_record(ctx_isp,
|
||||
CAM_ISP_CTX_EVENT_EPOCH, req);
|
||||
break;
|
||||
|
|
@ -1873,6 +1884,9 @@ notify_only:
|
|||
if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE)
|
||||
request_id = 0;
|
||||
|
||||
if (request_id != 0)
|
||||
ctx_isp->reported_req_id = request_id;
|
||||
|
||||
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
|
||||
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
|
||||
|
||||
|
|
@ -2099,6 +2113,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
|
|||
ctx_isp->frame_id, ctx->ctx_id);
|
||||
}
|
||||
}
|
||||
atomic_set(&ctx_isp->process_bubble, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2334,6 +2349,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
|
|||
ctx_isp->frame_id, ctx->ctx_id);
|
||||
}
|
||||
}
|
||||
atomic_set(&ctx_isp->process_bubble, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -5837,6 +5853,12 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_isp_shutdown_dev(
|
||||
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
return cam_isp_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
/* top state machine */
|
||||
static struct cam_ctx_ops
|
||||
cam_isp_ctx_top_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
|
|
@ -5850,6 +5872,7 @@ static struct cam_ctx_ops
|
|||
{
|
||||
.ioctl_ops = {
|
||||
.acquire_dev = __cam_isp_ctx_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -5861,6 +5884,7 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
|
||||
.config_dev = __cam_isp_ctx_config_dev_in_acquired,
|
||||
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
|
||||
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.link = __cam_isp_ctx_link_in_acquired,
|
||||
|
|
@ -5880,6 +5904,7 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_isp_ctx_release_dev_in_top_state,
|
||||
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
|
||||
.release_hw = __cam_isp_ctx_release_hw_in_top_state,
|
||||
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.unlink = __cam_isp_ctx_unlink_in_ready,
|
||||
|
|
@ -5897,6 +5922,7 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_isp_ctx_release_dev_in_activated,
|
||||
.config_dev = __cam_isp_ctx_config_dev_in_flushed,
|
||||
.release_hw = __cam_isp_ctx_release_hw_in_activated,
|
||||
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.unlink = __cam_isp_ctx_unlink_in_ready,
|
||||
|
|
@ -5914,6 +5940,7 @@ static struct cam_ctx_ops
|
|||
.release_dev = __cam_isp_ctx_release_dev_in_activated,
|
||||
.config_dev = __cam_isp_ctx_config_dev_in_top_state,
|
||||
.release_hw = __cam_isp_ctx_release_hw_in_activated,
|
||||
.shutdown_dev = __cam_isp_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {
|
||||
.unlink = __cam_isp_ctx_unlink_in_activated,
|
||||
|
|
|
|||
|
|
@ -364,5 +364,16 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
|
|||
*/
|
||||
int cam_isp_context_deinit(struct cam_isp_context *ctx);
|
||||
|
||||
/**
|
||||
* cam_isp_subdev_close_internal()
|
||||
*
|
||||
* @brief: Close function for the isp dev
|
||||
*
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*
|
||||
*/
|
||||
int cam_isp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* __CAM_ISP_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ static int cam_isp_subdev_open(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_isp_subdev_close(struct v4l2_subdev *sd,
|
||||
int cam_isp_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -99,6 +99,18 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_ISP);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_ISP, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
return cam_isp_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops cam_isp_subdev_internal_ops = {
|
||||
.close = cam_isp_subdev_close,
|
||||
.open = cam_isp_subdev_open,
|
||||
|
|
@ -120,6 +132,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
|
|||
(const char **)&compat_str);
|
||||
|
||||
g_isp_dev.sd.internal_ops = &cam_isp_subdev_internal_ops;
|
||||
g_isp_dev.sd.close_seq_prior = CAM_SD_CLOSE_HIGH_PRIORITY;
|
||||
/* Initialize the v4l2 subdevice first. (create cam_node) */
|
||||
if (strnstr(compat_str, "ife", strlen(compat_str))) {
|
||||
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <media/cam_defs.h>
|
||||
|
|
@ -141,6 +141,14 @@ static int cam_isp_update_dual_config(
|
|||
}
|
||||
|
||||
hw_mgr_res = &res_list_isp_out[i];
|
||||
if (!hw_mgr_res) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid isp out resource i %d num_out_res %d",
|
||||
i, dual_config->num_ports);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1684,6 +1684,8 @@ static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
|
|||
CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
|
||||
}
|
||||
|
||||
res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4241,6 +4243,8 @@ int cam_ife_csid_stop(void *hw_priv,
|
|||
res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
|
||||
}
|
||||
|
||||
csid_hw->error_irq_count = 0;
|
||||
|
||||
CAM_DBG(CAM_ISP, "%s: Exit\n", __func__);
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
|
|
@ -203,6 +203,152 @@ static int cam_tfe_csid_get_format_ipp(
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void cam_tfe_csid_enable_path_for_init_frame_drop(
|
||||
struct cam_tfe_csid_hw *csid_hw,
|
||||
int res_id)
|
||||
{
|
||||
struct cam_tfe_csid_path_cfg *path_data;
|
||||
const struct cam_tfe_csid_pxl_reg_offset *pxl_reg = NULL;
|
||||
const struct cam_tfe_csid_rdi_reg_offset *rdi_reg = NULL;
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_isp_resource_node *res;
|
||||
uint32_t val;
|
||||
|
||||
if (!csid_hw) {
|
||||
CAM_WARN(CAM_ISP, "csid_hw cannot be NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
|
||||
if (res_id == CAM_TFE_CSID_PATH_RES_IPP) {
|
||||
res = &csid_hw->ipp_res;
|
||||
pxl_reg = csid_reg->ipp_reg;
|
||||
} else if (res_id >= CAM_TFE_CSID_PATH_RES_RDI_0 &&
|
||||
res_id <= CAM_TFE_CSID_PATH_RES_RDI_2) {
|
||||
res = &csid_hw->rdi_res[res_id];
|
||||
rdi_reg = csid_reg->rdi_reg[res_id];
|
||||
} else {
|
||||
CAM_ERR(CAM_ISP, "Invalid res_id");
|
||||
return;
|
||||
}
|
||||
|
||||
path_data = (struct cam_tfe_csid_path_cfg *)res->res_priv;
|
||||
|
||||
if (!path_data || !path_data->init_frame_drop)
|
||||
return;
|
||||
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)
|
||||
return;
|
||||
|
||||
path_data->res_sof_cnt++;
|
||||
if ((path_data->res_sof_cnt + 1) <
|
||||
path_data->res_sof_cnt) {
|
||||
CAM_WARN(CAM_ISP, "Res %d sof count overflow %d",
|
||||
res_id, path_data->res_sof_cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "CSID:%d res_id %d SOF cnt:%d init_frame_drop:%d",
|
||||
csid_hw->hw_intf->hw_idx, res_id, path_data->res_sof_cnt,
|
||||
path_data->init_frame_drop);
|
||||
|
||||
if ((path_data->res_sof_cnt ==
|
||||
path_data->init_frame_drop) &&
|
||||
pxl_reg) {
|
||||
CAM_DBG(CAM_ISP, "Enabling pixel IPP Path");
|
||||
if (path_data->sync_mode !=
|
||||
CAM_ISP_HW_SYNC_SLAVE) {
|
||||
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
val |= CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY;
|
||||
cam_io_w_mb(val,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_ctrl_addr);
|
||||
}
|
||||
|
||||
if (!(csid_hw->csid_debug &
|
||||
TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
|
||||
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_irq_mask_addr);
|
||||
val &= ~(TFE_CSID_PATH_INFO_INPUT_SOF);
|
||||
cam_io_w_mb(val,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
pxl_reg->csid_pxl_irq_mask_addr);
|
||||
}
|
||||
} else if ((path_data->res_sof_cnt ==
|
||||
path_data->init_frame_drop) && rdi_reg) {
|
||||
CAM_DBG(CAM_ISP, "Enabling RDI %d Path", res_id);
|
||||
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
rdi_reg->csid_rdi_ctrl_addr);
|
||||
if (!(csid_hw->csid_debug &
|
||||
TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
|
||||
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
rdi_reg->csid_rdi_irq_mask_addr);
|
||||
val &= ~(TFE_CSID_PATH_INFO_INPUT_SOF);
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
rdi_reg->csid_rdi_irq_mask_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool cam_tfe_csid_check_path_active(struct cam_tfe_csid_hw *csid_hw)
|
||||
{
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t i;
|
||||
uint32_t path_status = 1;
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
|
||||
/* check the IPP path status */
|
||||
if (csid_reg->cmn_reg->num_pix) {
|
||||
path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
csid_reg->ipp_reg->csid_pxl_status_addr);
|
||||
CAM_DBG(CAM_ISP, "CSID:%d IPP path status:%d",
|
||||
csid_hw->hw_intf->hw_idx, path_status);
|
||||
/* if status is 0 then it is active */
|
||||
if (!path_status)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Check the RDI path status */
|
||||
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
|
||||
path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
csid_reg->rdi_reg[i]->csid_rdi_status_addr);
|
||||
CAM_DBG(CAM_ISP, "CSID:%d RDI:%d path status:%d",
|
||||
csid_hw->hw_intf->hw_idx, i, path_status);
|
||||
/* if status is 0 then it is active */
|
||||
if (!path_status)
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
/* if status is 0 then path is active */
|
||||
return path_status ? false : true;
|
||||
}
|
||||
|
||||
static void cam_tfe_csid_reset_path_data(
|
||||
struct cam_tfe_csid_hw *csid_hw,
|
||||
struct cam_isp_resource_node *res)
|
||||
{
|
||||
struct cam_tfe_csid_path_cfg *path_data = NULL;
|
||||
|
||||
if (!csid_hw || !res) {
|
||||
CAM_WARN(CAM_ISP, "csid_hw or res cannot be NULL");
|
||||
return;
|
||||
}
|
||||
path_data = res->res_priv;
|
||||
|
||||
if (path_data) {
|
||||
path_data->init_frame_drop = 0;
|
||||
path_data->res_sof_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_cid_get(struct cam_tfe_csid_hw *csid_hw,
|
||||
int32_t vc, uint32_t dt, uint32_t *cid)
|
||||
{
|
||||
|
|
@ -249,6 +395,7 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
|
|||
{
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_tfe_csid_path_cfg *path_data = NULL;
|
||||
int rc = 0;
|
||||
uint32_t val = 0, i;
|
||||
uint32_t status;
|
||||
|
|
@ -348,6 +495,15 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
|
|||
csid_hw->error_irq_count = 0;
|
||||
csid_hw->prev_boot_timestamp = 0;
|
||||
|
||||
path_data = (struct cam_tfe_csid_path_cfg *)csid_hw->ipp_res.res_priv;
|
||||
path_data->res_sof_cnt = 0;
|
||||
|
||||
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
|
||||
path_data = (struct cam_tfe_csid_path_cfg *)
|
||||
csid_hw->rdi_res[i].res_priv;
|
||||
path_data->res_sof_cnt = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -675,6 +831,7 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
|
|||
path_data->height = reserve->in_port->height;
|
||||
path_data->start_line = reserve->in_port->line_start;
|
||||
path_data->end_line = reserve->in_port->line_end;
|
||||
path_data->usage_type = reserve->in_port->usage_type;
|
||||
|
||||
csid_hw->event_cb = reserve->event_cb;
|
||||
csid_hw->event_cb_priv = reserve->event_cb_prv;
|
||||
|
|
@ -868,7 +1025,8 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw *csid_hw)
|
|||
{
|
||||
int rc = 0;
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_tfe_csid_path_cfg *path_data = NULL;
|
||||
uint32_t i, val, clk_lvl;
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -949,6 +1107,16 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw *csid_hw)
|
|||
spin_unlock_irqrestore(&csid_hw->spin_lock, flags);
|
||||
cam_tasklet_start(csid_hw->tasklet);
|
||||
|
||||
path_data = (struct cam_tfe_csid_path_cfg *)csid_hw->ipp_res.res_priv;
|
||||
path_data->res_sof_cnt = 0;
|
||||
|
||||
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
|
||||
path_data = (struct cam_tfe_csid_path_cfg *)
|
||||
csid_hw->rdi_res[i].res_priv;
|
||||
path_data->res_sof_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
|
||||
disable_soc:
|
||||
|
|
@ -1512,11 +1680,14 @@ static int cam_tfe_csid_enable_rdi_path(
|
|||
{
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_tfe_csid_path_cfg *path_data;
|
||||
uint32_t id, val;
|
||||
bool path_active = false;
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
id = res->res_id;
|
||||
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
|
||||
|
||||
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
|
||||
res->res_id > CAM_TFE_CSID_PATH_RES_RDI_2 ||
|
||||
|
|
@ -1528,17 +1699,38 @@ static int cam_tfe_csid_enable_rdi_path(
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* resume at frame boundary */
|
||||
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
|
||||
/*Drop one frame extra on RDI for dual TFE use case */
|
||||
if (path_data->usage_type == CAM_ISP_TFE_IN_RES_USAGE_DUAL)
|
||||
path_data->init_frame_drop = 1;
|
||||
|
||||
/*resume at frame boundary */
|
||||
if (!path_data->init_frame_drop) {
|
||||
CAM_DBG(CAM_ISP, "Start RDI:%d path", id);
|
||||
/* resume at frame boundary */
|
||||
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
|
||||
} else {
|
||||
path_active = cam_tfe_csid_check_path_active(csid_hw);
|
||||
if (path_active)
|
||||
cam_io_w_mb(CAM_TFE_CSID_RESUME_AT_FRAME_BOUNDARY,
|
||||
soc_info->reg_map[0].mem_base +
|
||||
csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"CSID:%d %s RDI:%d path frame drop %d",
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
path_active ? "Starting" : "Not Starting", id,
|
||||
path_data->init_frame_drop);
|
||||
}
|
||||
|
||||
/* Enable the required RDI interrupts */
|
||||
val = TFE_CSID_PATH_INFO_RST_DONE | TFE_CSID_PATH_ERROR_FIFO_OVERFLOW |
|
||||
TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION |
|
||||
TFE_CSID_PATH_RDI_OVERFLOW_IRQ;
|
||||
|
||||
if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)
|
||||
if ((csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ) ||
|
||||
(path_data->init_frame_drop && !path_active))
|
||||
val |= TFE_CSID_PATH_INFO_INPUT_SOF;
|
||||
if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
|
||||
val |= TFE_CSID_PATH_INFO_INPUT_EOF;
|
||||
|
|
@ -1560,10 +1752,12 @@ static int cam_tfe_csid_disable_rdi_path(
|
|||
uint32_t id, val = 0;
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_tfe_csid_path_cfg *path_data;
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
id = res->res_id;
|
||||
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
|
||||
|
||||
if ((res->res_id > CAM_TFE_CSID_PATH_RES_RDI_2) ||
|
||||
(!csid_reg->rdi_reg[res->res_id])) {
|
||||
|
|
@ -1599,6 +1793,9 @@ static int cam_tfe_csid_disable_rdi_path(
|
|||
CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
|
||||
csid_hw->hw_intf->hw_idx, res->res_id);
|
||||
|
||||
path_data->init_frame_drop = 0;
|
||||
path_data->res_sof_cnt = 0;
|
||||
|
||||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
|
||||
|
||||
|
|
@ -1964,6 +2161,8 @@ static int cam_tfe_csid_release(void *hw_priv,
|
|||
|
||||
res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
|
||||
|
||||
cam_tfe_csid_reset_path_data(csid_hw, res);
|
||||
|
||||
end:
|
||||
mutex_unlock(&csid_hw->hw_info->hw_mutex);
|
||||
return rc;
|
||||
|
|
@ -3276,6 +3475,9 @@ handle_fatal_error:
|
|||
complete(&csid_hw->csid_rdin_complete[i]);
|
||||
}
|
||||
|
||||
if (irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF)
|
||||
cam_tfe_csid_enable_path_for_init_frame_drop(csid_hw, i);
|
||||
|
||||
if ((irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF) &&
|
||||
(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
|
||||
if (!csid_hw->sof_irq_triggered)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TFE_CSID_HW_H_
|
||||
|
|
@ -332,7 +332,12 @@ struct cam_tfe_csid_cid_data {
|
|||
* @sensor_fps Sensor fps
|
||||
* @sensor_hbi Sensor horizontal blanking interval
|
||||
* @sensor_vbi Sensor vertical blanking interval
|
||||
*
|
||||
* @usage_type: dual or single tfe information
|
||||
* @init_frame_drop init frame drop value. In dual ife case rdi need to drop one
|
||||
* more frame than pix.
|
||||
* @res_sof_cnt path resource sof count value. it used for initial
|
||||
* frame drop
|
||||
|
||||
*/
|
||||
struct cam_tfe_csid_path_cfg {
|
||||
uint32_t vc;
|
||||
|
|
@ -355,6 +360,9 @@ struct cam_tfe_csid_path_cfg {
|
|||
uint32_t sensor_fps;
|
||||
uint32_t sensor_hbi;
|
||||
uint32_t sensor_vbi;
|
||||
uint32_t usage_type;
|
||||
uint32_t init_frame_drop;
|
||||
uint32_t res_sof_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2954,9 +2954,8 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
|||
struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL;
|
||||
struct cam_vfe_bus_ver3_reg_offset_ubwc_client *ubwc_client = NULL;
|
||||
uint32_t *reg_val_pair;
|
||||
uint32_t i, j, k, size = 0;
|
||||
uint32_t i, j, size = 0;
|
||||
uint32_t frame_inc = 0, val;
|
||||
uint32_t loop_size = 0;
|
||||
|
||||
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
|
|
@ -3086,41 +3085,31 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
|||
wm_data->index, reg_val_pair[j-1]);
|
||||
}
|
||||
|
||||
if ((!bus_priv->common_data.is_lite && wm_data->index > 22) ||
|
||||
bus_priv->common_data.is_lite)
|
||||
loop_size = wm_data->irq_subsample_period + 1;
|
||||
else
|
||||
loop_size = 1;
|
||||
|
||||
/* WM Image address */
|
||||
for (k = 0; k < loop_size; k++) {
|
||||
if (wm_data->en_ubwc) {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
update_buf->wm_update->image_buf[i] +
|
||||
io_cfg->planes[i].meta_size +
|
||||
k * frame_inc);
|
||||
update_buf->wm_update->image_buf_offset[i] =
|
||||
io_cfg->planes[i].meta_size;
|
||||
} else if (wm_data->en_cfg & (0x3 << 16)) {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
(update_buf->wm_update->image_buf[i] +
|
||||
wm_data->offset + k * frame_inc));
|
||||
update_buf->wm_update->image_buf_offset[i] =
|
||||
wm_data->offset;
|
||||
} else {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
(update_buf->wm_update->image_buf[i] +
|
||||
k * frame_inc));
|
||||
update_buf->wm_update->image_buf_offset[i] = 0;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "WM:%d image address 0x%X",
|
||||
wm_data->index, reg_val_pair[j-1]);
|
||||
if (wm_data->en_ubwc) {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
update_buf->wm_update->image_buf[i] +
|
||||
io_cfg->planes[i].meta_size);
|
||||
update_buf->wm_update->image_buf_offset[i] =
|
||||
io_cfg->planes[i].meta_size;
|
||||
} else if (wm_data->en_cfg & (0x3 << 16)) {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
(update_buf->wm_update->image_buf[i] +
|
||||
wm_data->offset));
|
||||
update_buf->wm_update->image_buf_offset[i] =
|
||||
wm_data->offset;
|
||||
} else {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_addr,
|
||||
update_buf->wm_update->image_buf[i]);
|
||||
update_buf->wm_update->image_buf_offset[i] = 0;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "WM:%d image address 0x%X",
|
||||
wm_data->index, reg_val_pair[j-1]);
|
||||
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->frame_incr, frame_inc);
|
||||
CAM_DBG(CAM_ISP, "WM:%d frame_inc %d",
|
||||
|
|
|
|||
|
|
@ -135,6 +135,12 @@ static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_jpeg_shutdown_dev(
|
||||
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
return cam_jpeg_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
/* top state machine */
|
||||
static struct cam_ctx_ops
|
||||
cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
|
|
@ -148,6 +154,7 @@ static struct cam_ctx_ops
|
|||
{
|
||||
.ioctl_ops = {
|
||||
.acquire_dev = __cam_jpeg_ctx_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||
},
|
||||
.crm_ops = { },
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -160,11 +167,30 @@ static struct cam_ctx_ops
|
|||
.stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired,
|
||||
.flush_dev = __cam_jpeg_ctx_flush_dev_in_acquired,
|
||||
.dump_dev = __cam_jpeg_ctx_dump_dev_in_acquired,
|
||||
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||
},
|
||||
.crm_ops = { },
|
||||
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
|
||||
.pagefault_ops = cam_jpeg_context_dump_active_request,
|
||||
},
|
||||
/* Ready */
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||
},
|
||||
},
|
||||
/* Flushed */
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||
},
|
||||
},
|
||||
/* Activated */
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_jpeg_shutdown_dev,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
|
||||
|
|
|
|||
|
|
@ -64,4 +64,16 @@ int cam_jpeg_context_init(struct cam_jpeg_context *ctx,
|
|||
*/
|
||||
int cam_jpeg_context_deinit(struct cam_jpeg_context *ctx);
|
||||
|
||||
/**
|
||||
* cam_jpeg_subdev_close_internal()
|
||||
*
|
||||
* @brief: Close function for the jpeg dev
|
||||
*
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*
|
||||
*/
|
||||
int cam_jpeg_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* __CAM_JPEG_CONTEXT_H__ */
|
||||
|
|
|
|||
|
|
@ -56,13 +56,12 @@ static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
|
||||
int cam_jpeg_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_node *node = v4l2_get_subdevdata(sd);
|
||||
|
||||
|
||||
mutex_lock(&g_jpeg_dev.jpeg_mutex);
|
||||
if (g_jpeg_dev.open_cnt <= 0) {
|
||||
CAM_DBG(CAM_JPEG, "JPEG subdev is already closed");
|
||||
|
|
@ -86,6 +85,18 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_jpeg_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_JPEG);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_JPEG, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
return cam_jpeg_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops cam_jpeg_subdev_internal_ops = {
|
||||
.close = cam_jpeg_subdev_close,
|
||||
.open = cam_jpeg_subdev_open,
|
||||
|
|
@ -102,6 +113,7 @@ static int cam_jpeg_dev_component_bind(struct device *dev,
|
|||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
g_jpeg_dev.sd.internal_ops = &cam_jpeg_subdev_internal_ops;
|
||||
g_jpeg_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
rc = cam_subdev_probe(&g_jpeg_dev.sd, pdev, CAM_JPEG_DEV_NAME,
|
||||
CAM_JPEG_DEVICE_TYPE);
|
||||
if (rc) {
|
||||
|
|
|
|||
|
|
@ -172,6 +172,12 @@ static int __cam_lrme_ctx_handle_irq_in_activated(void *context,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_lrme_shutdown_dev(
|
||||
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
return cam_lrme_dev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
/* top state machine */
|
||||
static struct cam_ctx_ops
|
||||
cam_lrme_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
|
|
@ -185,6 +191,7 @@ static struct cam_ctx_ops
|
|||
{
|
||||
.ioctl_ops = {
|
||||
.acquire_dev = __cam_lrme_ctx_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -195,18 +202,25 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_lrme_ctx_config_dev_in_activated,
|
||||
.release_dev = __cam_lrme_ctx_release_dev_in_acquired,
|
||||
.start_dev = __cam_lrme_ctx_start_dev_in_acquired,
|
||||
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
/* Ready */
|
||||
{
|
||||
.ioctl_ops = {},
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
/* Flushed */
|
||||
{},
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||
},
|
||||
},
|
||||
/* Activate */
|
||||
{
|
||||
.ioctl_ops = {
|
||||
|
|
@ -215,6 +229,7 @@ static struct cam_ctx_ops
|
|||
.stop_dev = __cam_lrme_ctx_stop_dev_in_activated,
|
||||
.flush_dev = __cam_lrme_ctx_flush_dev_in_activated,
|
||||
.dump_dev = __cam_lrme_ctx_dump_dev_in_activated,
|
||||
.shutdown_dev = __cam_lrme_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = __cam_lrme_ctx_handle_irq_in_activated,
|
||||
|
|
|
|||
|
|
@ -30,4 +30,16 @@ int cam_lrme_context_init(struct cam_lrme_context *lrme_ctx,
|
|||
uint32_t index);
|
||||
int cam_lrme_context_deinit(struct cam_lrme_context *lrme_ctx);
|
||||
|
||||
/**
|
||||
* cam_lrme_dev_close_internal()
|
||||
*
|
||||
* @brief: Close function for the jpeg dev
|
||||
*
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*
|
||||
*/
|
||||
int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* _CAM_LRME_CONTEXT_H_ */
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
|
||||
int cam_lrme_dev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -106,6 +106,18 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_lrme_dev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_LRME);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_LRME, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
return cam_lrme_dev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
|
||||
.open = cam_lrme_dev_open,
|
||||
.close = cam_lrme_dev_close,
|
||||
|
|
@ -126,6 +138,7 @@ static int cam_lrme_component_bind(struct device *dev,
|
|||
return -ENOMEM;
|
||||
}
|
||||
g_lrme_dev->sd.internal_ops = &cam_lrme_subdev_internal_ops;
|
||||
g_lrme_dev->sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
mutex_init(&g_lrme_dev->lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -195,6 +195,12 @@ static int __cam_ope_handle_buf_done_in_ready(void *ctx,
|
|||
return cam_context_buf_done_from_hw(ctx, done, evt_id);
|
||||
}
|
||||
|
||||
static int __cam_ope_shutdown_dev(
|
||||
struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
return cam_ope_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static struct cam_ctx_ops
|
||||
cam_ope_ctx_state_machine[CAM_CTX_STATE_MAX] = {
|
||||
/* Uninit */
|
||||
|
|
@ -207,6 +213,7 @@ static struct cam_ctx_ops
|
|||
{
|
||||
.ioctl_ops = {
|
||||
.acquire_dev = __cam_ope_acquire_dev_in_available,
|
||||
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
|
|
@ -219,6 +226,7 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_ope_config_dev_in_ready,
|
||||
.flush_dev = __cam_ope_flush_dev_in_ready,
|
||||
.dump_dev = __cam_ope_dump_dev_in_ready,
|
||||
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = __cam_ope_handle_buf_done_in_ready,
|
||||
|
|
@ -232,14 +240,23 @@ static struct cam_ctx_ops
|
|||
.config_dev = __cam_ope_config_dev_in_ready,
|
||||
.flush_dev = __cam_ope_flush_dev_in_ready,
|
||||
.dump_dev = __cam_ope_dump_dev_in_ready,
|
||||
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = __cam_ope_handle_buf_done_in_ready,
|
||||
.pagefault_ops = cam_ope_context_dump_active_request,
|
||||
},
|
||||
/* Flushed */
|
||||
{
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||
},
|
||||
},
|
||||
/* Activated */
|
||||
{
|
||||
.ioctl_ops = {},
|
||||
.ioctl_ops = {
|
||||
.shutdown_dev = __cam_ope_shutdown_dev,
|
||||
},
|
||||
.crm_ops = {},
|
||||
.irq_ops = NULL,
|
||||
.pagefault_ops = cam_ope_context_dump_active_request,
|
||||
|
|
|
|||
|
|
@ -41,4 +41,12 @@ int cam_ope_context_init(struct cam_ope_context *ctx,
|
|||
*/
|
||||
int cam_ope_context_deinit(struct cam_ope_context *ctx);
|
||||
|
||||
/**
|
||||
* cam_ope_subdev_close_internal() - Close function for the icp dev
|
||||
* @sd: Pointer to struct v4l2_subdev
|
||||
* @fh: Pointer to struct v4l2_subdev_fh
|
||||
*/
|
||||
int cam_ope_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh);
|
||||
|
||||
#endif /* _CAM_OPE_CONTEXT_H_ */
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ope_subdev_close(struct v4l2_subdev *sd,
|
||||
int cam_ope_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -134,6 +134,19 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ope_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_OPE);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_OPE, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_ope_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
const struct v4l2_subdev_internal_ops cam_ope_subdev_internal_ops = {
|
||||
.open = cam_ope_subdev_open,
|
||||
.close = cam_ope_subdev_close,
|
||||
|
|
@ -156,6 +169,7 @@ static int cam_ope_subdev_component_bind(struct device *dev,
|
|||
|
||||
g_ope_dev.sd.pdev = pdev;
|
||||
g_ope_dev.sd.internal_ops = &cam_ope_subdev_internal_ops;
|
||||
g_ope_dev.sd.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
rc = cam_subdev_probe(&g_ope_dev.sd, pdev, OPE_DEV_NAME,
|
||||
CAM_OPE_DEVICE_TYPE);
|
||||
if (rc) {
|
||||
|
|
|
|||
|
|
@ -1339,7 +1339,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
|
|||
static int __cam_req_mgr_check_sync_req_is_ready(
|
||||
struct cam_req_mgr_core_link *link,
|
||||
struct cam_req_mgr_core_link *sync_link,
|
||||
struct cam_req_mgr_slot *slot)
|
||||
struct cam_req_mgr_slot *slot,
|
||||
uint32_t trigger)
|
||||
{
|
||||
struct cam_req_mgr_slot *sync_rd_slot = NULL;
|
||||
int64_t req_id = 0, sync_req_id = 0;
|
||||
|
|
@ -1513,7 +1514,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
|
|||
*/
|
||||
master_slave_diff = sync_frame_duration;
|
||||
do_div(master_slave_diff, 5);
|
||||
if ((sync_link->sof_timestamp > 0) &&
|
||||
if ((trigger == CAM_TRIGGER_POINT_SOF) &&
|
||||
(sync_link->sof_timestamp > 0) &&
|
||||
(sof_timestamp_delta < master_slave_diff) &&
|
||||
(sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) {
|
||||
|
||||
|
|
@ -1574,7 +1576,8 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
|
|||
}
|
||||
if (link->max_delay == link->sync_link[i]->max_delay) {
|
||||
rc = __cam_req_mgr_check_sync_req_is_ready(
|
||||
link, link->sync_link[i], slot);
|
||||
link, link->sync_link[i],
|
||||
slot, trigger);
|
||||
if (rc < 0) {
|
||||
CAM_DBG(CAM_CRM, "link %x not ready",
|
||||
link->link_hdl);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/cam_req_mgr.h>
|
||||
#include <media/cam_defs.h>
|
||||
#include <linux/list_sort.h>
|
||||
|
||||
#include "cam_req_mgr_dev.h"
|
||||
#include "cam_req_mgr_util.h"
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
|
||||
static struct cam_req_mgr_device g_dev;
|
||||
struct kmem_cache *g_cam_req_mgr_timer_cachep;
|
||||
static struct list_head cam_req_mgr_ordered_sd_list;
|
||||
|
||||
static struct device_attribute camera_debug_sysfs_attr =
|
||||
__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);
|
||||
|
|
@ -122,6 +124,7 @@ static int cam_req_mgr_open(struct file *filep)
|
|||
spin_unlock_bh(&g_dev.cam_eventq_lock);
|
||||
|
||||
g_dev.open_cnt++;
|
||||
g_dev.read_active_dev_id_hdls = 0;
|
||||
rc = cam_mem_mgr_init();
|
||||
if (rc) {
|
||||
g_dev.open_cnt--;
|
||||
|
|
@ -158,6 +161,7 @@ static unsigned int cam_req_mgr_poll(struct file *f,
|
|||
static int cam_req_mgr_close(struct file *filep)
|
||||
{
|
||||
struct v4l2_subdev *sd;
|
||||
struct cam_subdev *csd;
|
||||
struct v4l2_fh *vfh = filep->private_data;
|
||||
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
|
||||
|
||||
|
|
@ -172,18 +176,23 @@ static int cam_req_mgr_close(struct file *filep)
|
|||
}
|
||||
|
||||
cam_req_mgr_handle_core_shutdown();
|
||||
g_dev.shutdown_state = true;
|
||||
|
||||
list_for_each_entry(sd, &g_dev.v4l2_dev->subdevs, list) {
|
||||
list_for_each_entry(csd, &cam_req_mgr_ordered_sd_list, list) {
|
||||
sd = &csd->sd;
|
||||
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
|
||||
continue;
|
||||
if (sd->internal_ops && sd->internal_ops->close) {
|
||||
if (sd->internal_ops) {
|
||||
CAM_DBG(CAM_CRM, "Invoke subdev close for device %s",
|
||||
sd->name);
|
||||
sd->internal_ops->close(sd, subdev_fh);
|
||||
v4l2_subdev_call(sd, core, ioctl,
|
||||
CAM_SD_SHUTDOWN, subdev_fh);
|
||||
}
|
||||
}
|
||||
|
||||
g_dev.open_cnt--;
|
||||
g_dev.shutdown_state = false;
|
||||
g_dev.read_active_dev_id_hdls = 0;
|
||||
v4l2_fh_release(filep);
|
||||
|
||||
spin_lock_bh(&g_dev.cam_eventq_lock);
|
||||
|
|
@ -659,6 +668,51 @@ void cam_subdev_notify_message(u32 subdev_type,
|
|||
}
|
||||
EXPORT_SYMBOL(cam_subdev_notify_message);
|
||||
|
||||
|
||||
static int cam_req_mgr_ordered_list_cmp(void *priv,
|
||||
struct list_head *head_1, struct list_head *head_2)
|
||||
{
|
||||
struct cam_subdev *entry_1 =
|
||||
list_entry(head_1, struct cam_subdev, list);
|
||||
struct cam_subdev *entry_2 =
|
||||
list_entry(head_2, struct cam_subdev, list);
|
||||
int ret = -1;
|
||||
|
||||
if (entry_1->close_seq_prior > entry_2->close_seq_prior)
|
||||
return 1;
|
||||
else if (entry_1->close_seq_prior < entry_2->close_seq_prior)
|
||||
return ret;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cam_req_mgr_is_open(uint64_t dev_id)
|
||||
{
|
||||
bool crm_status;
|
||||
bool dev_id_status;
|
||||
|
||||
mutex_lock(&g_dev.cam_lock);
|
||||
crm_status = g_dev.open_cnt ? true : false;
|
||||
|
||||
if (!g_dev.read_active_dev_id_hdls) {
|
||||
g_dev.active_dev_id_hdls = cam_get_dev_handle_status();
|
||||
g_dev.read_active_dev_id_hdls++;
|
||||
}
|
||||
|
||||
dev_id_status = (g_dev.active_dev_id_hdls & dev_id) ? true : false;
|
||||
crm_status &= dev_id_status;
|
||||
mutex_unlock(&g_dev.cam_lock);
|
||||
|
||||
return crm_status;
|
||||
}
|
||||
EXPORT_SYMBOL(cam_req_mgr_is_open);
|
||||
|
||||
bool cam_req_mgr_is_shutdown(void)
|
||||
{
|
||||
return g_dev.shutdown_state;
|
||||
}
|
||||
EXPORT_SYMBOL(cam_req_mgr_is_shutdown);
|
||||
|
||||
int cam_register_subdev(struct cam_subdev *csd)
|
||||
{
|
||||
struct v4l2_subdev *sd;
|
||||
|
|
@ -687,6 +741,10 @@ int cam_register_subdev(struct cam_subdev *csd)
|
|||
sd->entity.pads = NULL;
|
||||
sd->entity.function = csd->ent_function;
|
||||
|
||||
list_add(&csd->list, &cam_req_mgr_ordered_sd_list);
|
||||
list_sort(NULL, &cam_req_mgr_ordered_sd_list,
|
||||
cam_req_mgr_ordered_list_cmp);
|
||||
|
||||
rc = v4l2_device_register_subdev(g_dev.v4l2_dev, sd);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CRM, "register subdev failed");
|
||||
|
|
@ -747,6 +805,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
|
|||
goto video_setup_fail;
|
||||
|
||||
g_dev.open_cnt = 0;
|
||||
g_dev.shutdown_state = false;
|
||||
mutex_init(&g_dev.cam_lock);
|
||||
spin_lock_init(&g_dev.cam_eventq_lock);
|
||||
mutex_init(&g_dev.dev_lock);
|
||||
|
|
@ -764,6 +823,7 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
|
|||
}
|
||||
|
||||
g_dev.state = true;
|
||||
INIT_LIST_HEAD(&cam_req_mgr_ordered_sd_list);
|
||||
|
||||
if (g_cam_req_mgr_timer_cachep == NULL) {
|
||||
g_cam_req_mgr_timer_cachep = kmem_cache_create("crm_timer",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
* @cam_lock: per file handle lock
|
||||
* @cam_eventq: event queue
|
||||
* @cam_eventq_lock: lock for event queue
|
||||
* @shutdown_state: shutdown state
|
||||
* @active_dev_id_hdls: active dev id handles
|
||||
* @read_active_dev_id_hdls: read active_dev_id_hdls status
|
||||
*/
|
||||
struct cam_req_mgr_device {
|
||||
struct video_device *video;
|
||||
|
|
@ -30,6 +33,9 @@ struct cam_req_mgr_device {
|
|||
struct mutex cam_lock;
|
||||
struct v4l2_fh *cam_eventq;
|
||||
spinlock_t cam_eventq_lock;
|
||||
bool shutdown_state;
|
||||
uint64_t active_dev_id_hdls;
|
||||
int read_active_dev_id_hdls;
|
||||
};
|
||||
|
||||
#define CAM_REQ_MGR_GET_PAYLOAD_PTR(ev, type) \
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <media/cam_req_mgr.h>
|
||||
#include "cam_req_mgr_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_context.h"
|
||||
|
||||
static struct cam_req_mgr_util_hdl_tbl *hdl_tbl;
|
||||
static DEFINE_SPINLOCK(hdl_tbl_lock);
|
||||
|
|
@ -209,6 +210,36 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
|
|||
return handle;
|
||||
}
|
||||
|
||||
int32_t cam_get_dev_handle_info(uint64_t handle,
|
||||
struct cam_context **ctx, int32_t dev_index)
|
||||
{
|
||||
int32_t idx;
|
||||
struct v4l2_subdev *sd = (struct v4l2_subdev *)handle;
|
||||
|
||||
for (idx = dev_index + 1; idx < CAM_REQ_MGR_MAX_HANDLES_V2; idx++) {
|
||||
if (hdl_tbl->hdl[idx].state == HDL_ACTIVE) {
|
||||
*ctx = (struct cam_context *)cam_get_device_priv(
|
||||
hdl_tbl->hdl[idx].hdl_value);
|
||||
if ((*ctx) && !strcmp(sd->name, (*ctx)->dev_name))
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
*ctx = NULL;
|
||||
return CAM_REQ_MGR_MAX_HANDLES_V2;
|
||||
}
|
||||
|
||||
uint64_t cam_get_dev_handle_status(void)
|
||||
{
|
||||
int32_t idx;
|
||||
uint64_t active_dev_hdls = 0;
|
||||
|
||||
for (idx = 0; idx < CAM_REQ_MGR_MAX_HANDLES_V2; idx++)
|
||||
if (hdl_tbl->hdl[idx].state == HDL_ACTIVE)
|
||||
active_dev_hdls |= hdl_tbl->hdl[idx].dev_id;
|
||||
|
||||
return active_dev_hdls;
|
||||
}
|
||||
|
||||
void *cam_get_device_priv(int32_t dev_hdl)
|
||||
{
|
||||
int idx;
|
||||
|
|
|
|||
|
|
@ -166,4 +166,11 @@ int32_t cam_req_mgr_util_deinit(void);
|
|||
*/
|
||||
int32_t cam_req_mgr_util_free_hdls(void);
|
||||
|
||||
/**
|
||||
* cam_get_dev_handle_status() - get dev handles status
|
||||
*
|
||||
* Returns dev handle status
|
||||
*/
|
||||
uint64_t cam_get_dev_handle_status(void);
|
||||
|
||||
#endif /* _CAM_REQ_MGR_UTIL_API_H_ */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@ enum cam_subdev_message_type_t {
|
|||
CAM_SUBDEV_MESSAGE_CLOCK_UPDATE
|
||||
};
|
||||
|
||||
/* Enum for close sequence priority */
|
||||
enum cam_subdev_close_seq_priority {
|
||||
CAM_SD_CLOSE_HIGH_PRIORITY,
|
||||
CAM_SD_CLOSE_MEDIUM_PRIORITY,
|
||||
CAM_SD_CLOSE_LOW_PRIORITY
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_subdev - describes a camera sub-device
|
||||
*
|
||||
|
|
@ -39,6 +46,8 @@ enum cam_subdev_message_type_t {
|
|||
* @ent_function: Media entity function type. Can be:
|
||||
* %CAM_IFE_DEVICE_TYPE - identifies as IFE device.
|
||||
* %CAM_ICP_DEVICE_TYPE - identifies as ICP device.
|
||||
* @list: list pointer
|
||||
* @close_seq_prior: cam_subdev_close_seq_priority type
|
||||
*
|
||||
* Each instance of a subdev driver should create this struct, either
|
||||
* stand-alone or embedded in a larger struct. This structure should be
|
||||
|
|
@ -58,6 +67,8 @@ struct cam_subdev {
|
|||
struct v4l2_subdev *sd,
|
||||
enum cam_subdev_message_type_t msg_type,
|
||||
uint32_t data);
|
||||
struct list_head list;
|
||||
enum cam_subdev_close_seq_priority close_seq_prior;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -119,4 +130,20 @@ int cam_register_subdev(struct cam_subdev *sd);
|
|||
*/
|
||||
int cam_unregister_subdev(struct cam_subdev *sd);
|
||||
|
||||
/**
|
||||
* cam_req_mgr_is_open()
|
||||
*
|
||||
* @brief: This common utility function returns the crm active status
|
||||
*
|
||||
* @dev_id: device id type
|
||||
*/
|
||||
bool cam_req_mgr_is_open(uint64_t dev_id);
|
||||
|
||||
/**
|
||||
* cam_req_mgr_is_shutdown()
|
||||
*
|
||||
* @brief: This common utility function returns the shutdown state
|
||||
*/
|
||||
bool cam_req_mgr_is_shutdown(void);
|
||||
|
||||
#endif /* _CAM_SUBDEV_H_ */
|
||||
|
|
|
|||
|
|
@ -10,6 +10,38 @@
|
|||
#include "cam_trace.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_actuator_ctrl_t *a_ctrl =
|
||||
v4l2_get_subdevdata(sd);
|
||||
|
||||
if (!a_ctrl) {
|
||||
CAM_ERR(CAM_ACTUATOR, "a_ctrl ptr is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&(a_ctrl->actuator_mutex));
|
||||
cam_actuator_shutdown(a_ctrl);
|
||||
mutex_unlock(&(a_ctrl->actuator_mutex));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_actuator_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_ACTUATOR);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_ACTUATOR,
|
||||
"CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_actuator_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
|
|
@ -24,6 +56,14 @@ static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
CAM_ERR(CAM_ACTUATOR,
|
||||
"Failed for driver_cmd: %d", rc);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = cam_actuator_subdev_close_internal(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ACTUATOR, "Invalid ioctl cmd: %u", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
|
|
@ -77,24 +117,6 @@ static long cam_actuator_init_subdev_do_ioctl(struct v4l2_subdev *sd,
|
|||
}
|
||||
#endif
|
||||
|
||||
static int cam_actuator_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_actuator_ctrl_t *a_ctrl =
|
||||
v4l2_get_subdevdata(sd);
|
||||
|
||||
if (!a_ctrl) {
|
||||
CAM_ERR(CAM_ACTUATOR, "a_ctrl ptr is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&(a_ctrl->actuator_mutex));
|
||||
cam_actuator_shutdown(a_ctrl);
|
||||
mutex_unlock(&(a_ctrl->actuator_mutex));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct v4l2_subdev_core_ops cam_actuator_subdev_core_ops = {
|
||||
.ioctl = cam_actuator_subdev_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
@ -127,10 +149,13 @@ static int cam_actuator_init_subdev(struct cam_actuator_ctrl_t *a_ctrl)
|
|||
a_ctrl->v4l2_dev_str.ent_function =
|
||||
CAM_ACTUATOR_DEVICE_TYPE;
|
||||
a_ctrl->v4l2_dev_str.token = a_ctrl;
|
||||
a_ctrl->v4l2_dev_str.close_seq_prior =
|
||||
CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(a_ctrl->v4l2_dev_str));
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR, "Fail with cam_register_subdev rc: %d", rc);
|
||||
CAM_ERR(CAM_ACTUATOR,
|
||||
"Fail with cam_register_subdev rc: %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -985,6 +985,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]);
|
||||
cci_dev->is_burst_read[master] = true;
|
||||
reinit_completion(&cci_dev->cci_master_info[master].report_q[queue]);
|
||||
|
||||
soc_info = &cci_dev->soc_info;
|
||||
|
|
@ -1256,6 +1257,7 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]);
|
||||
cci_dev->is_burst_read[master] = false;
|
||||
reinit_completion(&cci_dev->cci_master_info[master].report_q[queue]);
|
||||
|
||||
soc_info = &cci_dev->soc_info;
|
||||
|
|
@ -1622,7 +1624,7 @@ static int32_t cam_cci_read_bytes_v_1_2(struct v4l2_subdev *sd,
|
|||
else
|
||||
read_cfg->num_byte = read_bytes;
|
||||
|
||||
cci_dev->is_burst_read = false;
|
||||
cci_dev->is_burst_read[master] = false;
|
||||
rc = cam_cci_read(sd, c_ctrl);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_CCI, "failed to read rc:%d", rc);
|
||||
|
|
@ -1639,7 +1641,6 @@ static int32_t cam_cci_read_bytes_v_1_2(struct v4l2_subdev *sd,
|
|||
} while (read_bytes);
|
||||
|
||||
ERROR:
|
||||
cci_dev->is_burst_read = false;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1704,10 +1705,8 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
|
|||
read_cfg->num_byte = read_bytes;
|
||||
|
||||
if (read_cfg->num_byte >= CCI_READ_MAX) {
|
||||
cci_dev->is_burst_read = true;
|
||||
rc = cam_cci_burst_read(sd, c_ctrl);
|
||||
} else {
|
||||
cci_dev->is_burst_read = false;
|
||||
rc = cam_cci_read(sd, c_ctrl);
|
||||
}
|
||||
if (rc) {
|
||||
|
|
@ -1726,7 +1725,6 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
|
|||
} while (read_bytes);
|
||||
|
||||
ERROR:
|
||||
cci_dev->is_burst_read = false;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_cci_dev.h"
|
||||
|
|
@ -112,7 +112,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
|
|||
(!rd_done_th_assert)) {
|
||||
cci_dev->cci_master_info[MASTER_0].status = 0;
|
||||
rd_done_th_assert = true;
|
||||
if (cci_dev->is_burst_read)
|
||||
if (cci_dev->is_burst_read[MASTER_0])
|
||||
complete(
|
||||
&cci_dev->cci_master_info[MASTER_0].th_complete);
|
||||
complete(&cci_dev->cci_master_info[MASTER_0].rd_done);
|
||||
|
|
@ -168,7 +168,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data)
|
|||
(!rd_done_th_assert)) {
|
||||
cci_dev->cci_master_info[MASTER_1].status = 0;
|
||||
rd_done_th_assert = true;
|
||||
if (cci_dev->is_burst_read)
|
||||
if (cci_dev->is_burst_read[MASTER_1])
|
||||
complete(
|
||||
&cci_dev->cci_master_info[MASTER_1].th_complete);
|
||||
complete(&cci_dev->cci_master_info[MASTER_1].rd_done);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CCI_DEV_H_
|
||||
|
|
@ -50,8 +50,8 @@
|
|||
#define CCI_READ_MAX 256
|
||||
#define CCI_READ_MAX_V_1_2 0xE
|
||||
#define CCI_I2C_READ_MAX_RETRIES 3
|
||||
#define CCI_I2C_MAX_READ 10240
|
||||
#define CCI_I2C_MAX_WRITE 10240
|
||||
#define CCI_I2C_MAX_READ 20480
|
||||
#define CCI_I2C_MAX_WRITE 20480
|
||||
#define CCI_I2C_MAX_BYTE_COUNT 65535
|
||||
|
||||
#define CAMX_CCI_DEV_NAME "cam-cci-driver"
|
||||
|
|
@ -224,7 +224,7 @@ struct cci_device {
|
|||
uint32_t cpas_handle;
|
||||
uint32_t irq_status1;
|
||||
spinlock_t lock_status;
|
||||
bool is_burst_read;
|
||||
bool is_burst_read[MASTER_MAX];
|
||||
uint32_t irqs_disabled;
|
||||
struct mutex init_mutex;
|
||||
uint64_t dump_en;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_cci_dev.h"
|
||||
|
|
@ -76,6 +76,7 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
|
|||
|
||||
cci_dev->cci_master_info[master].status = 0;
|
||||
cci_dev->cci_master_info[master].is_initilized = true;
|
||||
cci_dev->is_burst_read[master] = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -77,29 +77,7 @@ static void cam_csiphy_debug_unregister(void)
|
|||
root_dentry = NULL;
|
||||
}
|
||||
|
||||
static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
|
||||
int rc = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_csiphy_core_cfg(csiphy_dev, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CSIPHY,
|
||||
"Failed in configuring the device: %d", rc);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CSIPHY, "Wrong ioctl : %d", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
|
||||
static int cam_csiphy_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct csiphy_device *csiphy_dev =
|
||||
|
|
@ -117,6 +95,49 @@ static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_csiphy_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_CSIPHY);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_CSIPHY, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_csiphy_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
|
||||
int rc = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_csiphy_core_cfg(csiphy_dev, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_CSIPHY,
|
||||
"Failed in configuring the device: %d", rc);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = cam_csiphy_subdev_close_internal(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CSIPHY, "Wrong ioctl : %d", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long cam_csiphy_subdev_compat_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
|
@ -236,6 +257,8 @@ static int cam_csiphy_component_bind(struct device *dev,
|
|||
cam_csiphy_subdev_handle_message;
|
||||
new_csiphy_dev->v4l2_dev_str.token =
|
||||
new_csiphy_dev;
|
||||
new_csiphy_dev->v4l2_dev_str.close_seq_prior =
|
||||
CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(new_csiphy_dev->v4l2_dev_str));
|
||||
if (rc < 0) {
|
||||
|
|
|
|||
|
|
@ -10,28 +10,7 @@
|
|||
#include "cam_debug_util.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_eeprom_driver_cmd(e_ctrl, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_EEPROM,
|
||||
"Failed in Driver cmd: %d", rc);
|
||||
break;
|
||||
default:
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
|
||||
static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_eeprom_ctrl_t *e_ctrl =
|
||||
|
|
@ -49,6 +28,48 @@ static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_eeprom_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_EEPROM);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_EEPROM, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_eeprom_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_eeprom_driver_cmd(e_ctrl, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_EEPROM,
|
||||
"Failed in Driver cmd: %d", rc);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = cam_eeprom_subdev_close_internal(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t cam_eeprom_update_i2c_info(struct cam_eeprom_ctrl_t *e_ctrl,
|
||||
struct cam_eeprom_i2c_info_t *i2c_info)
|
||||
{
|
||||
|
|
@ -147,6 +168,7 @@ static int cam_eeprom_init_subdev(struct cam_eeprom_ctrl_t *e_ctrl)
|
|||
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
|
||||
e_ctrl->v4l2_dev_str.ent_function = CAM_EEPROM_DEVICE_TYPE;
|
||||
e_ctrl->v4l2_dev_str.token = e_ctrl;
|
||||
e_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(e_ctrl->v4l2_dev_str));
|
||||
if (rc)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "cam_res_mgr_api.h"
|
||||
#include "cam_common_util.h"
|
||||
#include "cam_packet_util.h"
|
||||
#include <asm/div64.h>
|
||||
|
||||
static uint default_on_timer = 2;
|
||||
module_param(default_on_timer, uint, 0644);
|
||||
|
|
@ -1558,8 +1559,7 @@ int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
|
|||
add_req.trigger_eof = true;
|
||||
/* Active time for the preflash */
|
||||
flash_data->flash_active_time_ms =
|
||||
(flash_operation_info->time_on_duration_ns)
|
||||
/ 1000000;
|
||||
do_div(flash_operation_info->time_on_duration_ns, 1000000);
|
||||
CAM_DBG(CAM_FLASH,
|
||||
"PRECISE FLASH: active_time: %llu",
|
||||
flash_data->flash_active_time_ms);
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
struct cam_flash_query_cap_info flash_cap = {0};
|
||||
|
||||
CAM_DBG(CAM_FLASH, "CAM_QUERY_CAP");
|
||||
flash_cap.slot_info = fctrl->soc_info.index;
|
||||
flash_cap.slot_info = fctrl->soc_info.index;
|
||||
flash_cap.flash_type = soc_private->flash_type;
|
||||
for (i = 0; i < fctrl->flash_num_sources; i++) {
|
||||
flash_cap.max_current_flash[i] =
|
||||
soc_private->flash_max_current[i];
|
||||
|
|
@ -236,6 +237,37 @@ static const struct of_device_id cam_flash_dt_match[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static int cam_flash_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_flash_ctrl *fctrl =
|
||||
v4l2_get_subdevdata(sd);
|
||||
|
||||
if (!fctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&fctrl->flash_mutex);
|
||||
cam_flash_shutdown(fctrl);
|
||||
mutex_unlock(&fctrl->flash_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_FLASH);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_FLASH, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_flash_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
|
|
@ -257,6 +289,14 @@ static long cam_flash_subdev_ioctl(struct v4l2_subdev *sd,
|
|||
"Failed in driver cmd: %d", rc);
|
||||
break;
|
||||
}
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = cam_flash_subdev_close_internal(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_FLASH, "Invalid ioctl cmd type");
|
||||
rc = -ENOIOCTLCMD;
|
||||
|
|
@ -328,24 +368,6 @@ static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_flash_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_flash_ctrl *fctrl =
|
||||
v4l2_get_subdevdata(sd);
|
||||
|
||||
if (!fctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Flash ctrl ptr is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&fctrl->flash_mutex);
|
||||
cam_flash_shutdown(fctrl);
|
||||
mutex_unlock(&fctrl->flash_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct v4l2_subdev_core_ops cam_flash_subdev_core_ops = {
|
||||
.ioctl = cam_flash_subdev_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
@ -375,6 +397,7 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl)
|
|||
V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
fctrl->v4l2_dev_str.ent_function = CAM_FLASH_DEVICE_TYPE;
|
||||
fctrl->v4l2_dev_str.token = fctrl;
|
||||
fctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(fctrl->v4l2_dev_str));
|
||||
if (rc)
|
||||
|
|
@ -390,6 +413,7 @@ static int cam_flash_component_bind(struct device *dev,
|
|||
struct cam_flash_ctrl *fctrl = NULL;
|
||||
struct device_node *of_parent = NULL;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
|
||||
CAM_DBG(CAM_FLASH, "Binding flash component");
|
||||
if (!pdev->dev.of_node) {
|
||||
|
|
@ -445,6 +469,19 @@ static int cam_flash_component_bind(struct device *dev,
|
|||
fctrl->io_master_info.cci_client->cci_device = fctrl->cci_num;
|
||||
CAM_DBG(CAM_FLASH, "cci-index %d", fctrl->cci_num, rc);
|
||||
|
||||
soc_info = &fctrl->soc_info;
|
||||
rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
|
||||
&fctrl->power_info.gpio_num_info);
|
||||
if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) {
|
||||
CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = cam_sensor_util_regulator_powerup(soc_info);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_FLASH, "regulator power up for flash failed %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
fctrl->i2c_data.per_frame =
|
||||
kzalloc(sizeof(struct i2c_settings_array) *
|
||||
MAX_PER_FRAME_ARRAY, GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_FLASH_DEV_H_
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#include "cam_subdev.h"
|
||||
#include "cam_mem_mgr.h"
|
||||
#include "cam_sensor_cmn_header.h"
|
||||
#include "cam_sensor_util.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_sensor_io.h"
|
||||
|
|
@ -137,6 +138,7 @@ struct cam_flash_frame_setting {
|
|||
* @torch_op_current : Torch operational current
|
||||
* @torch_max_current : Max supported current for LED in torch mode
|
||||
* @is_wled_flash : Detection between WLED/LED flash
|
||||
* @flash_type : Flash type
|
||||
*/
|
||||
|
||||
struct cam_flash_private_soc {
|
||||
|
|
@ -149,6 +151,7 @@ struct cam_flash_private_soc {
|
|||
uint32_t torch_op_current[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
uint32_t torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
bool is_wled_flash;
|
||||
uint32_t flash_type;
|
||||
};
|
||||
|
||||
struct cam_flash_func_tbl {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
|
@ -73,6 +73,12 @@ static int32_t cam_get_source_node_info(
|
|||
soc_private->is_wled_flash =
|
||||
of_property_read_bool(of_node, "wled-flash-support");
|
||||
|
||||
rc = of_property_read_u32(of_node, "flash-type", &soc_private->flash_type);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"flash-type read failed rc=%d", rc);
|
||||
}
|
||||
|
||||
switch_src_node = of_parse_phandle(of_node, "switch-source", 0);
|
||||
if (!switch_src_node) {
|
||||
CAM_WARN(CAM_FLASH, "switch_src_node NULL");
|
||||
|
|
|
|||
|
|
@ -10,29 +10,7 @@
|
|||
#include "cam_debug_util.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_ois_driver_cmd(o_ctrl, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_OIS,
|
||||
"Failed with driver cmd: %d", rc);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_OIS, "Wrong IOCTL cmd: %u", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ois_subdev_close(struct v4l2_subdev *sd,
|
||||
static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_ois_ctrl_t *o_ctrl =
|
||||
|
|
@ -50,6 +28,48 @@ static int cam_ois_subdev_close(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_ois_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_OIS);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_OIS, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_ois_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_ois_ctrl_t *o_ctrl = v4l2_get_subdevdata(sd);
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_ois_driver_cmd(o_ctrl, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_OIS,
|
||||
"Failed with driver cmd: %d", rc);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
rc = cam_ois_subdev_close_internal(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_OIS, "Wrong IOCTL cmd: %u", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t cam_ois_update_i2c_info(struct cam_ois_ctrl_t *o_ctrl,
|
||||
struct cam_ois_i2c_info_t *i2c_info)
|
||||
{
|
||||
|
|
@ -144,6 +164,7 @@ static int cam_ois_init_subdev_param(struct cam_ois_ctrl_t *o_ctrl)
|
|||
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
|
||||
o_ctrl->v4l2_dev_str.ent_function = CAM_OIS_DEVICE_TYPE;
|
||||
o_ctrl->v4l2_dev_str.token = o_ctrl;
|
||||
o_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(o_ctrl->v4l2_dev_str));
|
||||
if (rc)
|
||||
|
|
|
|||
|
|
@ -9,29 +9,7 @@
|
|||
#include "cam_sensor_core.h"
|
||||
#include "camera_main.h"
|
||||
|
||||
static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sensor_ctrl_t *s_ctrl =
|
||||
v4l2_get_subdevdata(sd);
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_sensor_driver_cmd(s_ctrl, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Failed in Driver cmd: %d", rc);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
|
||||
static int cam_sensor_subdev_close_internal(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct cam_sensor_ctrl_t *s_ctrl =
|
||||
|
|
@ -49,6 +27,49 @@ static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sensor_subdev_close(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
bool crm_active = cam_req_mgr_is_open(CAM_SENSOR);
|
||||
|
||||
if (crm_active) {
|
||||
CAM_DBG(CAM_SENSOR, "CRM is ACTIVE, close should be from CRM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cam_sensor_subdev_close_internal(sd, fh);
|
||||
}
|
||||
|
||||
static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sensor_ctrl_t *s_ctrl =
|
||||
v4l2_get_subdevdata(sd);
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_CAM_CONTROL:
|
||||
rc = cam_sensor_driver_cmd(s_ctrl, arg);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Failed in Driver cmd: %d", rc);
|
||||
break;
|
||||
case CAM_SD_SHUTDOWN:
|
||||
if (!cam_req_mgr_is_shutdown()) {
|
||||
CAM_ERR(CAM_CORE, "SD shouldn't come from user space");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = cam_sensor_subdev_close_internal(sd, NULL);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_SENSOR, "Invalid ioctl cmd: %d", cmd);
|
||||
rc = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long cam_sensor_init_subdev_do_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
|
@ -122,6 +143,8 @@ static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
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_PRIORITY;
|
||||
|
||||
rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str));
|
||||
if (rc)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SENSOR_I2C_H_
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
#define I2C_COMPARE_MATCH 0
|
||||
#define I2C_COMPARE_MISMATCH 1
|
||||
|
||||
#define I2C_REG_DATA_MAX (10*1024)
|
||||
#define I2C_REG_DATA_MAX (20*1024)
|
||||
|
||||
/**
|
||||
* @client: CCI client structure
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_SENSOR_CMN_HEADER_
|
||||
|
|
@ -345,6 +345,12 @@ enum msm_sensor_camera_id_t {
|
|||
CAMERA_7,
|
||||
CAMERA_8,
|
||||
CAMERA_9,
|
||||
CAMERA_10,
|
||||
CAMERA_11,
|
||||
CAMERA_12,
|
||||
CAMERA_13,
|
||||
CAMERA_14,
|
||||
CAMERA_15,
|
||||
MAX_CAMERAS,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2407,6 +2407,10 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
|
|||
case SENSOR_CUSTOM_GPIO1:
|
||||
case SENSOR_CUSTOM_GPIO2:
|
||||
|
||||
if (!gpio_num_info) {
|
||||
CAM_ERR(CAM_SENSOR, "failed: No gpio");
|
||||
continue;
|
||||
}
|
||||
if (!gpio_num_info->valid[pd->seq_type])
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/interconnect.h>
|
||||
#include "cam_soc_bus.h"
|
||||
|
||||
#include <asm/div64.h>
|
||||
/**
|
||||
* struct cam_soc_bus_client_data : Bus client data
|
||||
*
|
||||
|
|
@ -37,8 +37,8 @@ int cam_soc_bus_client_update_request(void *client, unsigned int idx)
|
|||
CAM_DBG(CAM_PERF, "Bus client=[%s] index[%d] ab[%llu] ib[%llu]",
|
||||
bus_client->common_data->name, idx, ab, ib);
|
||||
|
||||
rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
|
||||
Bps_to_icc(ib));
|
||||
rc = icc_set_bw(bus_client_data->icc_data, do_div(ab, 1000),
|
||||
do_div(ib, 1000));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL,
|
||||
"Update request failed, client[%s], idx: %d",
|
||||
|
|
@ -60,8 +60,8 @@ int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
|
|||
|
||||
CAM_DBG(CAM_PERF, "Bus client=[%s] :ab[%llu] ib[%llu]",
|
||||
bus_client->common_data->name, ab, ib);
|
||||
rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
|
||||
Bps_to_icc(ib));
|
||||
rc = icc_set_bw(bus_client_data->icc_data, do_div(ab, 1000),
|
||||
do_div(ib, 1000));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
|
||||
bus_client->common_data->name);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __UAPI_CAM_SENSOR_H__
|
||||
|
|
@ -476,6 +476,7 @@ struct cam_flash_query_curr {
|
|||
* @max_current_flash : max supported current for flash
|
||||
* @max_duration_flash : max flash turn on duration
|
||||
* @max_current_torch : max supported current for torch
|
||||
* @flash_type : Indicates about the flash type -I2C,GPIO,PMIC
|
||||
*
|
||||
*/
|
||||
struct cam_flash_query_cap_info {
|
||||
|
|
@ -483,6 +484,7 @@ struct cam_flash_query_cap_info {
|
|||
__u32 max_current_flash[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
__u32 max_duration_flash[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
__u32 max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
__u32 flash_type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue