Merge "ARM: dts: msm: Enable early camera on msm8996 auto"
This commit is contained in:
commit
42be98d03f
7 changed files with 668 additions and 4 deletions
110
Documentation/devicetree/bindings/soc/qcom/msm-early-cam.txt
Normal file
110
Documentation/devicetree/bindings/soc/qcom/msm-early-cam.txt
Normal file
|
@ -0,0 +1,110 @@
|
|||
* Qualcomm Technologies Inc MSM BA
|
||||
|
||||
[Root level node]
|
||||
==================
|
||||
Required properties:
|
||||
- compatible: Must be "qcom,early-cam".
|
||||
|
||||
[Subnode]
|
||||
==========
|
||||
- qcom,early-cam-input-profile-#: Defines child nodes for the profiles supported
|
||||
by early camera driver. Each profile should have properties
|
||||
"mmagic-supply", "gdscr-supply", "vfe0-vdd-supply",
|
||||
"qcom,cam-vreg-name", "clocks", "clock-names",
|
||||
"qcom,clock-rates".
|
||||
Required properties:
|
||||
- mmagic-supply : should contain mmagic regulator used for mmagic clocks.
|
||||
- gdscr-supply : should contain gdsr regulator used for cci clocks.
|
||||
- vfe0-vdd-supply: phandle to vfe0 regulator.
|
||||
- qcom,cam-vreg-name : name of the voltage regulators required for the device.
|
||||
- clocks: List of clock handles. The parent clocks of the input clocks to the
|
||||
devices in this power domain are set to oscclk before power gating
|
||||
and restored back after powering on a domain. This is required for
|
||||
all domains which are powered on and off and not required for unused
|
||||
domains.
|
||||
- clock-names: name of the clock used by the driver.
|
||||
- qcom,clock-rates: clock rate in Hz.
|
||||
Example:
|
||||
|
||||
qcom,early-cam {
|
||||
cell-index = <0>;
|
||||
compatible = "qcom,early-cam";
|
||||
status = "ok";
|
||||
mmagic-supply = <&gdsc_mmagic_camss>;
|
||||
gdscr-supply = <&gdsc_camss_top>;
|
||||
vfe0-vdd-supply = <&gdsc_vfe0>;
|
||||
qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
|
||||
clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
|
||||
<&clock_mmss clk_camss_top_ahb_clk>,
|
||||
<&clock_mmss clk_cci_clk_src>,
|
||||
<&clock_mmss clk_camss_cci_ahb_clk>,
|
||||
<&clock_mmss clk_camss_cci_clk>,
|
||||
<&clock_mmss clk_camss_ahb_clk>,
|
||||
<&clock_mmss clk_mmagic_camss_axi_clk>,
|
||||
<&clock_mmss clk_camss_vfe_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe_axi_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_stream_clk>,
|
||||
<&clock_mmss clk_smmu_vfe_axi_clk>,
|
||||
<&clock_mmss clk_smmu_vfe_ahb_clk>,
|
||||
<&clock_mmss clk_camss_csi_vfe0_clk>,
|
||||
<&clock_mmss clk_vfe0_clk_src>,
|
||||
<&clock_mmss clk_camss_csi_vfe0_clk>,
|
||||
<&clock_mmss clk_camss_csi2_ahb_clk>,
|
||||
<&clock_mmss clk_camss_csi2_clk>,
|
||||
<&clock_mmss clk_camss_csi2phy_clk>,
|
||||
<&clock_mmss clk_csi2phytimer_clk_src>,
|
||||
<&clock_mmss clk_camss_csi2phytimer_clk>,
|
||||
<&clock_mmss clk_camss_csi2rdi_clk>,
|
||||
<&clock_mmss clk_camss_ispif_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_clk>;
|
||||
clock-names =
|
||||
"mmss_mmagic_ahb_clk",
|
||||
"camss_top_ahb_clk",
|
||||
"cci_clk_src",
|
||||
"camss_cci_ahb_clk",
|
||||
"camss_cci_clk",
|
||||
"camss_ahb_clk",
|
||||
"mmagic_camss_axi_clk",
|
||||
"camss_vfe_ahb_clk",
|
||||
"camss_vfe0_ahb_clk",
|
||||
"camss_vfe_axi_clk",
|
||||
"camss_vfe0_stream_clk",
|
||||
"smmu_vfe_axi_clk",
|
||||
"smmu_vfe_ahb_clk",
|
||||
"camss_csi_vfe0_clk",
|
||||
"vfe0_clk_src",
|
||||
"camss_csi_vfe0_clk",
|
||||
"camss_csi2_ahb_clk",
|
||||
"camss_csi2_clk",
|
||||
"camss_csi2phy_clk",
|
||||
"csi2phytimer_clk_src",
|
||||
"camss_csi2phytimer_clk",
|
||||
"camss_csi2rdi_clk",
|
||||
"camss_ispif_ahb_clk",
|
||||
"clk_camss_vfe0_clk";
|
||||
|
||||
qcom,clock-rates = <19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
0
|
||||
0
|
||||
0
|
||||
320000000
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
19200000
|
||||
0
|
||||
0
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
0
|
||||
};
|
|
@ -858,6 +858,90 @@
|
|||
};
|
||||
|
||||
&soc {
|
||||
qcom,early-cam {
|
||||
cell-index = <0>;
|
||||
compatible = "qcom,early-cam";
|
||||
status = "ok";
|
||||
mmagic-supply = <&gdsc_mmagic_camss>;
|
||||
gdscr-supply = <&gdsc_camss_top>;
|
||||
vfe0-vdd-supply = <&gdsc_vfe0>;
|
||||
qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
|
||||
clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
|
||||
<&clock_mmss clk_camss_top_ahb_clk>,
|
||||
<&clock_mmss clk_cci_clk_src>,
|
||||
<&clock_mmss clk_camss_cci_ahb_clk>,
|
||||
<&clock_mmss clk_camss_cci_clk>,
|
||||
<&clock_mmss clk_camss_ahb_clk>,
|
||||
<&clock_mmss clk_mmagic_camss_axi_clk>,
|
||||
<&clock_mmss clk_camss_vfe_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe_axi_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_stream_clk>,
|
||||
<&clock_mmss clk_smmu_vfe_axi_clk>,
|
||||
<&clock_mmss clk_smmu_vfe_ahb_clk>,
|
||||
<&clock_mmss clk_camss_csi_vfe0_clk>,
|
||||
<&clock_mmss clk_vfe0_clk_src>,
|
||||
<&clock_mmss clk_camss_csi_vfe0_clk>,
|
||||
<&clock_mmss clk_camss_csi2_ahb_clk>,
|
||||
<&clock_mmss clk_camss_csi2_clk>,
|
||||
<&clock_mmss clk_camss_csi2phy_clk>,
|
||||
<&clock_mmss clk_csi2phytimer_clk_src>,
|
||||
<&clock_mmss clk_camss_csi2phytimer_clk>,
|
||||
<&clock_mmss clk_camss_csi2rdi_clk>,
|
||||
<&clock_mmss clk_camss_ispif_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_clk>;
|
||||
clock-names =
|
||||
"mmss_mmagic_ahb_clk",
|
||||
"camss_top_ahb_clk",
|
||||
"cci_clk_src",
|
||||
"camss_cci_ahb_clk",
|
||||
"camss_cci_clk",
|
||||
"camss_ahb_clk",
|
||||
"mmagic_camss_axi_clk",
|
||||
"camss_vfe_ahb_clk",
|
||||
"camss_vfe0_ahb_clk",
|
||||
"camss_vfe_axi_clk",
|
||||
"camss_vfe0_stream_clk",
|
||||
"smmu_vfe_axi_clk",
|
||||
"smmu_vfe_ahb_clk",
|
||||
"camss_csi_vfe0_clk",
|
||||
"vfe0_clk_src",
|
||||
"camss_csi_vfe0_clk",
|
||||
"camss_csi2_ahb_clk",
|
||||
"camss_csi2_clk",
|
||||
"camss_csi2phy_clk",
|
||||
"csi2phytimer_clk_src",
|
||||
"camss_csi2phytimer_clk",
|
||||
"camss_csi2rdi_clk",
|
||||
"camss_ispif_ahb_clk",
|
||||
"clk_camss_vfe0_clk";
|
||||
|
||||
qcom,clock-rates = <19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
0
|
||||
0
|
||||
0
|
||||
320000000
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
19200000
|
||||
0
|
||||
0
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
0
|
||||
100000000>;
|
||||
};
|
||||
|
||||
qcom,ntn_avb {
|
||||
compatible = "qcom,ntn_avb";
|
||||
|
||||
|
@ -1457,11 +1541,21 @@
|
|||
};
|
||||
};
|
||||
|
||||
&vfe_smmu {
|
||||
qcom,no-smr-check;
|
||||
};
|
||||
|
||||
/ {
|
||||
reserved-memory {
|
||||
lk_mem: lk_pool@91600000 {
|
||||
reg = <0x0 0x91600000 0x0 0x600000>;
|
||||
lk_mem: lk_pool@0x91600000 {
|
||||
no-map;
|
||||
reg = <0 0x91600000 0 0x00600000>;
|
||||
label = "lk_pool";
|
||||
};
|
||||
|
||||
early_camera_mem: early_camera_mem@b3fff000 {
|
||||
reg = <0 0xb3fff000 0 0x800000>;
|
||||
label = "early_camera_mem";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -623,6 +623,90 @@
|
|||
};
|
||||
|
||||
&soc {
|
||||
qcom,early-cam {
|
||||
cell-index = <0>;
|
||||
compatible = "qcom,early-cam";
|
||||
status = "ok";
|
||||
mmagic-supply = <&gdsc_mmagic_camss>;
|
||||
gdscr-supply = <&gdsc_camss_top>;
|
||||
vfe0-vdd-supply = <&gdsc_vfe0>;
|
||||
qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
|
||||
clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
|
||||
<&clock_mmss clk_camss_top_ahb_clk>,
|
||||
<&clock_mmss clk_cci_clk_src>,
|
||||
<&clock_mmss clk_camss_cci_ahb_clk>,
|
||||
<&clock_mmss clk_camss_cci_clk>,
|
||||
<&clock_mmss clk_camss_ahb_clk>,
|
||||
<&clock_mmss clk_mmagic_camss_axi_clk>,
|
||||
<&clock_mmss clk_camss_vfe_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe_axi_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_stream_clk>,
|
||||
<&clock_mmss clk_smmu_vfe_axi_clk>,
|
||||
<&clock_mmss clk_smmu_vfe_ahb_clk>,
|
||||
<&clock_mmss clk_camss_csi_vfe0_clk>,
|
||||
<&clock_mmss clk_vfe0_clk_src>,
|
||||
<&clock_mmss clk_camss_csi_vfe0_clk>,
|
||||
<&clock_mmss clk_camss_csi2_ahb_clk>,
|
||||
<&clock_mmss clk_camss_csi2_clk>,
|
||||
<&clock_mmss clk_camss_csi2phy_clk>,
|
||||
<&clock_mmss clk_csi2phytimer_clk_src>,
|
||||
<&clock_mmss clk_camss_csi2phytimer_clk>,
|
||||
<&clock_mmss clk_camss_csi2rdi_clk>,
|
||||
<&clock_mmss clk_camss_ispif_ahb_clk>,
|
||||
<&clock_mmss clk_camss_vfe0_clk>;
|
||||
clock-names =
|
||||
"mmss_mmagic_ahb_clk",
|
||||
"camss_top_ahb_clk",
|
||||
"cci_clk_src",
|
||||
"camss_cci_ahb_clk",
|
||||
"camss_cci_clk",
|
||||
"camss_ahb_clk",
|
||||
"mmagic_camss_axi_clk",
|
||||
"camss_vfe_ahb_clk",
|
||||
"camss_vfe0_ahb_clk",
|
||||
"camss_vfe_axi_clk",
|
||||
"camss_vfe0_stream_clk",
|
||||
"smmu_vfe_axi_clk",
|
||||
"smmu_vfe_ahb_clk",
|
||||
"camss_csi_vfe0_clk",
|
||||
"vfe0_clk_src",
|
||||
"camss_csi_vfe0_clk",
|
||||
"camss_csi2_ahb_clk",
|
||||
"camss_csi2_clk",
|
||||
"camss_csi2phy_clk",
|
||||
"csi2phytimer_clk_src",
|
||||
"camss_csi2phytimer_clk",
|
||||
"camss_csi2rdi_clk",
|
||||
"camss_ispif_ahb_clk",
|
||||
"clk_camss_vfe0_clk";
|
||||
|
||||
qcom,clock-rates = <19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
19200000
|
||||
0
|
||||
0
|
||||
0
|
||||
320000000
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
19200000
|
||||
0
|
||||
0
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
200000000
|
||||
0
|
||||
100000000>;
|
||||
};
|
||||
|
||||
ntn1: ntn_avb@1 { /* Neutrno device on RC1*/
|
||||
compatible = "qcom,ntn_avb";
|
||||
|
||||
|
@ -1231,12 +1315,22 @@
|
|||
/delete-property/ qcom,spkr-sd-n-gpio;
|
||||
};
|
||||
|
||||
&vfe_smmu {
|
||||
qcom,no-smr-check;
|
||||
};
|
||||
|
||||
/ {
|
||||
reserved-memory {
|
||||
lk_mem: lk_pool@91600000 {
|
||||
reg = <0x0 0x91600000 0x0 0x600000>;
|
||||
lk_mem: lk_pool@0x91600000 {
|
||||
no-map;
|
||||
reg = <0 0x91600000 0 0x00600000>;
|
||||
label = "lk_pool";
|
||||
};
|
||||
|
||||
early_camera_mem: early_camera_mem@b3fff000 {
|
||||
reg = <0 0xb3fff000 0 0x800000>;
|
||||
label = "early_camera_mem";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@ ccflags-y += -Idrivers/media/platform/msm/ais
|
|||
ccflags-y += -Idrivers/media/platform/msm/ais/common
|
||||
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
|
||||
obj-$(CONFIG_MSM_AIS) += msm_cci.o
|
||||
obj-$(CONFIG_MSM_AIS) += msm_early_cam.o
|
||||
|
|
279
drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
Normal file
279
drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include "msm_sd.h"
|
||||
#include "msm_early_cam.h"
|
||||
#include "msm_cam_cci_hwreg.h"
|
||||
#include "msm_camera_io_util.h"
|
||||
#include "msm_camera_dt_util.h"
|
||||
#include "cam_hw_ops.h"
|
||||
|
||||
#undef CDBG
|
||||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
|
||||
#undef EARLY_CAM_DBG
|
||||
#ifdef MSM_EARLY_CAM_DEBUG
|
||||
#define EARLY_CAM_DBG(fmt, args...) pr_err(fmt, ##args)
|
||||
#else
|
||||
#define EARLY_CAM_DBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
#endif
|
||||
|
||||
#define MSM_EARLY_CAM_DRV_NAME "msm_early_cam"
|
||||
static struct platform_driver msm_early_camera_driver;
|
||||
static struct early_cam_device *new_early_cam_dev;
|
||||
|
||||
int msm_early_cam_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_CCI,
|
||||
CAM_AHB_SUSPEND_VOTE);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to vote OFF AHB_CLIENT_CCI %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;
|
||||
}
|
||||
pr_debug("Turned OFF camera clocks\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
static int msm_early_cam_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("%s: pdev %pK device id = %d\n", __func__, pdev, pdev->id);
|
||||
|
||||
/* Vote for Early camera if enabled */
|
||||
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_CCI,
|
||||
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;
|
||||
}
|
||||
|
||||
new_early_cam_dev = kzalloc(sizeof(struct early_cam_device),
|
||||
GFP_KERNEL);
|
||||
if (!new_early_cam_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
of_property_read_u32((&pdev->dev)->of_node,
|
||||
"cell-index", &pdev->id);
|
||||
|
||||
rc = msm_camera_get_clk_info_and_rates(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__);
|
||||
kfree(new_early_cam_dev);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
new_early_cam_dev->ref_count = 0;
|
||||
new_early_cam_dev->pdev = pdev;
|
||||
|
||||
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;
|
||||
goto early_cam_release_mem;
|
||||
}
|
||||
|
||||
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;
|
||||
goto early_cam_invalid_vreg_data;
|
||||
}
|
||||
|
||||
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;
|
||||
goto early_cam_release_mem;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, new_early_cam_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
early_cam_invalid_vreg_data:
|
||||
kfree(new_early_cam_dev->early_cam_vreg);
|
||||
early_cam_release_mem:
|
||||
kfree(new_early_cam_dev);
|
||||
new_early_cam_dev = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_early_cam_exit(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init msm_early_cam_init_module(void)
|
||||
{
|
||||
return platform_driver_register(&msm_early_camera_driver);
|
||||
}
|
||||
|
||||
static void __exit msm_early_cam_exit_module(void)
|
||||
{
|
||||
kfree(new_early_cam_dev);
|
||||
platform_driver_unregister(&msm_early_camera_driver);
|
||||
}
|
||||
|
||||
static const struct of_device_id msm_early_camera_match_table[] = {
|
||||
{ .compatible = "qcom,early-cam" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver msm_early_camera_driver = {
|
||||
.probe = msm_early_cam_probe,
|
||||
.remove = msm_early_cam_exit,
|
||||
.driver = {
|
||||
.name = MSM_EARLY_CAM_DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = msm_early_camera_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, msm_early_camera_match_table);
|
||||
|
||||
module_init(msm_early_cam_init_module);
|
||||
module_exit(msm_early_cam_exit_module);
|
||||
MODULE_DESCRIPTION("MSM early camera driver");
|
||||
MODULE_LICENSE("GPL v2");
|
53
drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
Normal file
53
drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* Copyright (c) 2012-2017, 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_EARLY_CAM_H
|
||||
#define MSM_EARLY_CAM_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <media/ais/msm_ais_sensor.h>
|
||||
#include <soc/qcom/ais.h>
|
||||
#include "msm_sd.h"
|
||||
#include "cam_soc_api.h"
|
||||
|
||||
#define NUM_MASTERS 2
|
||||
#define NUM_QUEUES 2
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
enum msm_early_cam_state_t {
|
||||
STATE_DISABLED,
|
||||
STATE_ENABLED,
|
||||
};
|
||||
|
||||
struct early_cam_device {
|
||||
struct platform_device *pdev;
|
||||
uint8_t ref_count;
|
||||
enum msm_early_cam_state_t early_cam_state;
|
||||
size_t num_clk;
|
||||
size_t num_clk_cases;
|
||||
struct clk **early_cam_clk;
|
||||
uint32_t **early_cam_clk_rates;
|
||||
struct msm_cam_clk_info *early_cam_clk_info;
|
||||
struct camera_vreg_t *early_cam_vreg;
|
||||
struct regulator *early_cam_reg_ptr[MAX_REGULATOR];
|
||||
int32_t regulator_count;
|
||||
};
|
||||
|
||||
int msm_early_cam_disable_clocks(void);
|
||||
#endif
|
|
@ -16,11 +16,17 @@
|
|||
#include "msm_sensor_driver.h"
|
||||
#include "msm_sensor.h"
|
||||
#include "msm_sd.h"
|
||||
#include "msm_camera_io_util.h"
|
||||
#include "msm_early_cam.h"
|
||||
|
||||
/* Logging macro */
|
||||
#undef CDBG
|
||||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
|
||||
#define EARLY_CAMERA_SIGNAL_DONE 0xa5a5a5a5
|
||||
#define EARLY_CAMERA_SIGNAL_DISABLED 0
|
||||
|
||||
static bool early_camera_clock_off;
|
||||
static struct msm_sensor_init_t *s_init;
|
||||
|
||||
static int msm_sensor_wait_for_probe_done(struct msm_sensor_init_t *s_init)
|
||||
|
@ -42,10 +48,14 @@ static int msm_sensor_wait_for_probe_done(struct msm_sensor_init_t *s_init)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define MMSS_A_VFE_0_SPARE 0xC84
|
||||
|
||||
/* Static function definition */
|
||||
int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init, void *arg)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
u32 val = 0;
|
||||
void __iomem *base;
|
||||
struct sensor_init_cfg_data *cfg = (struct sensor_init_cfg_data *)arg;
|
||||
|
||||
/* Validate input parameters */
|
||||
|
@ -68,6 +78,28 @@ int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init, void *arg)
|
|||
break;
|
||||
|
||||
case CFG_SINIT_PROBE_DONE:
|
||||
if (early_camera_clock_off == false) {
|
||||
base = ioremap(0x00A10000, 0x1000);
|
||||
val = msm_camera_io_r_mb(base + MMSS_A_VFE_0_SPARE);
|
||||
while (val != EARLY_CAMERA_SIGNAL_DONE) {
|
||||
if (val == EARLY_CAMERA_SIGNAL_DISABLED)
|
||||
break;
|
||||
msleep(1000);
|
||||
val = msm_camera_io_r_mb(
|
||||
base + MMSS_A_VFE_0_SPARE);
|
||||
pr_err("Waiting for signal from LK val = %u\n",
|
||||
val);
|
||||
}
|
||||
rc = msm_early_cam_disable_clocks();
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to disable early camera :%d\n",
|
||||
rc);
|
||||
} else {
|
||||
early_camera_clock_off = true;
|
||||
pr_debug("Voted OFF early camera clocks\n");
|
||||
}
|
||||
}
|
||||
|
||||
s_init->module_init_status = 1;
|
||||
wake_up(&s_init->state_wait);
|
||||
break;
|
||||
|
@ -99,6 +131,7 @@ static int __init msm_sensor_init_module(void)
|
|||
mutex_init(&s_init->imutex);
|
||||
|
||||
init_waitqueue_head(&s_init->state_wait);
|
||||
early_camera_clock_off = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue