Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a319aa43 authored by Sureshnaidu Laveti's avatar Sureshnaidu Laveti Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: sensor: Adapting sensor driver to soc layer



Adapting sensor driver to SOC layer by replacing msm specific
routines with SOC API which eases the portability of sensor driver
on to non-msm platforms.

Change-Id: I147dbf714d913b4aa55adc313c354f85cf4b23dd
Signed-off-by: default avatarSureshnaidu Laveti <lsuresh@codeaurora.org>
parent 55a40a40
Loading
Loading
Loading
Loading
+45 −116
Original line number Diff line number Diff line
@@ -59,8 +59,6 @@

static struct v4l2_subdev *g_cci_subdev;

static struct msm_cam_clk_info cci_clk_info[CCI_NUM_CLK_CASES][CCI_NUM_CLK_MAX];

static void msm_cci_dump_registers(struct cci_device *cci_dev,
	enum cci_i2c_master_t master, enum cci_i2c_queue_t queue)
{
@@ -1189,7 +1187,7 @@ static uint32_t msm_cci_cycles_per_ms(unsigned long clk)
	return cycles_per_us;
}

static struct msm_cam_clk_info *msm_cci_get_clk(struct cci_device *cci_dev,
static uint32_t *msm_cci_get_clk_rates(struct cci_device *cci_dev,
	struct msm_camera_cci_ctrl *c_ctrl)
{
	uint32_t j;
@@ -1207,21 +1205,21 @@ static struct msm_cam_clk_info *msm_cci_get_clk(struct cci_device *cci_dev,
		"clock-names", CCI_CLK_SRC_NAME);
	if (idx < 0) {
		cci_dev->cycles_per_us = CYCLES_PER_MICRO_SEC_DEFAULT;
		return &cci_clk_info[0][0];
		return cci_dev->cci_clk_rates[0];
	}

	if (cci_clk_src == 0) {
		clk = cci_clk_info[0][idx].clk_rate;
		clk = cci_dev->cci_clk_rates[0][idx];
		cci_dev->cycles_per_us = msm_cci_cycles_per_ms(clk);
		return &cci_clk_info[0][0];
		return cci_dev->cci_clk_rates[0];
	}

	for (j = 0; j < cci_dev->num_clk_cases; j++) {
		clk = cci_clk_info[j][idx].clk_rate;
		clk = cci_dev->cci_clk_rates[j][idx];
		if (clk == cci_clk_src) {
			cci_dev->cycles_per_us = msm_cci_cycles_per_ms(clk);
			cci_dev->cci_clk_src = cci_clk_src;
			return &cci_clk_info[j][0];
			return cci_dev->cci_clk_rates[j];
		}
	}

@@ -1254,7 +1252,7 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
	int32_t rc = 0, ret = 0;
	struct cci_device *cci_dev;
	enum cci_i2c_master_t master = MASTER_0;
	struct msm_cam_clk_info *clk_info = NULL;
	uint32_t *clk_rates  = NULL;

	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev || !c_ctrl) {
@@ -1341,24 +1339,32 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
		goto reg_enable_failed;
	}

	clk_info = msm_cci_get_clk(cci_dev, c_ctrl);
	if (!clk_info) {
	clk_rates = msm_cci_get_clk_rates(cci_dev, c_ctrl);
	if (!clk_rates) {
		pr_err("%s: clk enable failed\n", __func__);
		goto reg_enable_failed;
	}

	rc = msm_cam_clk_enable(&cci_dev->pdev->dev, clk_info,
		cci_dev->cci_clk, cci_dev->num_clk, 1);
	for (i = 0; i < cci_dev->num_clk; i++) {
		cci_dev->cci_clk_info[i].clk_rate =
			clk_rates[i];
	}
	rc = msm_camera_clk_enable(&cci_dev->pdev->dev,
		cci_dev->cci_clk_info, cci_dev->cci_clk,
		cci_dev->num_clk, true);
	if (rc < 0) {
		CDBG("%s: clk enable failed\n", __func__);
		pr_err("%s: clk enable failed\n", __func__);
		goto reg_enable_failed;
	}

	/* Re-initialize the completion */
	reinit_completion(&cci_dev->cci_master_info[master].reset_complete);
	for (i = 0; i < NUM_QUEUES; i++)
		reinit_completion(&cci_dev->cci_master_info[master].
			report_q[i]);
	enable_irq(cci_dev->irq->start);
	rc = msm_camera_enable_irq(cci_dev->irq, true);
	if (rc < 0)
		pr_err("%s: irq enable failed\n", __func__);
	cci_dev->hw_version = msm_camera_io_r_mb(cci_dev->base +
		CCI_HW_VERSION_ADDR);
	pr_info("%s:%d: hw_version = 0x%x\n", __func__, __LINE__,
@@ -1436,9 +1442,9 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
	return 0;

reset_complete_failed:
	disable_irq(cci_dev->irq->start);
	msm_cam_clk_enable(&cci_dev->pdev->dev, clk_info,
		cci_dev->cci_clk, cci_dev->num_clk, 0);
	msm_camera_enable_irq(cci_dev->irq, false);
	msm_camera_clk_enable(&cci_dev->pdev->dev, cci_dev->cci_clk_info,
		cci_dev->cci_clk, cci_dev->num_clk, false);
reg_enable_failed:
	msm_camera_config_vreg(&cci_dev->pdev->dev, cci_dev->cci_vreg,
		cci_dev->regulator_count, NULL, 0, &cci_dev->cci_reg_ptr[0], 0);
@@ -1481,9 +1487,9 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd)
		if (cci_dev->write_wq[i])
			flush_workqueue(cci_dev->write_wq[i]);

	disable_irq(cci_dev->irq->start);
	msm_cam_clk_enable(&cci_dev->pdev->dev, &cci_clk_info[0][0],
		cci_dev->cci_clk, cci_dev->num_clk, 0);
	msm_camera_enable_irq(cci_dev->irq, false);
	msm_camera_clk_enable(&cci_dev->pdev->dev, cci_dev->cci_clk_info,
		cci_dev->cci_clk, cci_dev->num_clk, false);

	rc = msm_camera_enable_vreg(&cci_dev->pdev->dev, cci_dev->cci_vreg,
		cci_dev->regulator_count, NULL, 0, &cci_dev->cci_reg_ptr[0], 0);
@@ -1970,75 +1976,6 @@ struct v4l2_subdev *msm_cci_get_subdev(void)
	return g_cci_subdev;
}

static int msm_cci_get_clk_info(struct cci_device *cci_dev,
	struct platform_device *pdev)
{
	uint32_t count;
	uint32_t count_r;
	int i, j, rc;
	const uint32_t *p;
	int index = 0;

	struct device_node *of_node;
	of_node = pdev->dev.of_node;

	count = of_property_count_strings(of_node, "clock-names");
	cci_dev->num_clk = count;

	CDBG("%s: count = %d\n", __func__, count);
	if (count == 0) {
		pr_err("%s: no clocks found in device tree, count=%d",
			__func__, count);
		return 0;
	}

	if (count > CCI_NUM_CLK_MAX) {
		pr_err("%s: invalid count=%d, max is %d\n", __func__,
			count, CCI_NUM_CLK_MAX);
		return -EINVAL;
	}

	p = of_get_property(of_node, "qcom,clock-rates", &count_r);
	if (!p || !count_r) {
		pr_err("failed\n");
		return -EINVAL;
	}

	count_r /= sizeof(uint32_t);
	cci_dev->num_clk_cases = count_r/count;

	if (cci_dev->num_clk_cases > CCI_NUM_CLK_CASES) {
		pr_err("%s: invalid count=%d, max is %d\n", __func__,
			cci_dev->num_clk_cases, CCI_NUM_CLK_CASES);
		return -EINVAL;
	}

	index = 0;
	for (i = 0; i < count_r/count; i++) {
		for (j = 0; j < count; j++) {
			rc = of_property_read_string_index(of_node,
				"clock-names", j,
				&(cci_clk_info[i][j].clk_name));
			CDBG("%s: clock-names[%d][%d] = %s\n", __func__,
				i, j, cci_clk_info[i][j].clk_name);
			if (rc < 0) {
				pr_err("%s:%d, failed\n", __func__, __LINE__);
				return rc;
			}

			cci_clk_info[i][j].clk_rate =
				(be32_to_cpu(p[index]) == 0) ?
					(long)-1 : be32_to_cpu(p[index]);
			CDBG("%s: clk_rate[%d][%d] = %ld\n", __func__, i, j,
				cci_clk_info[i][j].clk_rate);
			index++;
		}
	}
	return 0;
}



static int msm_cci_probe(struct platform_device *pdev)
{
	struct cci_device *new_cci_dev;
@@ -2060,7 +1997,10 @@ static int msm_cci_probe(struct platform_device *pdev)
		of_property_read_u32((&pdev->dev)->of_node,
			"cell-index", &pdev->id);

	rc = msm_cci_get_clk_info(new_cci_dev, pdev);
	rc = msm_camera_get_clk_info_and_rates(pdev,
		&new_cci_dev->cci_clk_info, &new_cci_dev->cci_clk,
		&new_cci_dev->cci_clk_rates, &new_cci_dev->num_clk_cases,
		&new_cci_dev->num_clk);
	if (rc < 0) {
		pr_err("%s: msm_cci_get_clk_info() failed", __func__);
		kfree(new_cci_dev);
@@ -2068,15 +2008,13 @@ static int msm_cci_probe(struct platform_device *pdev)
	}

	new_cci_dev->ref_count = 0;
	new_cci_dev->mem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "cci");
	if (!new_cci_dev->mem) {
	new_cci_dev->base = msm_camera_get_reg_base(pdev, "cci", true);
	if (!new_cci_dev->base) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto cci_no_resource;
	}
	new_cci_dev->irq = platform_get_resource_byname(pdev,
					IORESOURCE_IRQ, "cci");
	new_cci_dev->irq = msm_camera_get_irq(pdev, "cci");
	CDBG("%s line %d cci irq start %d end %d\n", __func__,
		__LINE__,
		(int) new_cci_dev->irq->start,
@@ -2086,29 +2024,15 @@ static int msm_cci_probe(struct platform_device *pdev)
		rc = -ENODEV;
		goto cci_no_resource;
	}
	new_cci_dev->io = request_mem_region(new_cci_dev->mem->start,
		resource_size(new_cci_dev->mem), pdev->name);
	if (!new_cci_dev->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto cci_no_resource;
	}

	new_cci_dev->base = ioremap(new_cci_dev->mem->start,
		resource_size(new_cci_dev->mem));
	if (!new_cci_dev->base) {
		rc = -ENOMEM;
		goto cci_release_mem;
	}
	rc = request_irq(new_cci_dev->irq->start, msm_cci_irq,
		IRQF_TRIGGER_RISING, "cci", new_cci_dev);
	rc = msm_camera_register_irq(pdev, new_cci_dev->irq,
		msm_cci_irq, IRQF_TRIGGER_RISING, "cci", new_cci_dev);
	if (rc < 0) {
		pr_err("%s: irq request fail\n", __func__);
		rc = -EBUSY;
		goto cci_release_mem;
	}

	disable_irq(new_cci_dev->irq->start);
	msm_camera_enable_irq(new_cci_dev->irq, false);
	new_cci_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
	msm_sd_register(&new_cci_dev->msm_sd);
	new_cci_dev->pdev = pdev;
@@ -2150,8 +2074,7 @@ static int msm_cci_probe(struct platform_device *pdev)
cci_invalid_vreg_data:
	kfree(new_cci_dev->cci_vreg);
cci_release_mem:
	release_mem_region(new_cci_dev->mem->start,
		resource_size(new_cci_dev->mem));
	msm_camera_put_reg_base(pdev, new_cci_dev->base, "cci", true);
cci_no_resource:
	kfree(new_cci_dev);
	return rc;
@@ -2162,7 +2085,13 @@ static int msm_cci_exit(struct platform_device *pdev)
	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
	struct cci_device *cci_dev =
		v4l2_get_subdevdata(subdev);
	release_mem_region(cci_dev->mem->start, resource_size(cci_dev->mem));

	msm_camera_put_clk_info_and_rates(pdev,
		&cci_dev->cci_clk_info, &cci_dev->cci_clk,
		&cci_dev->cci_clk_rates, cci_dev->num_clk_cases,
		cci_dev->num_clk);

	msm_camera_put_reg_base(pdev, cci_dev->base, "cci", true);
	kfree(cci_dev);
	return 0;
}
+7 −7
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 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
@@ -21,6 +21,7 @@
#include <media/msm_cam_sensor.h>
#include <soc/qcom/camera2.h>
#include "msm_sd.h"
#include "cam_soc_api.h"

#define NUM_MASTERS 2
#define NUM_QUEUES 2
@@ -149,18 +150,17 @@ struct cci_device {
	struct platform_device *pdev;
	struct msm_sd_subdev msm_sd;
	struct v4l2_subdev subdev;
	struct resource *mem;
	struct resource *irq;
	struct resource *io;
	void __iomem *base;

	uint32_t hw_version;
	uint8_t ref_count;
	enum msm_cci_state_t cci_state;
	uint32_t num_clk;
	uint32_t num_clk_cases;

	struct clk *cci_clk[CCI_NUM_CLK_MAX];
	size_t num_clk;
	size_t num_clk_cases;
	struct clk **cci_clk;
	uint32_t **cci_clk_rates;
	struct msm_cam_clk_info *cci_clk_info;
	struct msm_camera_cci_i2c_queue_info
		cci_i2c_queue_info[NUM_MASTERS][NUM_QUEUES];
	struct msm_camera_cci_master_info cci_master_info[NUM_MASTERS];
+99 −255
Original line number Diff line number Diff line
@@ -66,16 +66,10 @@
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)

static struct msm_cam_clk_info csid_clk_info[CSID_NUM_CLK_MAX];
static struct msm_cam_clk_info csid_clk_src_info[CSID_NUM_CLK_MAX];

