Пример #1
0
static int ispif_probe(struct platform_device *pdev)
{
	int rc;
	struct ispif_device *ispif;

	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
	if (!ispif) {
		pr_err("%s: no enough memory\n", __func__);
		return -ENOMEM;
	}

	if (pdev->dev.of_node) {
		of_property_read_u32((&pdev->dev)->of_node,
		"cell-index", &pdev->id);
		rc = of_property_read_u32((&pdev->dev)->of_node,
		"qcom,num-isps", &ispif->hw_num_isps);
		if (rc)
			/* backward compatibility */
			ispif->hw_num_isps = 1;
		/* not an error condition */
		rc = 0;
	}

	rc = msm_ispif_get_clk_info(ispif, pdev,
		ispif_ahb_clk_info, ispif_clk_info);
	if (rc < 0) {
		pr_err("%s: msm_isp_get_clk_info() failed", __func__);
			return -EFAULT;
	}

	mutex_init(&ispif->mutex);
	ispif->mem = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "ispif");
	if (!ispif->mem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto error;
	}
	ispif->irq = platform_get_resource_byname(pdev,
		IORESOURCE_IRQ, "ispif");
	if (!ispif->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto error;
	}
	ispif->io = request_mem_region(ispif->mem->start,
		resource_size(ispif->mem), pdev->name);
	if (!ispif->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto error;
	}
	ispif->clk_mux_mem = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "csi_clk_mux");
	if (ispif->clk_mux_mem) {
		ispif->clk_mux_io = request_mem_region(
			ispif->clk_mux_mem->start,
			resource_size(ispif->clk_mux_mem),
			ispif->clk_mux_mem->name);
		if (!ispif->clk_mux_io)
			pr_err("%s: no valid csi_mux region\n", __func__);
	}

	v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops);
	ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops;
	ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	snprintf(ispif->msm_sd.sd.name,
		ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME);
	v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif);

	platform_set_drvdata(pdev, &ispif->msm_sd.sd);

	media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0);
	ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF;
	ispif->msm_sd.sd.entity.name = pdev->name;
	ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1;
	rc = msm_sd_register(&ispif->msm_sd);
	if (rc) {
		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
		goto error;
	}
	msm_ispif_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
	msm_ispif_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
	msm_ispif_v4l2_subdev_fops.unlocked_ioctl = msm_ispif_subdev_fops_ioctl;
	msm_ispif_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
	msm_ispif_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
#ifdef CONFIG_COMPAT
	msm_ispif_v4l2_subdev_fops.compat_ioctl32 = msm_ispif_subdev_fops_ioctl;
#endif
	ispif->msm_sd.sd.devnode->fops = &msm_ispif_v4l2_subdev_fops;
	ispif->pdev = pdev;
	ispif->ispif_state = ISPIF_POWER_DOWN;
	ispif->open_cnt = 0;
	return 0;

