Exemple #1
0
static int hdmi_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_hdmi_platdata *pdata = pdev->dev.platform_data;
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	int ret = 0;

	dev_dbg(dev, "%s start\n", __func__);

	/* HDMI PHY power off
	 * HDMI PHY is on as default configuration
	 * So, HDMI PHY must be turned off if it's not used */
	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 1);

	ret = v4l2_subdev_call(hdev->phy_sd, core, s_power, 0);
	if (ret)
		dev_err(dev, "failed to turn off hdmiphy\n");

	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 0);

	return ret;
}
static int hdmi_s_power(struct v4l2_subdev *sd, int on)
{
    struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
    int ret = 0;

    /* If runtime PM is not implemented, hdmi_runtime_resume
     * and hdmi_runtime_suspend functions are directly called.
     */
    if (on) {
#ifdef CONFIG_PM_RUNTIME
        ret = pm_runtime_get_sync(hdev->dev);
#else
        hdmi_runtime_resume(hdev->dev);
#endif
    } else {
#ifdef CONFIG_PM_RUNTIME
        ret = pm_runtime_put_sync(hdev->dev);
#else
        hdmi_runtime_suspend(hdev->dev);
#endif
    }

    /* only values < 0 indicate errors */
    return IS_ERR_VALUE(ret) ? ret : 0;
}
Exemple #3
0
int hdmi_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;

	switch (ctrl->id) {
	case V4L2_CID_TV_GET_DVI_MODE:
		ctrl->value = hdev->dvi_mode;
		break;
	case V4L2_CID_TV_HPD_STATUS:
		ctrl->value = switch_get_state(&hdev->hpd_switch);
		break;
	case V4L2_CID_TV_HDMI_STATUS:
		ctrl->value = (hdev->streaming |
				switch_get_state(&hdev->hpd_switch));
		break;
	case V4L2_CID_TV_MAX_AUDIO_CHANNELS:
		ctrl->value = edid_max_audio_channels(hdev);
		break;
	case V4L2_CID_TV_SOURCE_PHY_ADDR:
		ctrl->value = edid_source_phy_addr(hdev);
		break;
	default:
		dev_err(dev, "invalid control id\n");
		return -EINVAL;
	}

	return 0;
}
Exemple #4
0
static int hdmi_runtime_resume(struct device *dev)
{
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct hdmi_resources *res = &hdev->res;
	int ret = 0;

	dev_dbg(dev, "%s\n", __func__);

	hdmi_resource_poweron(&hdev->res);

	hdmi_phy_sw_reset(hdev);
	ret = v4l2_subdev_call(hdev->phy_sd, core, s_power, 1);
	if (ret) {
		dev_err(dev, "failed to turn on hdmiphy\n");
		goto fail;
	}

	ret = hdmi_conf_apply(hdev);
	if (ret)
		goto fail;

	dev_dbg(dev, "poweron succeed\n");

	return 0;

fail:
	clk_disable(res->sclk_hdmi);
	v4l2_subdev_call(hdev->phy_sd, core, s_power, 0);
	clk_disable(res->hdmiphy);
	dev_err(dev, "poweron failed\n");

	return ret;
}
Exemple #5
0
static int hdmi_g_dv_preset(struct v4l2_subdev *sd,
	struct v4l2_dv_preset *preset)
{
	memset(preset, 0, sizeof(*preset));
	preset->preset = sd_to_hdmi_dev(sd)->cur_preset;
	return 0;
}
Exemple #6
0
static int hdmi_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_hdmi_platdata *pdata = pdev->dev.platform_data;
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct hdmi_resources *res = &hdev->res;

	dev_dbg(dev, "%s\n", __func__);

	if (hdev->probe_state == HDMI_PROBING) {
		hdev->probe_state = HDMI_PROBED;
		return 0;
	}

	/* HDMI PHY off sequence
	 * LINK off -> PHY off -> HDMI_PHY_CONTROL disable */

	if (is_ip_ver_5a || is_ip_ver_5s)
		hdmiphy_set_power(hdev, 0);

	/* turn clocks off */
	clk_disable(res->sclk_hdmi);

	if (is_ip_ver_5g)
		v4l2_subdev_call(hdev->phy_sd, core, s_power, 0);

	/* power-off hdmiphy */
	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 0);

	return 0;
}
Exemple #7
0
static int hdmi_s_power(struct v4l2_subdev *sd, int on)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);

	/* If runtime PM is not implemented, hdmi_runtime_resume
	 * and hdmi_runtime_suspend functions are directly called.
	 */
