Merge "msm: ais: Camera clock voting fixes for LA XO"

This commit is contained in:
Linux Build Service Account 2018-01-16 10:03:29 -08:00 committed by Gerrit - the friendly Code Review server
commit 874c79ac6b
18 changed files with 565 additions and 29 deletions

View file

@ -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/

View file

@ -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

View file

@ -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__);

View file

@ -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);

View file

@ -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);

View 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

View 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");

View 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

View file

@ -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

View file

@ -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)
{

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View 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__ */

View file

@ -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,