Merge "msm: ais: Camera clock voting fixes for LA XO"
This commit is contained in:
commit
874c79ac6b
18 changed files with 565 additions and 29 deletions
|
@ -21,4 +21,5 @@ obj-$(CONFIG_MSM_AIS) += ispif/
|
|||
obj-$(CONFIG_MSM_AIS_JPEG) += jpeg_10/
|
||||
obj-$(CONFIG_MSM_AIS_JPEGDMA) += jpeg_dma/
|
||||
obj-$(CONFIG_MSM_AIS) += msm_buf_mgr/
|
||||
obj-$(CONFIG_MSM_AIS) += msm_ais_mgr/
|
||||
obj-$(CONFIG_MSM_AIS_FD) += fd/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -306,19 +306,12 @@ int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
|
|||
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] =
|
||||
vfe_dev->vfe_base;
|
||||
|
||||
rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
|
||||
MSM_ISP_MIN_AB, MSM_ISP_MIN_IB);
|
||||
if (rc)
|
||||
goto bw_enable_fail;
|
||||
|
||||
rc = msm_camera_enable_irq(vfe_dev->vfe_irq, 1);
|
||||
if (rc < 0)
|
||||
goto irq_enable_fail;
|
||||
|
||||
return rc;
|
||||
irq_enable_fail:
|
||||
msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, 0, 0);
|
||||
bw_enable_fail:
|
||||
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;
|
||||
if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
|
||||
pr_err("%s: failed to remove vote for AHB\n", __func__);
|
||||
|
@ -347,8 +340,6 @@ void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
|
|||
|
||||
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;
|
||||
|
||||
msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, 0, 0);
|
||||
|
||||
if (vfe_dev->pdev->id == 0)
|
||||
id = CAM_AHB_CLIENT_VFE0;
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -1106,9 +1106,11 @@ void msm_isp_calculate_bandwidth(
|
|||
int bpp = 0;
|
||||
|
||||
if (stream_info->stream_src < RDI_INTF_0) {
|
||||
stream_info->max_width = max(stream_info->max_width,
|
||||
axi_data->src_info[VFE_PIX_0].width);
|
||||
stream_info->bandwidth =
|
||||
(axi_data->src_info[VFE_PIX_0].pixel_clock /
|
||||
axi_data->src_info[VFE_PIX_0].width) *
|
||||
(axi_data->src_info[VFE_PIX_0].pixel_clock *
|
||||
axi_data->src_info[VFE_PIX_0].width) /
|
||||
stream_info->max_width;
|
||||
stream_info->bandwidth = (unsigned long)stream_info->bandwidth *
|
||||
stream_info->format_factor / ISP_Q2;
|
||||
|
@ -2272,8 +2274,7 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev,
|
|||
|
||||
total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth;
|
||||
rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
|
||||
(total_bandwidth + vfe_dev->hw_info->min_ab),
|
||||
(total_bandwidth + vfe_dev->hw_info->min_ib));
|
||||
total_bandwidth, total_bandwidth);
|
||||
if (rc < 0)
|
||||
pr_err("%s: update failed\n", __func__);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -2217,6 +2217,7 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||
{
|
||||
struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
|
||||
long rc = 0;
|
||||
enum cam_ahb_clk_client id;
|
||||
|
||||
ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);
|
||||
|
||||
|
@ -2291,6 +2292,17 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||
cam_smmu_reg_client_page_fault_handler(
|
||||
vfe_dev->buf_mgr->iommu_hdl,
|
||||
msm_vfe_iommu_fault_handler, vfe_dev);
|
||||
|
||||
/* Disable vfe clks and allow device to go XO shutdown mode */
|
||||
if (vfe_dev->pdev->id == 0)
|
||||
id = CAM_AHB_CLIENT_VFE0;
|
||||
else
|
||||
id = CAM_AHB_CLIENT_VFE1;
|
||||
if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
|
||||
pr_err("%s: failed to remove vote for AHB\n", __func__);
|
||||
vfe_dev->hw_info->vfe_ops.platform_ops.enable_clks(vfe_dev, 0);
|
||||
vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(vfe_dev, 0);
|
||||
|
||||
mutex_unlock(&vfe_dev->core_mutex);
|
||||
mutex_unlock(&vfe_dev->realtime_mutex);
|
||||
return 0;
|
||||
|
@ -2313,11 +2325,22 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||
long rc = 0;
|
||||
int wm;
|
||||
struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
|
||||
enum cam_ahb_clk_client id;
|
||||
|
||||
ISP_DBG("%s E open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);
|
||||
mutex_lock(&vfe_dev->realtime_mutex);
|
||||
mutex_lock(&vfe_dev->core_mutex);
|
||||
|
||||
/* Enable vfe clks to wake up from XO shutdown mode */
|
||||
if (vfe_dev->pdev->id == 0)
|
||||
id = CAM_AHB_CLIENT_VFE0;
|
||||
else
|
||||
id = CAM_AHB_CLIENT_VFE1;
|
||||
if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SVS_VOTE) < 0)
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
vfe_dev->hw_info->vfe_ops.platform_ops.enable_clks(vfe_dev, 1);
|
||||
vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(vfe_dev, 1);
|
||||
|
||||
if (!vfe_dev->vfe_open_cnt) {
|
||||
pr_err("%s invalid state open cnt %d\n", __func__,
|
||||
vfe_dev->vfe_open_cnt);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -1437,13 +1437,6 @@ static int msm_ispif_init(struct ispif_device *ispif,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0,
|
||||
CAM_AHB_CLIENT_ISPIF, CAM_AHB_SVS_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = msm_ispif_reset_hw(ispif);
|
||||
if (rc)
|
||||
goto error_ahb;
|
||||
|
@ -1608,6 +1601,11 @@ static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||
rc = msm_camera_enable_irq(ispif->irq, 1);
|
||||
if (rc)
|
||||
goto irq_enable_fail;
|
||||
|
||||
/* Disable ispif clk and allow device to go XO shutdown */
|
||||
msm_ispif_clk_ahb_enable(ispif, 0);
|
||||
msm_ispif_set_regulators(ispif->ispif_vdd,
|
||||
ispif->ispif_vdd_count, 0);
|
||||
}
|
||||
/* mem remap is done in init when the clock is on */
|
||||
ispif->open_cnt++;
|
||||
|
@ -1640,6 +1638,10 @@ static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||
}
|
||||
ispif->open_cnt--;
|
||||
if (ispif->open_cnt == 0) {
|
||||
/* Enable ispif clk to wake up from XO shutdown mode */
|
||||
msm_ispif_clk_ahb_enable(ispif, 1);
|
||||
msm_ispif_set_regulators(ispif->ispif_vdd,
|
||||
ispif->ispif_vdd_count, 1);
|
||||
msm_ispif_release(ispif);
|
||||
/* disable clocks and regulator on last close */
|
||||
msm_ispif_clk_ahb_enable(ispif, 0);
|
||||
|
|
5
drivers/media/platform/msm/ais/msm_ais_mgr/Makefile
Normal file
5
drivers/media/platform/msm/ais/msm_ais_mgr/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
ccflags-y += -Idrivers/media/platform/msm/ais
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/common
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/cci
|
||||
obj-$(CONFIG_MSM_AIS) += msm_ais_mgr.o
|
147
drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mgr.c
Normal file
147
drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mgr.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "CAM-BUFMGR %s:%d " fmt, __func__, __LINE__
|
||||
|
||||
#include <media/ais/msm_ais_mgr.h>
|
||||
#include "msm_ais_mngr.h"
|
||||
#include "msm_early_cam.h"
|
||||
|
||||
#undef CDBG
|
||||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
|
||||
static struct msm_ais_mngr_device *msm_ais_mngr_dev;
|
||||
|
||||
static long msm_ais_hndl_ioctl(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
long rc = 0;
|
||||
struct clk_mgr_cfg_data *pcdata = (struct clk_mgr_cfg_data *)arg;
|
||||
struct msm_ais_mngr_device *clk_mngr_dev =
|
||||
(struct msm_ais_mngr_device *)v4l2_get_subdevdata(sd);
|
||||
|
||||
if (WARN_ON(!clk_mngr_dev) || WARN_ON(!pcdata)) {
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
mutex_lock(&clk_mngr_dev->cont_mutex);
|
||||
CDBG(pr_fmt("cfg_type = %d\n"), pcdata->cfg_type);
|
||||
switch (pcdata->cfg_type) {
|
||||
case AIS_CLK_ENABLE:
|
||||
rc = msm_ais_enable_clocks();
|
||||
break;
|
||||
case AIS_CLK_DISABLE:
|
||||
rc = msm_ais_disable_clocks();
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("invalid cfg_type\n");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&clk_mngr_dev->cont_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long msm_ais_mngr_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
|
||||
CDBG(pr_fmt("Enter\n"));
|
||||
switch (cmd) {
|
||||
case VIDIOC_MSM_AIS_CLK_CFG:
|
||||
rc = msm_ais_hndl_ioctl(sd, arg);
|
||||
if (rc)
|
||||
pr_err("msm_ais_mngr_subdev_ioctl failed\n");
|
||||
break;
|
||||
default:
|
||||
rc = -ENOIOCTLCMD;
|
||||
}
|
||||
CDBG(pr_fmt("Exit\n"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct v4l2_subdev_core_ops msm_ais_mngr_subdev_core_ops = {
|
||||
.ioctl = msm_ais_mngr_subdev_ioctl,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops msm_ais_mngr_subdev_ops = {
|
||||
.core = &msm_ais_mngr_subdev_core_ops,
|
||||
};
|
||||
|
||||
static struct v4l2_file_operations msm_ais_v4l2_subdev_fops;
|
||||
|
||||
static long msm_clkmgr_subdev_do_ioctl(
|
||||
struct file *file, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
|
||||
|
||||
return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
|
||||
}
|
||||
|
||||
|
||||
static long msm_ais_subdev_fops_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return video_usercopy(file, cmd, arg, msm_clkmgr_subdev_do_ioctl);
|
||||
}
|
||||
|
||||
static int32_t __init msm_ais_mngr_init(void)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
|
||||
msm_ais_mngr_dev = kzalloc(sizeof(*msm_ais_mngr_dev),
|
||||
GFP_KERNEL);
|
||||
if (!msm_ais_mngr_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Sub-dev */
|
||||
v4l2_subdev_init(&msm_ais_mngr_dev->subdev.sd,
|
||||
&msm_ais_mngr_subdev_ops);
|
||||
msm_cam_copy_v4l2_subdev_fops(&msm_ais_v4l2_subdev_fops);
|
||||
msm_ais_v4l2_subdev_fops.unlocked_ioctl = msm_ais_subdev_fops_ioctl;
|
||||
|
||||
snprintf(msm_ais_mngr_dev->subdev.sd.name,
|
||||
ARRAY_SIZE(msm_ais_mngr_dev->subdev.sd.name), "msm_ais_mngr");
|
||||
msm_ais_mngr_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
v4l2_set_subdevdata(&msm_ais_mngr_dev->subdev.sd, msm_ais_mngr_dev);
|
||||
|
||||
media_entity_init(&msm_ais_mngr_dev->subdev.sd.entity, 0, NULL, 0);
|
||||
msm_ais_mngr_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
|
||||
msm_ais_mngr_dev->subdev.sd.entity.group_id =
|
||||
MSM_CAMERA_SUBDEV_AIS_MNGR;
|
||||
msm_ais_mngr_dev->subdev.close_seq = MSM_SD_CLOSE_4TH_CATEGORY;
|
||||
rc = msm_sd_register(&msm_ais_mngr_dev->subdev);
|
||||
if (rc != 0) {
|
||||
pr_err("msm_sd_register error = %d\n", rc);
|
||||
kfree(msm_ais_mngr_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
msm_ais_mngr_dev->subdev.sd.devnode->fops = &msm_ais_v4l2_subdev_fops;
|
||||
mutex_init(&msm_ais_mngr_dev->cont_mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit msm_ais_mngr_exit(void)
|
||||
{
|
||||
msm_sd_unregister(&msm_ais_mngr_dev->subdev);
|
||||
mutex_destroy(&msm_ais_mngr_dev->cont_mutex);
|
||||
kfree(msm_ais_mngr_dev);
|
||||
}
|
||||
|
||||
module_init(msm_ais_mngr_init);
|
||||
module_exit(msm_ais_mngr_exit);
|
||||
MODULE_DESCRIPTION("MSM AIS Manager");
|
||||
MODULE_LICENSE("GPL v2");
|
31
drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mngr.h
Normal file
31
drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mngr.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_CLK_GENERIC_MNGR_H__
|
||||
#define __MSM_CLK_GENERIC_MNGR_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/ais/msm_ais.h>
|
||||
|
||||
#include "msm.h"
|
||||
#include "msm_sd.h"
|
||||
|
||||
struct msm_ais_mngr_device {
|
||||
struct msm_sd_subdev subdev;
|
||||
struct mutex cont_mutex;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
ccflags-y += -Idrivers/media/platform/msm/ais
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/common
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/cci
|
||||
obj-$(CONFIG_MSM_AIS) += msm_cci.o
|
||||
obj-$(CONFIG_MSM_AIS) += msm_early_cam.o
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -112,6 +112,199 @@ int msm_early_cam_disable_clocks(void)
|
|||
pr_debug("Turned OFF camera clocks\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int msm_ais_enable_clocks(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("%s:\n", __func__);
|
||||
/* Vote ON for clocks */
|
||||
if (new_early_cam_dev == NULL) {
|
||||
rc = -EINVAL;
|
||||
pr_err("%s: clock structure uninitialised %d\n", __func__,
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Vote for camera abh clocks */
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
|
||||
CAM_AHB_SVS_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
|
||||
CAM_AHB_SVS_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
|
||||
CAM_AHB_SVS_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
|
||||
CAM_AHB_SVS_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE1,
|
||||
CAM_AHB_SVS_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote for AHB\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (new_early_cam_dev->pdev->dev.of_node)
|
||||
of_property_read_u32((&new_early_cam_dev->pdev->dev)->of_node,
|
||||
"cell-index", &new_early_cam_dev->pdev->id);
|
||||
|
||||
rc = msm_camera_get_clk_info_and_rates(new_early_cam_dev->pdev,
|
||||
&new_early_cam_dev->early_cam_clk_info,
|
||||
&new_early_cam_dev->early_cam_clk,
|
||||
&new_early_cam_dev->early_cam_clk_rates,
|
||||
&new_early_cam_dev->num_clk_cases,
|
||||
&new_early_cam_dev->num_clk);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: msm_early_cam_get_clk_info() failed", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = msm_camera_get_dt_vreg_data(
|
||||
new_early_cam_dev->pdev->dev.of_node,
|
||||
&(new_early_cam_dev->early_cam_vreg),
|
||||
&(new_early_cam_dev->regulator_count));
|
||||
if (rc < 0) {
|
||||
pr_err("%s: msm_camera_get_dt_vreg_data fail\n", __func__);
|
||||
rc = -EFAULT;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((new_early_cam_dev->regulator_count < 0) ||
|
||||
(new_early_cam_dev->regulator_count > MAX_REGULATOR)) {
|
||||
pr_err("%s: invalid reg count = %d, max is %d\n", __func__,
|
||||
new_early_cam_dev->regulator_count, MAX_REGULATOR);
|
||||
rc = -EFAULT;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = msm_camera_config_vreg(&new_early_cam_dev->pdev->dev,
|
||||
new_early_cam_dev->early_cam_vreg,
|
||||
new_early_cam_dev->regulator_count,
|
||||
NULL,
|
||||
0,
|
||||
&new_early_cam_dev->early_cam_reg_ptr[0], 1);
|
||||
if (rc < 0)
|
||||
pr_err("%s:%d early_cam config_vreg failed\n", __func__,
|
||||
__LINE__);
|
||||
|
||||
rc = msm_camera_enable_vreg(&new_early_cam_dev->pdev->dev,
|
||||
new_early_cam_dev->early_cam_vreg,
|
||||
new_early_cam_dev->regulator_count,
|
||||
NULL,
|
||||
0,
|
||||
&new_early_cam_dev->early_cam_reg_ptr[0], 1);
|
||||
if (rc < 0)
|
||||
pr_err("%s:%d early_cam enable_vreg failed\n", __func__,
|
||||
__LINE__);
|
||||
|
||||
rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
|
||||
new_early_cam_dev->early_cam_clk_info,
|
||||
new_early_cam_dev->early_cam_clk,
|
||||
new_early_cam_dev->num_clk, true);
|
||||
|
||||
if (rc < 0) {
|
||||
pr_err("%s: clk enable failed %d\n", __func__, rc);
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
pr_debug("Turned ON camera clocks\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int msm_ais_disable_clocks(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("%s:\n", __func__);
|
||||
/* Vote OFF for clocks */
|
||||
if (new_early_cam_dev == NULL) {
|
||||
rc = -EINVAL;
|
||||
pr_err("%s: clock structure uninitialised %d\n", __func__,
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((new_early_cam_dev->pdev == NULL) ||
|
||||
(new_early_cam_dev->early_cam_clk_info == NULL) ||
|
||||
(new_early_cam_dev->early_cam_clk == NULL) ||
|
||||
(new_early_cam_dev->num_clk == 0)) {
|
||||
rc = -EINVAL;
|
||||
pr_err("%s: Clock details uninitialised %d\n", __func__,
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
|
||||
new_early_cam_dev->early_cam_clk_info,
|
||||
new_early_cam_dev->early_cam_clk,
|
||||
new_early_cam_dev->num_clk, false);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: clk disable failed %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
|
||||
CAM_AHB_SUSPEND_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote OFF AHB_CLIENT_CSIPHY %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
|
||||
CAM_AHB_SUSPEND_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote OFF AHB_CLIENT_CSID %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
|
||||
CAM_AHB_SUSPEND_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote OFF AHB_CLIENT_ISPIF %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
|
||||
CAM_AHB_SUSPEND_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote OFF AHB_CLIENT_VFE0 %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE1,
|
||||
CAM_AHB_SUSPEND_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote OFF AHB_CLIENT_VFE0 %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
pr_debug("Turned OFF camera clocks\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
static int msm_early_cam_probe(struct platform_device *pdev)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include <linux/workqueue.h>
|
||||
#include <media/ais/msm_ais_sensor.h>
|
||||
#include <soc/qcom/ais.h>
|
||||
#include <media/ais/msm_ais.h>
|
||||
#include "msm_sd.h"
|
||||
#include "cam_soc_api.h"
|
||||
|
||||
|
@ -50,4 +51,6 @@ struct early_cam_device {
|
|||
};
|
||||
|
||||
int msm_early_cam_disable_clocks(void);
|
||||
int msm_ais_enable_clocks(void);
|
||||
int msm_ais_disable_clocks(void);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -1733,3 +1733,50 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int msm_camera_cci_power_up(enum msm_camera_device_type_t device_type,
|
||||
struct msm_camera_i2c_client *sensor_i2c_client)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("%s:%d\n", __func__, __LINE__);
|
||||
if (!sensor_i2c_client) {
|
||||
pr_err("failed sensor_i2c_client %pK\n",
|
||||
sensor_i2c_client);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_type == MSM_CAMERA_PLATFORM_DEVICE) {
|
||||
rc = sensor_i2c_client->i2c_func_tbl->i2c_util(
|
||||
sensor_i2c_client, MSM_CCI_INIT);
|
||||
if (rc < 0) {
|
||||
pr_err("%s cci_init failed\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
CDBG("%s exit\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_camera_cci_power_down(enum msm_camera_device_type_t device_type,
|
||||
struct msm_camera_i2c_client *sensor_i2c_client)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("%s:%d\n", __func__, __LINE__);
|
||||
if (!sensor_i2c_client) {
|
||||
pr_err("failed sensor_i2c_client %pK\n",
|
||||
sensor_i2c_client);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device_type == MSM_CAMERA_PLATFORM_DEVICE) {
|
||||
rc = sensor_i2c_client->i2c_func_tbl->i2c_util(
|
||||
sensor_i2c_client, MSM_CCI_RELEASE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s MSM_CCI_RELEASE failed\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
CDBG("%s exit\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -68,4 +68,10 @@ int msm_cam_sensor_handle_reg_gpio(int seq_val,
|
|||
int32_t msm_sensor_driver_get_gpio_data(
|
||||
struct msm_camera_gpio_conf **gpio_conf,
|
||||
struct device_node *of_node);
|
||||
|
||||
int msm_camera_cci_power_up(enum msm_camera_device_type_t device_type,
|
||||
struct msm_camera_i2c_client *sensor_i2c_client);
|
||||
|
||||
int msm_camera_cci_power_down(enum msm_camera_device_type_t device_type,
|
||||
struct msm_camera_i2c_client *sensor_i2c_client);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -875,6 +875,30 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
|
|||
rc = -EFAULT;
|
||||
}
|
||||
break;
|
||||
case CFG_CCI_POWER_UP:
|
||||
if (s_ctrl->is_csid_tg_mode)
|
||||
goto DONE;
|
||||
|
||||
rc = msm_camera_cci_power_up(s_ctrl->sensor_device_type,
|
||||
s_ctrl->sensor_i2c_client);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:%d failed rc %d\n", __func__,
|
||||
__LINE__, rc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CFG_CCI_POWER_DOWN:
|
||||
if (s_ctrl->is_csid_tg_mode)
|
||||
goto DONE;
|
||||
|
||||
rc = msm_camera_cci_power_down(s_ctrl->sensor_device_type,
|
||||
s_ctrl->sensor_i2c_client);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:%d failed rc %d\n", __func__,
|
||||
__LINE__, rc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CFG_SET_STOP_STREAM_SETTING: {
|
||||
struct msm_camera_i2c_reg_setting32 stop_setting32;
|
||||
struct msm_camera_i2c_reg_setting *stop_setting =
|
||||
|
@ -1364,6 +1388,32 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void *argp)
|
|||
}
|
||||
break;
|
||||
|
||||
case CFG_CCI_POWER_UP:
|
||||
if (s_ctrl->is_csid_tg_mode)
|
||||
goto DONE;
|
||||
|
||||
rc = msm_camera_cci_power_up(s_ctrl->sensor_device_type,
|
||||
s_ctrl->sensor_i2c_client);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:%d failed rc %d\n", __func__,
|
||||
__LINE__, rc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_CCI_POWER_DOWN:
|
||||
if (s_ctrl->is_csid_tg_mode)
|
||||
goto DONE;
|
||||
|
||||
rc = msm_camera_cci_power_down(s_ctrl->sensor_device_type,
|
||||
s_ctrl->sensor_i2c_client);
|
||||
if (rc < 0) {
|
||||
pr_err("%s:%d failed rc %d\n", __func__,
|
||||
__LINE__, rc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_SET_STOP_STREAM_SETTING: {
|
||||
struct msm_camera_i2c_reg_setting *stop_setting =
|
||||
&s_ctrl->stop_setting;
|
||||
|
|
|
@ -4,3 +4,4 @@ header-y += msm_ais_isp.h
|
|||
header-y += msm_ais_ispif.h
|
||||
header-y += msm_ais_sensor.h
|
||||
header-y += msm_ais_sensor_sdk.h
|
||||
header-y += msm_ais_mgr.h
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#define MSM_CAMERA_SUBDEV_IR_LED 18
|
||||
#define MSM_CAMERA_SUBDEV_IR_CUT 19
|
||||
#define MSM_CAMERA_SUBDEV_EXT 20
|
||||
#define MSM_CAMERA_SUBDEV_AIS_MNGR 21
|
||||
|
||||
#define MSM_MAX_CAMERA_SENSORS 5
|
||||
|
||||
|
|
28
include/uapi/media/ais/msm_ais_mgr.h
Normal file
28
include/uapi/media/ais/msm_ais_mgr.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef __UAPI_MEDIA_MSM_AIS_MGR_H__
|
||||
#define __UAPI_MEDIA_MSM_AIS_MGR_H__
|
||||
|
||||
#include <media/ais/msm_ais.h>
|
||||
|
||||
enum clk_mgr_cfg_type_t {
|
||||
AIS_CLK_ENABLE,
|
||||
AIS_CLK_DISABLE,
|
||||
};
|
||||
|
||||
#define AIS_CLK_ENABLE AIS_CLK_ENABLE
|
||||
#define AIS_CLK_DISABLE AIS_CLK_DISABLE
|
||||
|
||||
struct clk_mgr_cfg_data_ext {
|
||||
enum clk_mgr_cfg_type_t cfg_type;
|
||||
};
|
||||
|
||||
struct clk_mgr_cfg_data {
|
||||
enum clk_mgr_cfg_type_t cfg_type;
|
||||
};
|
||||
|
||||
#define VIDIOC_MSM_AIS_CLK_CFG \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE, struct clk_mgr_cfg_data)
|
||||
|
||||
#define VIDIOC_MSM_AIS_CLK_CFG_EXT \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE+1, struct clk_mgr_cfg_data_ext)
|
||||
|
||||
#endif /* __UAPI_MEDIA_MSM_AIS_MGR_H__ */
|
|
@ -369,8 +369,13 @@ enum msm_sensor_cfg_type_t {
|
|||
CFG_WRITE_I2C_ARRAY_ASYNC,
|
||||
CFG_WRITE_I2C_ARRAY_SYNC,
|
||||
CFG_WRITE_I2C_ARRAY_SYNC_BLOCK,
|
||||
CFG_CCI_POWER_UP,
|
||||
CFG_CCI_POWER_DOWN,
|
||||
};
|
||||
|
||||
#define CFG_CCI_POWER_UP CFG_CCI_POWER_UP
|
||||
#define CFG_CCI_POWER_DOWN CFG_CCI_POWER_DOWN
|
||||
|
||||
enum msm_actuator_cfg_type_t {
|
||||
CFG_GET_ACTUATOR_INFO,
|
||||
CFG_SET_ACTUATOR_INFO,
|
||||
|
|
Loading…
Add table
Reference in a new issue