#ifdef CONFIG_PM_RUNTIME
	int ret;

	if (on) {
		clk_enable(hdev->res.hdmi);
		hdmi_hpd_enable(hdev, 1);
		ret = pm_runtime_get_sync(hdev->dev);
		set_internal_hpd_int(hdev);
	} else {
		hdmi_hpd_enable(hdev, 0);
		set_external_hpd_int(hdev);
		ret = pm_runtime_put_sync(hdev->dev);
		clk_disable(hdev->res.hdmi);
	}
	/* only values < 0 indicate errors */
	return IS_ERR_VALUE(ret) ? ret : 0;
#else
	if (on)
		hdmi_runtime_resume(hdev->dev);
	else
		hdmi_runtime_suspend(hdev->dev);
	return 0;
#endif
}
Exemple #8
0
int hdmi_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;

	dev_info(dev, "S_CTRL is not applied yet.\n");

	return 0;
}
int hdmi_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
    struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
    struct device *dev = hdev->dev;
    int ret = 0;

    dev_dbg(dev, "%s start\n", __func__);

    switch (ctrl->id) {
    case V4L2_CID_TV_SET_DVI_MODE:
        hdev->dvi_mode = ctrl->value;
        break;
    case V4L2_CID_TV_SET_ASPECT_RATIO:
        hdev->aspect = ctrl->value;
        break;
    case V4L2_CID_TV_ENABLE_HDMI_AUDIO:
        mutex_lock(&hdev->mutex);
        hdev->audio_enable = !!ctrl->value;
        if (is_hdmi_streaming(hdev)) {
            hdmi_set_infoframe(hdev);
            hdmi_audio_enable(hdev, hdev->audio_enable);
        }
        mutex_unlock(&hdev->mutex);
        break;
    case V4L2_CID_TV_SET_NUM_CHANNELS:
        mutex_lock(&hdev->mutex);
        hdmi_audio_information(hdev, ctrl->value);
        if (is_hdmi_streaming(hdev)) {
            hdmi_audio_enable(hdev, 0);
            hdmi_set_infoframe(hdev);
            hdmi_reg_i2s_audio_init(hdev);
            hdmi_audio_enable(hdev, 1);
        }
        mutex_unlock(&hdev->mutex);
        break;
    case V4L2_CID_TV_SET_COLOR_RANGE:
        hdev->color_range = ctrl->value;
        break;
    case V4L2_CID_TV_HDCP_ENABLE:
        hdev->hdcp_info.hdcp_enable = ctrl->value;
        dev_dbg(hdev->dev, "HDCP %s\n",
                ctrl->value ? "enable" : "disable");
#ifdef CONFIG_SEC_MHL_HDCP
        hdev->hdcp_info.hdcp_enable = false;
        /*MHL8240 control the HDCP*/
        dev_dbg(hdev->dev, "MHL control the HDCP\n");
#endif
        break;
    default:
        dev_err(dev, "invalid control id\n");
        ret = -EINVAL;
        break;
    }

    return ret;
}
Exemple #10
0
static int hdmi_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;

	//dev_dbg(dev, "%s(%d)\n", __func__, enable);
	if (enable)
		return hdmi_streamon(hdev);
	return hdmi_streamoff(hdev);
}
Exemple #11
0
static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
	struct v4l2_dv_enum_preset *enum_preset)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	u32 preset = edid_enum_presets(hdev, enum_preset->index);

	if (preset == V4L2_DV_INVALID)
		return -EINVAL;

	return v4l_fill_dv_preset_info(preset, enum_preset);
}
Exemple #12
0
int hdmi_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;
	int ret = 0;

	dev_dbg(dev, "%s start\n", __func__);

	switch (ctrl->id) {
	case V4L2_CID_TV_SET_DVI_MODE:
		hdev->dvi_mode = ctrl->value;
		break;
	case V4L2_CID_TV_SET_ASPECT_RATIO:
		hdev->aspect = ctrl->value;
		break;
	case V4L2_CID_TV_ENABLE_HDMI_AUDIO:
		mutex_lock(&hdev->mutex);
		hdev->audio_enable = !!ctrl->value;
		if (is_hdmi_streaming(hdev)) {
			hdmi_set_infoframe(hdev);
			hdmi_audio_enable(hdev, hdev->audio_enable);
		}
		mutex_unlock(&hdev->mutex);
		break;
	case V4L2_CID_TV_SET_NUM_CHANNELS:
		mutex_lock(&hdev->mutex);
		if ((ctrl->value == 2) || (ctrl->value == 6) ||
							(ctrl->value == 8)) {
			hdev->audio_channel_count = ctrl->value;
		} else {
			dev_err(dev, "invalid channel count\n");
			hdev->audio_channel_count = 2;
		}
		if (is_hdmi_streaming(hdev))
			hdmi_set_infoframe(hdev);
		mutex_unlock(&hdev->mutex);
		break;
	case V4L2_CID_TV_SET_COLOR_RANGE:
		hdev->color_range = ctrl->value;
		break;
	case V4L2_CID_TV_HDCP_ENABLE:
		hdev->hdcp_info.hdcp_enable = ctrl->value;
		dev_dbg(hdev->dev, "HDCP %s\n",
				ctrl->value ? "enable" : "disable");
		break;
	default:
		dev_err(dev, "invalid control id\n");
		ret = -EINVAL;
		break;
	}

	return ret;
}
Exemple #13
0
static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd,
	  struct v4l2_mbus_framefmt *fmt)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;

	dev_dbg(dev, "%s\n", __func__);
	if (!hdev->cur_conf)
		return -EINVAL;
	*fmt = hdev->cur_conf->mbus_fmt;
	return 0;
}
Exemple #14
0
static int hdmi_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_hdmi_platdata *pdata = pdev->dev.platform_data;
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct hdmi_resources *res = &hdev->res;
	int ret = 0;

	dev_dbg(dev, "%s\n", __func__);

	if (hdev->probe_state == HDMI_PROBING)
		return 0;

	/* power-on hdmiphy */
	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 1);

	clk_enable(res->sclk_hdmi);

	if (is_ip_ver_5a || is_ip_ver_5s) {
		hdmiphy_set_power(hdev, 1);
	} else {
		ret = v4l2_subdev_call(hdev->phy_sd, core, s_power, 1);
		if (ret) {
			dev_err(dev, "failed to turn on hdmiphy\n");
			goto fail;
		}
	}

	hdmi_sw_reset(hdev);
	hdmi_phy_sw_reset(hdev);

	ret = hdmi_conf_apply(hdev);
	if (ret)
		goto fail;

	dev_dbg(dev, "poweron succeed\n");

	return 0;