static struct camera_vreg_t csid_vreg_info[] = {
	{"qcom,mipi-csi-vdd", 0, 0, 12000},
};

static struct camera_vreg_t csid_8960_vreg_info[] = {
	{"mipi_csi_vdd", 1200000, 1200000, 20000},
};
#ifdef CONFIG_COMPAT
static struct v4l2_file_operations msm_csid_v4l2_subdev_fops;
#endif
@@ -238,16 +232,36 @@ static int msm_csid_reset(struct csid_device *csid_dev)
	return rc;
}

static bool msm_csid_find_max_clk_rate(struct csid_device *csid_dev)
{
	int i;
	bool ret = FALSE;

	for (i = 0; i < csid_dev->num_clk; i++) {
		if (!strcmp(csid_dev->csid_clk_info[i].clk_name,
			 "csi_src_clk")) {
			CDBG("%s:%d, copy csi_src_clk, clk_rate[%d] = %ld",
				__func__, __LINE__, i,
				csid_dev->csid_clk_info[i].clk_rate);
			csid_dev->csid_max_clk =
				 csid_dev->csid_clk_info[i].clk_rate;
			csid_dev->csid_clk_index = i;
			ret = TRUE;
			break;
		}
	}
	return ret;
}
static int msm_csid_config(struct csid_device *csid_dev,
	struct msm_camera_csid_params *csid_params)
{
	int rc = 0;
	uint32_t val = 0, clk_rate = 0;
	uint32_t round_rate = 0, input_sel;
	uint32_t val = 0;
	long clk_rate = 0;
	uint32_t input_sel;
	uint32_t lane_assign = 0;
	uint8_t  lane_num = 0;
	uint8_t  i, j;
	struct clk **csid_clk_ptr;
	void __iomem *csidbase;
	csidbase = csid_dev->base;
	if (!csidbase || !csid_params) {
@@ -270,25 +284,17 @@ static int msm_csid_config(struct csid_device *csid_dev,
		return rc;
	}

	csid_clk_ptr = csid_dev->csid_clk;
	if (!csid_clk_ptr) {
		pr_err("csi_src_clk get failed\n");
		return -EINVAL;
	}
	if (!msm_csid_find_max_clk_rate(csid_dev))
		pr_err("msm_csid_find_max_clk_rate failed\n");

	clk_rate = (csid_params->csi_clk > 0) ?
				(csid_params->csi_clk) : csid_dev->csid_max_clk;
	round_rate = clk_round_rate(csid_clk_ptr[csid_dev->csid_clk_index],
					clk_rate);
	if (round_rate > csid_dev->csid_max_clk)
		round_rate = csid_dev->csid_max_clk;
	pr_debug("usr set rate csi_clk clk_rate = %u round_rate = %u\n",
					clk_rate, round_rate);
	rc = clk_set_rate(csid_clk_ptr[csid_dev->csid_clk_index],
				round_rate);
	if (rc < 0) {

	clk_rate = msm_camera_clk_set_rate(&csid_dev->pdev->dev,
		csid_dev->csid_clk[csid_dev->csid_clk_index], clk_rate);
	if (clk_rate < 0) {
		pr_err("csi_src_clk set failed\n");
		return rc;
		return -EINVAL;
	}

	if (csid_dev->is_testmode == 1) {
@@ -489,14 +495,6 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
		return rc;
	}

	csid_dev->base = ioremap(csid_dev->mem->start,
		resource_size(csid_dev->mem));
	if (!csid_dev->base) {
		pr_err("%s csid_dev->base NULL\n", __func__);
		rc = -ENOMEM;
		goto ioremap_fail;
	}

	pr_info("%s: CSID_VERSION = 0x%x\n", __func__,
		csid_dev->ctrl_reg->csid_reg.csid_version);
	/* power up */
@@ -508,15 +506,9 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
		goto top_vreg_config_failed;
	}

	if (csid_dev->ctrl_reg->csid_reg.csid_version < CSID_VERSION_V22) {
		rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 1);
	} else {
	rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
		csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
		NULL, 0, &csid_dev->csi_vdd, 1);
	}
	if (rc < 0) {
		pr_err("%s: regulator on failed\n", __func__);
		goto csid_vreg_config_failed;
@@ -530,28 +522,16 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
		goto top_vreg_enable_failed;
	}

	if (csid_dev->ctrl_reg->csid_reg.csid_version < CSID_VERSION_V22) {
		rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 1);
	} else {
	rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
		csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
		NULL, 0, &csid_dev->csi_vdd, 1);
	}
	if (rc < 0) {
		pr_err("%s: regulator enable failed\n", __func__);
		goto csid_vreg_enable_failed;
	}

	if (csid_dev->ctrl_reg->csid_reg.csid_version == CSID_VERSION_V22)
		msm_cam_clk_sel_src(&csid_dev->pdev->dev,
			&csid_clk_info[3], csid_clk_src_info,
			csid_dev->num_clk_src_info);

	rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
			csid_clk_info, csid_dev->csid_clk,
			csid_dev->num_clk, 1);
	rc = msm_camera_clk_enable(&csid_dev->pdev->dev,
		csid_dev->csid_clk_info, csid_dev->csid_clk,
		csid_dev->num_clk, true);
	if (rc < 0) {
		pr_err("%s:%d clock enable failed\n",
			 __func__, __LINE__);
@@ -570,8 +550,9 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)

	init_completion(&csid_dev->reset_complete);

	enable_irq(csid_dev->irq->start);

	rc = msm_camera_enable_irq(csid_dev->irq, true);
	if (rc < 0)
		pr_err("%s: irq enable failed\n", __func__);
	rc = msm_csid_reset(csid_dev);
	if (rc < 0) {
		pr_err("%s:%d msm_csid_reset failed\n", __func__, __LINE__);
@@ -582,41 +563,26 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
	return rc;

msm_csid_reset_fail:
	disable_irq(csid_dev->irq->start);
	msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
		csid_dev->csid_clk, csid_dev->num_clk, 0);
	msm_camera_enable_irq(csid_dev->irq, false);
	msm_camera_clk_enable(&csid_dev->pdev->dev, csid_dev->csid_clk_info,
		csid_dev->csid_clk, csid_dev->num_clk, false);
