Esempio n. 1
0
int tvenc_set_clock(boolean clock_on)
{
	int ret = 0;
	if (clock_on) {
		if (tvenc_pdata->poll) {
			ret = tvenc_set_encoder_clock(CLOCK_ON);
			if (ret) {
				pr_err("%s: TVenc clock(s) enable failed! %d\n",
					__func__, ret);
				goto tvenc_err;
			}
		}
		ret = clk_enable(tvdac_clk);
		if (ret) {
			pr_err("%s: tvdac_clk enable failed! %d\n",
				__func__, ret);
			goto tvdac_err;
		}
		if (!IS_ERR(mdp_tv_clk)) {
			ret = clk_enable(mdp_tv_clk);
			if (ret) {
				pr_err("%s: mdp_tv_clk enable failed! %d\n",
					__func__, ret);
				goto mdptv_err;
			}
		}
		return ret;
	} else {
		if (!IS_ERR(mdp_tv_clk))
			clk_disable(mdp_tv_clk);
		clk_disable(tvdac_clk);
		if (tvenc_pdata->poll)
			tvenc_set_encoder_clock(CLOCK_OFF);
		return ret;
	}

mdptv_err:
	clk_disable(tvdac_clk);
tvdac_err:
	tvenc_set_encoder_clock(CLOCK_OFF);
tvenc_err:
	return ret;
}
static int tvout_device_pm_suspend(struct device *dev)
{
	mutex_lock(&tvout_msm_state_mutex);
	if (tvout_msm_state->pm_suspended) {
		mutex_unlock(&tvout_msm_state_mutex);
		return 0;
	}
	if (tvenc_pdata->poll) {
		if (del_timer(&tvout_msm_state->hpd_work_timer))
			DEV_DBG("%s: suspending cable detect timer\n",
				__func__);
	} else {
		disable_irq(tvout_msm_state->irq);
		tvenc_set_encoder_clock(CLOCK_OFF);
	}
	tvout_msm_state->pm_suspended = TRUE;
	mutex_unlock(&tvout_msm_state_mutex);
	return 0;
}
static int tvout_device_pm_resume(struct device *dev)
{
	mutex_lock(&tvout_msm_state_mutex);
	if (!tvout_msm_state->pm_suspended) {
		mutex_unlock(&tvout_msm_state_mutex);
		return 0;
	}

	if (tvenc_pdata->poll) {
		tvout_msm_state->pm_suspended = FALSE;
		mod_timer(&tvout_msm_state->hpd_work_timer, jiffies
				+ msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE));
		mutex_unlock(&tvout_msm_state_mutex);
		DEV_DBG("%s: resuming cable detect timer\n", __func__);
	} else {
		tvenc_set_encoder_clock(CLOCK_ON);
		tvout_msm_state->pm_suspended = FALSE;
		mutex_unlock(&tvout_msm_state_mutex);
		enable_irq(tvout_msm_state->irq);
		DEV_DBG("%s: enable cable detect interrupt\n", __func__);
	}
	return 0;
}
static int __devinit tvout_probe(struct platform_device *pdev)
{
	int rc = 0;
	uint32 reg;
	struct platform_device *fb_dev;

#ifdef CONFIG_FB_MSM_TVOUT_NTSC_M
	external_common_state->video_resolution = NTSC_M;
#elif defined CONFIG_FB_MSM_TVOUT_NTSC_J
	external_common_state->video_resolution = NTSC_J;
#elif defined CONFIG_FB_MSM_TVOUT_PAL_M
	external_common_state->video_resolution = PAL_M;
#elif defined CONFIG_FB_MSM_TVOUT_PAL_N
	external_common_state->video_resolution = PAL_N;
#elif defined CONFIG_FB_MSM_TVOUT_PAL_BDGHIN
	external_common_state->video_resolution = PAL_BDGHIN;
#endif
	external_common_state->dev = &pdev->dev;
	if (pdev->id == 0) {
		struct resource *res;

		#define GET_RES(name, mode) do {			\
			res = platform_get_resource_byname(pdev, mode, name); \
			if (!res) {					\
				DEV_DBG("'" name "' resource not found\n"); \
				rc = -ENODEV;				\
				goto error;				\
			}						\
		} while (0)

		#define GET_IRQ(var, name) do {				\
			GET_RES(name, IORESOURCE_IRQ);			\
			var = res->start;				\
		} while (0)

		GET_IRQ(tvout_msm_state->irq, "tvout_device_irq");
		#undef GET_IRQ
		#undef GET_RES
		return 0;
	}

	DEV_DBG("%s: tvout_msm_state->irq : %d",
			__func__, tvout_msm_state->irq);

	rc = request_irq(tvout_msm_state->irq, &tvout_msm_isr,
		IRQF_TRIGGER_HIGH, "tvout_msm_isr", NULL);

	if (rc) {
		DEV_DBG("Init FAILED: IRQ request, rc=%d\n", rc);
		goto error;
	}
	disable_irq(tvout_msm_state->irq);

	init_timer(&tvout_msm_state->hpd_state_timer);
	tvout_msm_state->hpd_state_timer.function =
		tvout_msm_hpd_state_timer;
	tvout_msm_state->hpd_state_timer.data = (uint32)NULL;
	tvout_msm_state->hpd_state_timer.expires = jiffies
						+ msecs_to_jiffies(1000);

	if (tvenc_pdata->poll) {
		init_timer(&tvout_msm_state->hpd_work_timer);
		tvout_msm_state->hpd_work_timer.function =
			tvout_msm_hpd_work_timer;
		tvout_msm_state->hpd_work_timer.data = (uint32)NULL;
		tvout_msm_state->hpd_work_timer.expires = jiffies
						+ msecs_to_jiffies(1000);
	}
	fb_dev = msm_fb_add_device(pdev);
	if (fb_dev) {
		rc = external_common_state_create(fb_dev);
		if (rc) {
			DEV_ERR("Init FAILED: tvout_msm_state_create, rc=%d\n",
				rc);
			goto error;
		}
		if (tvenc_pdata->poll) {
			/* Start polling timer to detect load */
			mod_timer(&tvout_msm_state->hpd_work_timer, jiffies
				+ msecs_to_jiffies(TVOUT_HPD_DUTY_CYCLE));
		} else {
			/* Enable interrupt to detect load */
			tvenc_set_encoder_clock(CLOCK_ON);
			reg = TV_IN(TV_DAC_INTF);
			reg |= TVENC_LOAD_DETECT_EN;
			TV_OUT(TV_DAC_INTF, reg);
			TV_OUT(TV_INTR_ENABLE, 0x5);
			enable_irq(tvout_msm_state->irq);
		}
	} else
		DEV_ERR("Init FAILED: failed to add fb device\n");
error:
	return 0;
}