fail:
	clk_disable(res->sclk_hdmi);
	v4l2_subdev_call(hdev->phy_sd, core, s_power, 0);
	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 0);
	dev_err(dev, "poweron failed\n");

	return ret;
}
Exemple #15
0
static int hdmi_s_mbus_fmt(struct v4l2_subdev *sd,
	  struct v4l2_mbus_framefmt *fmt)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;

	dev_dbg(dev, "%s\n", __func__);
	if (fmt->code == V4L2_MBUS_FMT_YUV8_1X24)
		hdev->output_fmt = HDMI_OUTPUT_YUV444;
	else
		hdev->output_fmt = HDMI_OUTPUT_RGB888;

	return 0;
}
Exemple #16
0
static int hdmi_s_power(struct v4l2_subdev *sd, int on)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	int ret = 0;

	/* If runtime PM is not implemented, hdmi_runtime_resume
	 * and hdmi_runtime_suspend functions are directly called.
	 */

	if (on) {
		clk_enable(hdev->res.hdmi);

#ifdef CONFIG_PM_RUNTIME
		ret = pm_runtime_get_sync(hdev->dev);
#else
		hdmi_runtime_resume(hdev->dev);
#endif

		disable_irq(hdev->ext_irq);
		cancel_delayed_work_sync(&hdev->hpd_work_ext);

		s5p_v4l2_int_src_hdmi_hpd();
		hdmi_hpd_enable(hdev, 1);
		hdmi_hpd_clear_int(hdev);
		enable_irq(hdev->int_irq);

		dev_info(hdev->dev, "HDMI interrupt changed to internal\n");
	} else {
		cancel_work_sync(&hdev->work);
		hdmi_hpd_enable(hdev, 0);
		disable_irq(hdev->int_irq);
		cancel_work_sync(&hdev->hpd_work);

		s5p_v4l2_int_src_ext_hpd();
		enable_irq(hdev->ext_irq);
		dev_info(hdev->dev, "HDMI interrupt changed to external\n");

#ifdef CONFIG_PM_RUNTIME
		ret = pm_runtime_put_sync(hdev->dev);
#else
		hdmi_runtime_suspend(hdev->dev);
#endif

		clk_disable(hdev->res.hdmi);
	}

	/* only values < 0 indicate errors */
	return IS_ERR_VALUE(ret) ? ret : 0;
}
Exemple #17
0
int hdmi_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;

	if (!pm_runtime_suspended(hdev->dev) && !hdev->hpd_user_checked)
		ctrl->value = hdmi_hpd_status(hdev);
	else
		ctrl->value = atomic_read(&hdev->hpd_state);

	dev_dbg(dev, "HDMI cable is %s\n", ctrl->value ?
			"connected" : "disconnected");

	return 0;
}
Exemple #18
0
static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
	struct v4l2_dv_preset *preset)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;
	const struct hdmi_preset_conf *conf;

	conf = hdmi_preset2conf(preset->preset);
	if (conf == NULL) {
		dev_err(dev, "preset (%u) not supported\n", preset->preset);
		return -EINVAL;
	}
	hdev->cur_conf = conf;
	hdev->cur_preset = preset->preset;
	return 0;
}
Exemple #19
0
static int __devexit hdmi_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct hdmi_device *hdmi_dev = sd_to_hdmi_dev(sd);

	pm_runtime_disable(dev);
	clk_disable(hdmi_dev->res.hdmi);
	v4l2_device_unregister(&hdmi_dev->v4l2_dev);
	disable_irq(hdmi_dev->curr_irq);
	free_irq(hdmi_dev->curr_irq, hdmi_dev);
	iounmap(hdmi_dev->regs);
	hdmi_resources_cleanup(hdmi_dev);
	flush_workqueue(hdmi_dev->hdcp_wq);
	destroy_workqueue(hdmi_dev->hdcp_wq);
	kfree(hdmi_dev);
	dev_info(dev, "remove sucessful\n");

	return 0;
}
Exemple #20
0
static int hdmi_runtime_suspend(struct device *dev)
{
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct hdmi_resources *res = &hdev->res;

	dev_dbg(dev, "%s\n", __func__);

	/* HDMI PHY off sequence
	 * LINK off -> PHY off -> HDMI_PHY_CONTROL disable */

	/* turn clocks off */
	clk_disable(res->sclk_hdmi);

	v4l2_subdev_call(hdev->phy_sd, core, s_power, 0);

	/* power-off hdmiphy */
	clk_disable(res->hdmiphy);

	return 0;
}
static int hdmi_s_dv_timings(struct v4l2_subdev *sd,
                             struct v4l2_dv_timings *timings)
{
    struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
    struct device *dev = hdev->dev;