clk_enable_failed:
	if (csid_dev->ctrl_reg->csid_reg.csid_version < CSID_VERSION_V22) {
		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else {
	msm_camera_enable_vreg(&csid_dev->pdev->dev,
		csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
		NULL, 0, &csid_dev->csi_vdd, 0);
	}
csid_vreg_enable_failed:
	msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_dev->csid_vreg,
		csid_dev->regulator_count, NULL, 0,
		&csid_dev->csid_reg_ptr[0], 0);
top_vreg_enable_failed:
	if (csid_dev->ctrl_reg->csid_reg.csid_version < CSID_VERSION_V22) {
		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else {
	msm_camera_config_vreg(&csid_dev->pdev->dev,
		csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
		NULL, 0, &csid_dev->csi_vdd, 0);
	}
csid_vreg_config_failed:
	msm_camera_config_vreg(&csid_dev->pdev->dev, csid_dev->csid_vreg,
		csid_dev->regulator_count, NULL, 0,
		&csid_dev->csid_reg_ptr[0], 0);
top_vreg_config_failed:
	iounmap(csid_dev->base);
	csid_dev->base = NULL;
ioremap_fail:
	if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
		CAM_AHB_SUSPEND_VOTE) < 0)
		pr_err("%s: failed to remove vote from AHB\n", __func__);