error:
	mutex_destroy(&ispif->mutex);
	kfree(ispif);
	return rc;
}
Пример #2
0
static int msm_ispif_reset_hw(struct ispif_device *ispif)
{
	int rc = 0;
	long timeout = 0;
	struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)];
	ispif->clk_idx = 0;

	rc = msm_ispif_get_clk_info(ispif, ispif->pdev,
		ispif_ahb_clk_info, ispif_clk_info);
	if (rc < 0) {
		pr_err("%s: msm_isp_get_clk_info() failed", __func__);
			return -EFAULT;
	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
		ispif->num_clk, 1);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d\n",
			__func__, rc);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 1);
		if (rc < 0) {
			pr_err("%s: cannot enable clock, error = %d",
				__func__, rc);
		} else {
			/* This is set when device is 8x26 */
			ispif->clk_idx = 2;
		}
	} else {
		/* This is set when device is 8974 */
		ispif->clk_idx = 1;
	}

	init_completion(&ispif->reset_complete[VFE0]);
	if (ispif->hw_num_isps > 1)
		init_completion(&ispif->reset_complete[VFE1]);

	/* initiate reset of ISPIF */
	msm_camera_io_w(ISPIF_RST_CMD_MASK,
				ispif->base + ISPIF_RST_CMD_ADDR);


	timeout = wait_for_completion_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
	CDBG("%s: VFE0 done\n", __func__);

	if (timeout <= 0) {
		pr_err("%s: VFE0 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
		if (rc < 0) {
			rc = msm_cam_clk_enable(&ispif->pdev->dev,
				ispif_8626_reset_clk_info, reset_clk1,
				ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
			if (rc < 0)
				pr_err("%s: VFE0 reset wait timeout\n",
					 __func__);
		}
		return -ETIMEDOUT;
	}

	if (ispif->hw_num_isps > 1) {
		msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
					ispif->base + ISPIF_RST_CMD_1_ADDR);
		timeout = wait_for_completion_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		CDBG("%s: VFE1 done\n", __func__);
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
			return -ETIMEDOUT;
		}
	}

	if (ispif->clk_idx == 1) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	if (ispif->clk_idx == 2) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	return rc;
}
Пример #3
0
static int msm_ispif_reset_hw(struct ispif_device *ispif, int release)
{
	int rc = 0, i;
	long timeout = 0;
	struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)];
	ispif->clk_idx = 0;

	rc = msm_ispif_get_clk_info(ispif, ispif->pdev,
		ispif_ahb_clk_info, ispif_clk_info);
	if (rc < 0) {
		pr_err("%s: msm_isp_get_clk_info() failed", __func__);
		return -EFAULT;
	}

	/* Turn ON regulators before enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 1);
	if (rc < 0) {
		pr_err("%s: ispif enable regulator failed", __func__);
			return -EFAULT;
	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
		ispif->num_clk, 1);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d\n",
			__func__, rc);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 1);
		if (rc < 0) {
			pr_err("%s: cannot enable clock, error = %d",
				__func__, rc);
		} else {
			/* This is set when device is 8x26 */
			ispif->clk_idx = 2;
		}
	} else {
		/* This is set when device is 8974 */
		ispif->clk_idx = 1;
	}

	if (release) {
		for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
			msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY,
				ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
			msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY,
				ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
		}
		msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD,
			ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
	}
	init_completion(&ispif->reset_complete[VFE0]);
	if (ispif->hw_num_isps > 1)
		init_completion(&ispif->reset_complete[VFE1]);

	/* initiate reset of ISPIF */
	msm_camera_io_w(ISPIF_RST_CMD_MASK,
				ispif->base + ISPIF_RST_CMD_ADDR);


	timeout = wait_for_completion_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
	CDBG("%s: VFE0 done\n", __func__);

	if (timeout <= 0) {
		pr_err("%s: VFE0 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
		if (rc < 0) {
			rc = msm_cam_clk_enable(&ispif->pdev->dev,
				ispif_8626_reset_clk_info, reset_clk1,
				ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
			if (rc < 0)
				pr_err("%s: VFE0 reset wait timeout\n",
					__func__);
		}
		/* Turn OFF regulators */
		rc = msm_ispif_set_regulator(ispif, 0);
		return -ETIMEDOUT;
	}

	if (ispif->hw_num_isps > 1) {
		msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
					ispif->base + ISPIF_RST_CMD_1_ADDR);
		timeout = wait_for_completion_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		CDBG("%s: VFE1 done\n", __func__);
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
			/* Turn OFF regulators */
			rc = msm_ispif_set_regulator(ispif, 0);
			return -ETIMEDOUT;
		}
	}

	if (ispif->clk_idx == 1) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	if (ispif->clk_idx == 2) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	/* Turn OFF regulators after enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 0);
	if (rc < 0) {
		pr_err("%s: ispif disable regulator failed", __func__);
			return -EFAULT;
	}

	return rc;
}