Lines Matching +full:ddc +full:- +full:i2c
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Zheng Yang <zhengyang@rock-chips.com>
5 * Yakir Yang <ykk@rock-chips.com>
58 struct inno_hdmi_i2c *i2c; member
59 struct i2c_adapter *ddc; member
91 * R = 1.164*Y + 1.596*V - 204
92 * G = 1.164*Y - 0.391*U - 0.813*V + 154
93 * B = 1.164*Y + 2.018*U - 258
102 * R = Y + 1.402*V - 248
103 * G = Y - 0.344*U - 0.714*V + 135
104 * B = Y + 1.772*U - 227
113 * R = 1.164*Y + 1.793*V - 248
114 * G = 1.164*Y - 0.213*U - 0.534*V + 77
115 * B = 1.164*Y + 2.115*U - 289
125 * Cb = -0.291G - 0.148R + 0.439B + 128
127 * Cr = -0.368G + 0.439R - 0.071B + 128
136 * Cb = - 0.338G - 0.101R + 0.439B + 128
138 * Cr = - 0.399G + 0.439R - 0.040B + 128
147 * R' = R x (235-16)/255 + 16;
148 * G' = G x (235-16)/255 + 16;
149 * B' = B x (235-16)/255 + 16;
160 return readl_relaxed(hdmi->regs + (offset) * 0x04); in hdmi_readb()
165 writel_relaxed(val, hdmi->regs + (offset) * 0x04); in hdmi_writeb()
181 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE; in inno_hdmi_i2c_init()
228 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode); in inno_hdmi_set_pwr_mode()
286 &hdmi->connector, in inno_hdmi_config_video_vsi()
300 &hdmi->connector, in inno_hdmi_config_video_avi()
303 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) in inno_hdmi_config_video_avi()
305 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422) in inno_hdmi_config_video_avi()
315 struct hdmi_data_info *data = &hdmi->hdmi_data; in inno_hdmi_config_video_csc()
333 if (data->enc_in_format == data->enc_out_format) { in inno_hdmi_config_video_csc()
334 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) || in inno_hdmi_config_video_csc()
335 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) { in inno_hdmi_config_video_csc()
347 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) { in inno_hdmi_config_video_csc()
348 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && in inno_hdmi_config_video_csc()
349 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { in inno_hdmi_config_video_csc()
354 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && in inno_hdmi_config_video_csc()
355 (data->enc_out_format == HDMI_COLORSPACE_RGB)) { in inno_hdmi_config_video_csc()
362 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) && in inno_hdmi_config_video_csc()
363 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) { in inno_hdmi_config_video_csc()
368 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) && in inno_hdmi_config_video_csc()
369 (data->enc_out_format == HDMI_COLORSPACE_RGB)) { in inno_hdmi_config_video_csc()
397 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ? in inno_hdmi_config_video_timing()
399 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ? in inno_hdmi_config_video_timing()
401 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ? in inno_hdmi_config_video_timing()
406 value = mode->htotal; in inno_hdmi_config_video_timing()
410 value = mode->htotal - mode->hdisplay; in inno_hdmi_config_video_timing()
414 value = mode->htotal - mode->hsync_start; in inno_hdmi_config_video_timing()
418 value = mode->hsync_end - mode->hsync_start; in inno_hdmi_config_video_timing()
422 value = mode->vtotal; in inno_hdmi_config_video_timing()
426 value = mode->vtotal - mode->vdisplay; in inno_hdmi_config_video_timing()
429 value = mode->vtotal - mode->vsync_start; in inno_hdmi_config_video_timing()
432 value = mode->vsync_end - mode->vsync_start; in inno_hdmi_config_video_timing()
445 struct drm_display_info *display = &hdmi->connector.display_info; in inno_hdmi_setup()
447 hdmi->hdmi_data.vic = drm_match_cea_mode(mode); in inno_hdmi_setup()
449 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
450 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB; in inno_hdmi_setup()
452 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) || in inno_hdmi_setup()
453 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) || in inno_hdmi_setup()
454 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) || in inno_hdmi_setup()
455 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18)) in inno_hdmi_setup()
456 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; in inno_hdmi_setup()
458 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; in inno_hdmi_setup()
466 v_HDMI_DVI(display->is_hdmi)); in inno_hdmi_setup()
472 if (display->is_hdmi) { in inno_hdmi_setup()
481 * clock rate, and reconfigure the DDC clock. in inno_hdmi_setup()
483 hdmi->tmds_rate = mode->clock * 1000; in inno_hdmi_setup()
502 drm_mode_copy(&hdmi->previous_mode, adj_mode); in inno_hdmi_encoder_mode_set()
533 s->output_mode = ROCKCHIP_OUT_MODE_P888; in inno_hdmi_encoder_atomic_check()
534 s->output_type = DRM_MODE_CONNECTOR_HDMIA; in inno_hdmi_encoder_atomic_check()
562 if (!hdmi->ddc) in inno_hdmi_connector_get_modes()
565 edid = drm_get_edid(connector, hdmi->ddc); in inno_hdmi_connector_get_modes()
567 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid); in inno_hdmi_connector_get_modes()
612 struct drm_encoder *encoder = &hdmi->encoder.encoder; in inno_hdmi_register()
613 struct device *dev = hdmi->dev; in inno_hdmi_register()
615 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); in inno_hdmi_register()
623 if (encoder->possible_crtcs == 0) in inno_hdmi_register()
624 return -EPROBE_DEFER; in inno_hdmi_register()
629 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; in inno_hdmi_register()
631 drm_connector_helper_add(&hdmi->connector, in inno_hdmi_register()
633 drm_connector_init_with_ddc(drm, &hdmi->connector, in inno_hdmi_register()
636 hdmi->ddc); in inno_hdmi_register()
638 drm_connector_attach_encoder(&hdmi->connector, encoder); in inno_hdmi_register()
645 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_irq() local
655 complete(&i2c->cmp); in inno_hdmi_i2c_irq()
666 if (hdmi->i2c) in inno_hdmi_hardirq()
682 drm_helper_hpd_irq_event(hdmi->connector.dev); in inno_hdmi_irq()
689 int length = msgs->len; in inno_hdmi_i2c_read()
690 u8 *buf = msgs->buf; in inno_hdmi_i2c_read()
693 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10); in inno_hdmi_i2c_read()
695 return -EAGAIN; in inno_hdmi_i2c_read()
697 while (length--) in inno_hdmi_i2c_read()
706 * The DDC module only support read EDID message, so in inno_hdmi_i2c_write()
707 * we assume that each word write to this i2c adapter in inno_hdmi_i2c_write()
710 if ((msgs->len != 1) || in inno_hdmi_i2c_write()
711 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR))) in inno_hdmi_i2c_write()
712 return -EINVAL; in inno_hdmi_i2c_write()
714 reinit_completion(&hdmi->i2c->cmp); in inno_hdmi_i2c_write()
716 if (msgs->addr == DDC_SEGMENT_ADDR) in inno_hdmi_i2c_write()
717 hdmi->i2c->segment_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
718 if (msgs->addr == DDC_ADDR) in inno_hdmi_i2c_write()
719 hdmi->i2c->ddc_addr = msgs->buf[0]; in inno_hdmi_i2c_write()
725 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr); in inno_hdmi_i2c_write()
728 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr); in inno_hdmi_i2c_write()
737 struct inno_hdmi_i2c *i2c = hdmi->i2c; in inno_hdmi_i2c_xfer() local
740 mutex_lock(&i2c->lock); in inno_hdmi_i2c_xfer()
747 DRM_DEV_DEBUG(hdmi->dev, in inno_hdmi_i2c_xfer()
766 mutex_unlock(&i2c->lock); in inno_hdmi_i2c_xfer()
784 struct inno_hdmi_i2c *i2c; in inno_hdmi_i2c_adapter() local
787 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); in inno_hdmi_i2c_adapter()
788 if (!i2c) in inno_hdmi_i2c_adapter()
789 return ERR_PTR(-ENOMEM); in inno_hdmi_i2c_adapter()
791 mutex_init(&i2c->lock); in inno_hdmi_i2c_adapter()
792 init_completion(&i2c->cmp); in inno_hdmi_i2c_adapter()
794 adap = &i2c->adap; in inno_hdmi_i2c_adapter()
795 adap->class = I2C_CLASS_DDC; in inno_hdmi_i2c_adapter()
796 adap->owner = THIS_MODULE; in inno_hdmi_i2c_adapter()
797 adap->dev.parent = hdmi->dev; in inno_hdmi_i2c_adapter()
798 adap->dev.of_node = hdmi->dev->of_node; in inno_hdmi_i2c_adapter()
799 adap->algo = &inno_hdmi_algorithm; in inno_hdmi_i2c_adapter()
800 strscpy(adap->name, "Inno HDMI", sizeof(adap->name)); in inno_hdmi_i2c_adapter()
805 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); in inno_hdmi_i2c_adapter()
806 devm_kfree(hdmi->dev, i2c); in inno_hdmi_i2c_adapter()
810 hdmi->i2c = i2c; in inno_hdmi_i2c_adapter()
812 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name); in inno_hdmi_i2c_adapter()
828 return -ENOMEM; in inno_hdmi_bind()
830 hdmi->dev = dev; in inno_hdmi_bind()
831 hdmi->drm_dev = drm; in inno_hdmi_bind()
833 hdmi->regs = devm_platform_ioremap_resource(pdev, 0); in inno_hdmi_bind()
834 if (IS_ERR(hdmi->regs)) in inno_hdmi_bind()
835 return PTR_ERR(hdmi->regs); in inno_hdmi_bind()
837 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); in inno_hdmi_bind()
838 if (IS_ERR(hdmi->pclk)) { in inno_hdmi_bind()
839 DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n"); in inno_hdmi_bind()
840 return PTR_ERR(hdmi->pclk); in inno_hdmi_bind()
843 ret = clk_prepare_enable(hdmi->pclk); in inno_hdmi_bind()
845 DRM_DEV_ERROR(hdmi->dev, in inno_hdmi_bind()
858 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi); in inno_hdmi_bind()
859 if (IS_ERR(hdmi->ddc)) { in inno_hdmi_bind()
860 ret = PTR_ERR(hdmi->ddc); in inno_hdmi_bind()
861 hdmi->ddc = NULL; in inno_hdmi_bind()
869 * and reconfigure the DDC clock. in inno_hdmi_bind()
871 hdmi->tmds_rate = clk_get_rate(hdmi->pclk); in inno_hdmi_bind()
891 hdmi->connector.funcs->destroy(&hdmi->connector); in inno_hdmi_bind()
892 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); in inno_hdmi_bind()
894 i2c_put_adapter(hdmi->ddc); in inno_hdmi_bind()
896 clk_disable_unprepare(hdmi->pclk); in inno_hdmi_bind()
905 hdmi->connector.funcs->destroy(&hdmi->connector); in inno_hdmi_unbind()
906 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder); in inno_hdmi_unbind()
908 i2c_put_adapter(hdmi->ddc); in inno_hdmi_unbind()
909 clk_disable_unprepare(hdmi->pclk); in inno_hdmi_unbind()
919 return component_add(&pdev->dev, &inno_hdmi_ops); in inno_hdmi_probe()
924 component_del(&pdev->dev, &inno_hdmi_ops); in inno_hdmi_remove()
928 { .compatible = "rockchip,rk3036-inno-hdmi",
938 .name = "innohdmi-rockchip",