@@ -643,24 +609,12 @@ static int msm_csid_release(struct csid_device *csid_dev)
	msm_camera_io_w(0, csid_dev->base +
		csid_dev->ctrl_reg->csid_reg.csid_irq_mask_addr);

	disable_irq(csid_dev->irq->start);
	msm_camera_enable_irq(csid_dev->irq, false);

	if (csid_dev->hw_version == CSID_VERSION_V20) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
			csid_dev->csid_clk, csid_dev->num_clk, 0);

		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else {
		msm_cam_clk_enable(&csid_dev->pdev->dev,
			csid_clk_info,
	msm_camera_clk_enable(&csid_dev->pdev->dev,
		csid_dev->csid_clk_info,
		csid_dev->csid_clk,
			csid_dev->num_clk, 0);
		csid_dev->num_clk, false);

	msm_camera_enable_vreg(&csid_dev->pdev->dev,
		csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
@@ -677,15 +631,12 @@ static int msm_csid_release(struct csid_device *csid_dev)
	msm_camera_config_vreg(&csid_dev->pdev->dev,
		csid_dev->csid_vreg, csid_dev->regulator_count, NULL,
		0, &csid_dev->csid_reg_ptr[0], 0);
	}

	if (!IS_ERR_OR_NULL(csid_dev->reg_ptr)) {
		regulator_disable(csid_dev->reg_ptr);
		regulator_put(csid_dev->reg_ptr);
	}

	iounmap(csid_dev->base);
	csid_dev->base = NULL;
	csid_dev->csid_state = CSID_POWER_DOWN;

	if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
@@ -1011,116 +962,6 @@ static const struct v4l2_subdev_ops msm_csid_subdev_ops = {
	.core = &msm_csid_subdev_core_ops,
};

static int msm_csid_get_clk_info(struct csid_device *csid_dev,
	struct platform_device *pdev)
{
	uint32_t count;
	uint32_t cnt = 0;
	int i, rc;
	int ii = 0;
	uint32_t rates[CSID_NUM_CLK_MAX];
	const char *clock_name;
	struct device_node *of_node;
	of_node = pdev->dev.of_node;

	count = of_property_count_strings(of_node, "clock-names");
	csid_dev->num_clk = count;

	CDBG("%s: count = %d\n", __func__, count);
	if (count == 0) {
		pr_err("%s: no clocks found in device tree, count=%d",
			__func__, count);
		return -EINVAL;
	}

	if (count > CSID_NUM_CLK_MAX) {
		pr_err("%s: invalid count=%d, max is %d\n", __func__,
			count, CSID_NUM_CLK_MAX);
		return -EINVAL;
	}

	if (csid_dev->hw_dts_version == CSID_VERSION_V22) {
		cnt = count;
		count = 0;

		for (i = 0; i < cnt; i++) {
			count++;
			rc = of_property_read_string_index(of_node,
				"clock-names", i, &clock_name);
			CDBG("%s: clock_names[%d] = %s\n", __func__,
				i, clock_name);
			if (rc < 0) {
				pr_err("%s:%d, failed\n", __func__, __LINE__);
				return rc;
			}
			if (strcmp(clock_name, "csi_phy_src_clk") == 0)
				break;
		}
		csid_dev->num_clk = count;
	}

	for (i = 0; i < count; i++) {
		rc = of_property_read_string_index(of_node, "clock-names",
				i, &(csid_clk_info[i].clk_name));
		CDBG("%s: clock-names[%d] = %s\n", __func__,
			i, csid_clk_info[i].clk_name);
		if (rc < 0) {
			pr_err("%s:%d, failed\n", __func__, __LINE__);
			return rc;
		}
	}
	rc = of_property_read_u32_array(of_node, "qcom,clock-rates",
		rates, count);
	if (rc < 0) {
		pr_err("%s:%d, failed", __func__, __LINE__);
		return rc;
	}
	for (i = 0; i < count; i++) {
		csid_clk_info[i].clk_rate = (rates[i] == 0) ?
			(long)-1 : rates[i];
		if (!strcmp(csid_clk_info[i].clk_name, "csi_src_clk")) {
			CDBG("%s:%d, copy csi_src_clk",
				__func__, __LINE__);
			csid_dev->csid_max_clk = rates[i];
			csid_dev->csid_clk_index = i;
		}
		CDBG("%s: clk_rate[%d] = %ld\n", __func__, i,
			csid_clk_info[i].clk_rate);
	}

	if (csid_dev->hw_dts_version == CSID_VERSION_V22) {
		csid_dev->num_clk_src_info = cnt - count;
		CDBG("%s: count = %d\n", __func__, (cnt - count));

		for (i = count; i < cnt; i++) {
			ii++;
			rc = of_property_read_string_index(of_node,
				"clock-names", i,
				&(csid_clk_src_info[ii].clk_name));
			CDBG("%s: clock-names[%d] = %s\n", __func__,
				ii, csid_clk_src_info[ii].clk_name);
			if (rc < 0) {
				pr_err("%s:%d, failed\n", __func__, __LINE__);
				return rc;
			}
		}
		ii = 0;
		rc = of_property_read_u32_array(of_node, "qcom,clock-rates",
			rates, cnt);
		if (rc < 0) {
			pr_err("%s:%d, failed", __func__, __LINE__);
			return rc;
		}
		for (i = count; i < cnt; i++) {
			ii++;
			csid_clk_src_info[ii].clk_rate = rates[i];
			CDBG("%s: clk_rate[%d] = %ld\n", __func__, ii,
			csid_clk_src_info[ii].clk_rate);
		}
	}
	return 0;
}

static int csid_probe(struct platform_device *pdev)
{
	struct csid_device *new_csid_dev;
@@ -1171,9 +1012,10 @@ static int csid_probe(struct platform_device *pdev)
		csid_vreg_info[0].max_voltage = csi_vdd_voltage;
	}

	rc = msm_csid_get_clk_info(new_csid_dev, pdev);
	rc = msm_camera_get_clk_info(pdev, &new_csid_dev->csid_clk_info,
		&new_csid_dev->csid_clk, &new_csid_dev->num_clk);
	if (rc < 0) {
		pr_err("%s: msm_csid_get_clk_info() failed", __func__);
		pr_err("%s: msm_camera_get_clk_info failed", __func__);
		rc = -EFAULT;
		goto csid_no_resource;
	}
@@ -1194,28 +1036,18 @@ static int csid_probe(struct platform_device *pdev)
		goto csid_no_resource;
	}

	new_csid_dev->mem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "csid");
	if (!new_csid_dev->mem) {
	new_csid_dev->base = msm_camera_get_reg_base(pdev, "csid", true);
	if (!new_csid_dev->base) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto csid_invalid_vreg_data;
	}
	new_csid_dev->irq = platform_get_resource_byname(pdev,
					IORESOURCE_IRQ, "csid");
	new_csid_dev->irq = msm_camera_get_irq(pdev, "csid");
	if (!new_csid_dev->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto csid_invalid_vreg_data;
	}
	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
		resource_size(new_csid_dev->mem), pdev->name);
	if (!new_csid_dev->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto csid_invalid_vreg_data;
		goto csid_invalid_irq;
	}

	new_csid_dev->pdev = pdev;
	new_csid_dev->msm_sd.sd.internal_ops = &msm_csid_internal_ops;
	new_csid_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1233,22 +1065,18 @@ static int csid_probe(struct platform_device *pdev)
	new_csid_dev->msm_sd.sd.devnode->fops = &msm_csid_v4l2_subdev_fops;