    hdev->cur_conf = hdmi_timing2conf(timings);
    if (hdev->cur_conf == NULL) {
        dev_err(dev, "timings not supported\n");
        return -EINVAL;
    }
    hdev->cur_timings = *timings;

    if (hdev->streaming == HDMI_STREAMING) {
        hdmi_streamoff(hdev);
        hdmi_s_power(sd, 0);
        hdev->streaming = HDMI_STOP;
    }

    return 0;
}
static int hdmi_runtime_resume(struct device *dev)
{
    struct v4l2_subdev *sd = dev_get_drvdata(dev);
    struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
    struct hdmi_resources *res = &hdev->res;
    int ret = 0;

    dev_dbg(dev, "%s\n", __func__);

    hdmiphy_set_isolation(hdev, 1);
    hdmiphy_set_conf(hdev, 1);

    clk_prepare_enable(res->hdmiphy);
    clk_prepare_enable(res->hdmi);

    hdmiphy_set_power(hdev, 1);

    hdmi_clock_set(hdev, 1);

    hdmi_sw_reset(hdev);
    hdmi_phy_sw_reset(hdev);

    ret = hdmi_conf_apply(hdev);
    if (ret)
        goto fail;

    dev_dbg(dev, "poweron succeed\n");

    return 0;

fail:
    clk_disable_unprepare(res->hdmi);
    clk_disable_unprepare(res->hdmiphy);
    hdmiphy_set_isolation(hdev, 0);
    dev_err(dev, "poweron failed\n");

    return ret;
}
Exemple #23
0
static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
	struct v4l2_dv_preset *preset)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;
	const struct hdmi_preset_conf *conf;

	conf = hdmi_preset2conf(preset->preset);
	if (conf == NULL) {
		dev_err(dev, "preset (%u) not supported\n", preset->preset);
		return -EINVAL;
	}
	hdev->cur_conf = conf;
	hdev->cur_preset = preset->preset;

	if (hdev->streaming == HDMI_STREAMING) {
		hdmi_streamoff(hdev);
		hdmi_s_power(sd, 0);
		hdev->streaming = HDMI_STOP;
	}

	return 0;
}
static int hdmi_runtime_suspend(struct device *dev)
{
    struct v4l2_subdev *sd = dev_get_drvdata(dev);
    struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
    struct hdmi_resources *res = &hdev->res;

    dev_dbg(dev, "%s\n", __func__);

    hdmi_clock_set(hdev, 0);

    /* HDMI PHY off sequence
     * LINK off -> PHY off -> isolation disable */
    hdmiphy_set_power(hdev, 0);

    /* turn clocks off */
    clk_disable_unprepare(res->hdmi);
    clk_disable_unprepare(res->hdmiphy);

    hdmiphy_set_conf(hdev, 0);
    hdmiphy_set_isolation(hdev, 0);

    return 0;
}
Exemple #25
0
int hdmi_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
	struct device *dev = hdev->dev;
	int ret = 0;

	switch (ctrl->id) {
	case V4L2_CID_TV_HPD_STATUS:
		ctrl->value = switch_get_state(&hdev->hpd_switch);
		break;
	case V4L2_CID_TV_GET_DVI_MODE:
		ctrl->value = hdev->dvi_mode;
		break;
	case V4L2_CID_TV_MAX_AUDIO_CHANNELS:
		ctrl->value = edid_max_audio_channels(hdev);
		break;
	default:
		dev_err(dev, "invalid control id\n");
		ret = -EINVAL;
		break;
	}

	return ret;
}
static int hdmi_g_dv_timings(struct v4l2_subdev *sd,
                             struct v4l2_dv_timings *timings)
{
    *timings = sd_to_hdmi_dev(sd)->cur_timings;
    return 0;
}