#endif

	rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
		IRQF_TRIGGER_RISING, "csid", new_csid_dev);
	rc = msm_camera_register_irq(pdev, new_csid_dev->irq,
		msm_csid_irq, IRQF_TRIGGER_RISING, "csid", new_csid_dev);
	if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s: irq request fail\n", __func__);
		rc = -EBUSY;
		goto csid_invalid_vreg_data;
		goto csid_invalid_irq;
	}
	disable_irq(new_csid_dev->irq->start);
	rc = msm_camera_enable_irq(new_csid_dev->irq, false);
	if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s Error registering irq ", __func__);
		rc = -EBUSY;
		goto csid_invalid_vreg_data;
		goto csid_invalid_irq;
	}

	if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
@@ -1327,12 +1155,14 @@ static int csid_probe(struct platform_device *pdev)
		pr_err("%s:%d, invalid hw version : 0x%x", __func__, __LINE__,
			new_csid_dev->hw_dts_version);
		rc = -EINVAL;
		goto csid_invalid_vreg_data;
		goto csid_invalid_irq;
	}

	new_csid_dev->csid_state = CSID_POWER_DOWN;
	return 0;

csid_invalid_irq:
	msm_camera_put_reg_base(pdev, new_csid_dev->base, "csid", true);
csid_invalid_vreg_data:
	kfree(new_csid_dev->csid_vreg);
csid_no_resource:
@@ -1342,6 +1172,19 @@ csid_no_resource:
	return rc;
}

static int msm_csid_exit(struct platform_device *pdev)
{
	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
	struct csid_device *csid_dev =
		v4l2_get_subdevdata(subdev);

	msm_camera_put_clk_info(pdev, &csid_dev->csid_clk_info,
		&csid_dev->csid_clk, csid_dev->num_clk);
	msm_camera_put_reg_base(pdev, csid_dev->base, "csid", true);
	kfree(csid_dev);
	return 0;
}

static const struct of_device_id msm_csid_dt_match[] = {
	{.compatible = "qcom,csid"},
	{}
@@ -1351,6 +1194,7 @@ MODULE_DEVICE_TABLE(of, msm_csid_dt_match);

static struct platform_driver csid_driver = {
	.probe = csid_probe,
	.remove = msm_csid_exit,
	.driver = {
		.name = MSM_CSID_DRV_NAME,
		.owner = THIS_MODULE,
+4 −7
Original line number Diff line number Diff line
@@ -19,8 +19,7 @@
#include <media/v4l2-subdev.h>
#include <media/msm_cam_sensor.h>
#include "msm_sd.h"

#define CSID_NUM_CLK_MAX  16
#include "cam_soc_api.h"

enum csiphy_lane_assign {
	PHY_LANE_D0,
@@ -89,9 +88,7 @@ enum msm_csid_state_t {
struct csid_device {
	struct platform_device *pdev;
	struct msm_sd_subdev msm_sd;
	struct resource *mem;
	struct resource *irq;
	struct resource *io;
	struct regulator *csi_vdd;
	void __iomem *base;
	struct mutex mutex;
@@ -100,10 +97,10 @@ struct csid_device {
	uint32_t hw_dts_version;
	enum msm_csid_state_t csid_state;
	struct csid_ctrl_t *ctrl_reg;
	uint32_t num_clk;
	uint32_t num_clk_src_info;
	struct regulator *reg_ptr;
	struct clk *csid_clk[CSID_NUM_CLK_MAX];
	size_t num_clk;
	struct clk **csid_clk;
	struct msm_cam_clk_info *csid_clk_info;
	uint32_t csid_clk_index;
	uint32_t csid_max_clk;
	uint32_t csid_3p_enabled;
+158 −255

File changed.

Preview size limit exceeded, changes collapsed.

Loading