2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author: Chris Zhong <zyw@rock-chips.com>
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/clk.h>
16 #include <linux/component.h>
17 #include <linux/extcon.h>
18 #include <linux/firmware.h>
19 #include <linux/regmap.h>
20 #include <linux/reset.h>
21 #include <linux/mfd/syscon.h>
22 #include <linux/phy/phy.h>
23 #include <sound/hdmi-codec.h>
24 #include <video/of_videomode.h>
25 #include <video/videomode.h>
28 #include <linux/platform_device.h>
29 #include "rockchip_dp_core.h"
30 #include "cdn-dp-fb-reg.h"
32 static struct cdn_dp_data rk3399_cdn_dp = {
36 static const struct of_device_id cdn_dp_dt_ids[] = {
37 { .compatible = "rockchip,rk3399-cdn-dp-fb",
38 .data = (void *)&rk3399_cdn_dp },
42 MODULE_DEVICE_TABLE(of, cdn_dp_dt_ids);
44 static int cdn_dp_grf_write(struct cdn_dp_device *dp,
45 unsigned int reg, unsigned int val)
49 ret = clk_prepare_enable(dp->grf_clk);
51 dev_err(dp->dev, "Failed to prepare_enable grf clock\n");
55 ret = regmap_write(dp->grf, reg, val);
57 dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
61 clk_disable_unprepare(dp->grf_clk);
66 static int cdn_dp_set_fw_rate(struct cdn_dp_device *dp)
70 if (!dp->fw_clk_enabled) {
71 rate = clk_get_rate(dp->core_clk);
73 dev_err(dp->dev, "get clk rate failed: %d\n", rate);
76 cdn_dp_fb_set_fw_clk(dp, rate);
77 cdn_dp_fb_clock_reset(dp);
78 dp->fw_clk_enabled = true;
84 static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
88 ret = clk_prepare_enable(dp->pclk);
90 dev_err(dp->dev, "cannot enable dp pclk %d\n", ret);
94 ret = clk_prepare_enable(dp->core_clk);
96 dev_err(dp->dev, "cannot enable core_clk %d\n", ret);
100 ret = pm_runtime_get_sync(dp->dev);
102 dev_err(dp->dev, "cannot get pm runtime %d\n", ret);
106 reset_control_assert(dp->apb_rst);
107 reset_control_assert(dp->core_rst);
108 reset_control_assert(dp->dptx_rst);
110 reset_control_deassert(dp->dptx_rst);
111 reset_control_deassert(dp->core_rst);
112 reset_control_deassert(dp->apb_rst);
114 ret = cdn_dp_set_fw_rate(dp);
116 dev_err(dp->dev, "cannot get set fw rate %d\n", ret);
123 clk_disable_unprepare(dp->core_clk);
125 clk_disable_unprepare(dp->pclk);
127 pm_runtime_put_sync(dp->dev);
131 static void cdn_dp_clk_disable(struct cdn_dp_device *dp)
133 pm_runtime_put_sync(dp->dev);
134 clk_disable_unprepare(dp->pclk);
135 clk_disable_unprepare(dp->core_clk);
138 int cdn_dp_get_edid(void *dp, u8 *buf, int block)
141 struct cdn_dp_device *dp_dev = dp;
143 mutex_lock(&dp_dev->lock);
144 ret = cdn_dp_fb_get_edid_block(dp_dev, buf, block, EDID_BLOCK_SIZE);
145 mutex_unlock(&dp_dev->lock);
150 int cdn_dp_connector_detect(void *dp)
152 struct cdn_dp_device *dp_dev = dp;
155 mutex_lock(&dp_dev->lock);
156 if (dp_dev->hpd_status == connector_status_connected)
158 mutex_unlock(&dp_dev->lock);
163 int cdn_dp_encoder_disable(void *dp)
165 struct cdn_dp_device *dp_dev = dp;
168 mutex_lock(&dp_dev->lock);
169 memset(&dp_dev->mode, 0, sizeof(dp_dev->mode));
170 if (dp_dev->hpd_status == connector_status_disconnected) {
171 dp_dev->dpms_mode = DRM_MODE_DPMS_OFF;
172 mutex_unlock(&dp_dev->lock);
176 if (dp_dev->dpms_mode == DRM_MODE_DPMS_ON) {
177 dp_dev->dpms_mode = DRM_MODE_DPMS_OFF;
179 dev_warn(dp_dev->dev, "wrong dpms status,dp encoder has already been disabled\n");
182 mutex_unlock(&dp_dev->lock);
187 static void cdn_dp_commit(struct cdn_dp_device *dp)
190 int ret = cdn_dp_fb_training_start(dp);
193 dev_err(dp->dev, "link training failed: %d\n", ret);
197 ret = cdn_dp_fb_get_training_status(dp);
199 dev_err(dp->dev, "get link training status failed: %d\n", ret);
203 dev_info(dp->dev, "rate:%d, lanes:%d\n",
204 dp->link.rate, dp->link.num_lanes);
207 * Use dpcd@0x0030~0x003f(which is GUID registers) to sync with NanoC
208 * to make sure training is ok. Nanoc will write "nanoc" in GUID registers
209 * when booting, and then we will use these registers to decide whether
210 * need to sync with device which plugged in.
211 * The sync register is 0x0035, firstly we write 0xaa to sync register,
212 * nanoc will read this register and then start the part2 code of DP.
214 ret = cdn_dp_fb_dpcd_read(dp, 0x0030, guid, 8);
215 if (ret == 0 && guid[0] == 'n' && guid[1] == 'a' && guid[2] == 'n' &&
216 guid[3] == 'o' && guid[4] == 'c') {
217 u8 sync_number = 0xaa;
219 cdn_dp_fb_dpcd_write(dp, 0x0035, sync_number);
222 if (cdn_dp_fb_set_video_status(dp, CONTROL_VIDEO_IDLE))
225 if (cdn_dp_fb_config_video(dp)) {
226 dev_err(dp->dev, "unable to config video\n");
230 if (cdn_dp_fb_set_video_status(dp, CONTROL_VIDEO_VALID))
233 dp->dpms_mode = DRM_MODE_DPMS_ON;
236 int cdn_dp_encoder_mode_set(void *dp, struct dp_disp_info *disp_info)
239 struct cdn_dp_device *dp_dev = dp;
240 struct video_info *video = &dp_dev->video_info;
241 struct drm_display_mode disp_mode;
242 struct fb_videomode *mode = disp_info->mode;
244 mutex_lock(&dp_dev->lock);
245 disp_mode.clock = mode->pixclock / 1000;
246 disp_mode.hdisplay = mode->xres;
247 disp_mode.hsync_start = disp_mode.hdisplay + mode->right_margin;
248 disp_mode.hsync_end = disp_mode.hsync_start + mode->hsync_len;
249 disp_mode.htotal = disp_mode.hsync_end + mode->left_margin;
250 disp_mode.vdisplay = mode->yres;
251 disp_mode.vsync_start = disp_mode.vdisplay + mode->lower_margin;
252 disp_mode.vsync_end = disp_mode.vsync_start + mode->vsync_len;
253 disp_mode.vtotal = disp_mode.vsync_end + mode->upper_margin;
255 switch (disp_info->color_depth) {
259 video->color_depth = 10;
262 video->color_depth = 6;
265 video->color_depth = 8;
269 video->color_fmt = PXL_RGB;
271 video->v_sync_polarity = disp_info->vsync_polarity;
272 video->h_sync_polarity = disp_info->hsync_polarity;
274 if (disp_info->vop_sel)
275 val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
277 val = DP_SEL_VOP_LIT << 16;
279 ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
281 dev_err(dp_dev->dev, "Could not write to GRF: %d\n", ret);
282 mutex_unlock(&dp_dev->lock);
285 memcpy(&dp_dev->mode, &disp_mode, sizeof(disp_mode));
287 mutex_unlock(&dp_dev->lock);
292 int cdn_dp_encoder_enable(void *dp)
294 struct cdn_dp_device *dp_dev = dp;
297 mutex_lock(&dp_dev->lock);
299 if (dp_dev->dpms_mode == DRM_MODE_DPMS_OFF) {
301 * the mode info of dp device will be cleared when dp encoder is disabled
302 * so if clock value of mode is 0, means rockchip_dp_config_video is not
303 * return success, so we don't do cdn_dp_commit.
305 if (dp_dev->mode.clock == 0) {
306 dev_err(dp_dev->dev, "Error !Please make sure function cdn_dp_encoder_mode_set return success!\n");
307 mutex_unlock(&dp_dev->lock);
310 cdn_dp_commit(dp_dev);
312 dev_warn(dp_dev->dev, "wrong dpms status,dp encoder has already been enabled\n");
315 mutex_unlock(&dp_dev->lock);
320 static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
323 const u32 *iram_data, *dram_data;
324 const struct firmware *fw = dp->fw;
325 const struct cdn_firmware_header *hdr;
327 hdr = (struct cdn_firmware_header *)fw->data;
328 if (fw->size != le32_to_cpu(hdr->size_bytes)) {
329 dev_err(dp->dev, "firmware is invalid\n");
333 iram_data = (const u32 *)(fw->data + hdr->header_size);
334 dram_data = (const u32 *)(fw->data + hdr->header_size + hdr->iram_size);
336 ret = cdn_dp_fb_load_firmware(dp, iram_data, hdr->iram_size,
337 dram_data, hdr->dram_size);
341 ret = cdn_dp_fb_set_firmware_active(dp, true);
343 dev_err(dp->dev, "active ucpu failed: %d\n", ret);
348 return cdn_dp_fb_event_config(dp);
351 static int cdn_dp_init(struct cdn_dp_device *dp)
353 struct device *dev = dp->dev;
354 struct device_node *np = dev->of_node;
355 struct platform_device *pdev = to_platform_device(dev);
356 struct resource *res;
358 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
359 if (IS_ERR(dp->grf)) {
360 dev_err(dev, "cdn-dp needs rockchip,grf property\n");
361 return PTR_ERR(dp->grf);
364 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
365 dp->regs = devm_ioremap_resource(dev, res);
366 if (IS_ERR(dp->regs)) {
367 dev_err(dev, "ioremap reg failed\n");
368 return PTR_ERR(dp->regs);
371 dp->core_clk = devm_clk_get(dev, "core-clk");
372 if (IS_ERR(dp->core_clk)) {
373 dev_err(dev, "cannot get core_clk_dp\n");
374 return PTR_ERR(dp->core_clk);
377 dp->pclk = devm_clk_get(dev, "pclk");
378 if (IS_ERR(dp->pclk)) {
379 dev_err(dev, "cannot get pclk\n");
380 return PTR_ERR(dp->pclk);
383 dp->spdif_clk = devm_clk_get(dev, "spdif");
384 if (IS_ERR(dp->spdif_clk)) {
385 dev_err(dev, "cannot get spdif_clk\n");
386 return PTR_ERR(dp->spdif_clk);
389 dp->grf_clk = devm_clk_get(dev, "grf");
390 if (IS_ERR(dp->grf_clk)) {
391 dev_err(dev, "cannot get grf clk\n");
392 return PTR_ERR(dp->grf_clk);
395 dp->spdif_rst = devm_reset_control_get(dev, "spdif");
396 if (IS_ERR(dp->spdif_rst)) {
397 dev_err(dev, "no spdif reset control found\n");
398 return PTR_ERR(dp->spdif_rst);
401 dp->dptx_rst = devm_reset_control_get(dev, "dptx");
402 if (IS_ERR(dp->dptx_rst)) {
403 dev_err(dev, "no uphy reset control found\n");
404 return PTR_ERR(dp->dptx_rst);
407 dp->apb_rst = devm_reset_control_get(dev, "apb");
408 if (IS_ERR(dp->apb_rst)) {
409 dev_err(dev, "no apb reset control found\n");
410 return PTR_ERR(dp->apb_rst);
413 dp->core_rst = devm_reset_control_get(dev, "core");
414 if (IS_ERR(dp->core_rst)) {
415 DRM_DEV_ERROR(dev, "no core reset control found\n");
416 return PTR_ERR(dp->core_rst);
419 dp->dpms_mode = DRM_MODE_DPMS_OFF;
420 dp->fw_clk_enabled = false;
422 pm_runtime_enable(dev);
424 mutex_init(&dp->lock);
425 wake_lock_init(&dp->wake_lock, WAKE_LOCK_SUSPEND, "cdn_dp_fb");
429 struct cdn_dp_device *g_dp;
430 static int cdn_dp_audio_hw_params(struct device *dev, void *data,
431 struct hdmi_codec_daifmt *daifmt,
432 struct hdmi_codec_params *params)
434 struct dp_dev *dp_dev = dev_get_drvdata(dev);
435 struct cdn_dp_device *dp = dp_dev->dp;
437 struct audio_info audio = {
439 .sample_rate = 44100,
443 if (!cdn_dp_connector_detect(dp))
448 audio.format = AFMT_I2S;
451 audio.format = AFMT_SPDIF;
454 dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt);
458 ret = cdn_dp_fb_audio_config(dp, &audio);
460 dp->audio_info = audio;
465 static void cdn_dp_audio_shutdown(struct device *dev, void *data)
467 struct dp_dev *dp_dev = dev_get_drvdata(dev);
468 struct cdn_dp_device *dp = dp_dev->dp;
471 if (cdn_dp_connector_detect(dp)) {
472 ret = cdn_dp_fb_audio_stop(dp, &dp->audio_info);
474 dp->audio_info.format = AFMT_UNUSED;
478 static int cdn_dp_audio_digital_mute(struct device *dev, void *data,
481 struct dp_dev *dp_dev = dev_get_drvdata(dev);
482 struct cdn_dp_device *dp = dp_dev->dp;
484 if (!cdn_dp_connector_detect(dp))
486 return cdn_dp_fb_audio_mute(dp, enable);
489 static const struct hdmi_codec_ops audio_codec_ops = {
490 .hw_params = cdn_dp_audio_hw_params,
491 .audio_shutdown = cdn_dp_audio_shutdown,
492 .digital_mute = cdn_dp_audio_digital_mute,
495 static int cdn_dp_audio_codec_init(struct cdn_dp_device *dp,
498 struct hdmi_codec_pdata codec_data = {
501 .ops = &audio_codec_ops,
502 .max_i2s_channels = 8,
505 dp->audio_pdev = platform_device_register_data(
506 dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
507 &codec_data, sizeof(codec_data));
509 return PTR_ERR_OR_ZERO(dp->audio_pdev);
512 static int cdn_dp_get_cap_lanes(struct cdn_dp_device *dp,
513 struct extcon_dev *edev)
515 union extcon_property_value property;
522 dptx = extcon_get_state(edev, EXTCON_DISP_DP);
524 extcon_get_property(edev, EXTCON_DISP_DP,
525 EXTCON_PROP_USB_SS, &property);
535 static int cdn_dp_get_dpcd(struct cdn_dp_device *dp, struct cdn_dp_port *port)
542 * Native read with retry for link status and receiver capability reads
543 * for cases where the sink may still not be ready.
545 * Sinks are *supposed* to come up within 1ms from an off state, but
546 * some DOCKs need about 5 seconds to power up, so read the dpcd every
547 * 100ms, if can not get a good dpcd in 10 seconds, give up.
549 for (i = 0; i < 100; i++) {
550 ret = cdn_dp_fb_dpcd_read(dp, DP_SINK_COUNT,
553 dev_dbg(dp->dev, "get dpcd success!\n");
555 sink_count = DP_GET_SINK_COUNT(sink_count);
558 dev_err(dp->dev, "sink cout is 0, no sink device!\n");
565 ret = cdn_dp_fb_dpcd_read(dp, 0x000, dp->dpcd,
566 DP_RECEIVER_CAP_SIZE);
571 } else if (!extcon_get_state(port->extcon, EXTCON_DISP_DP)) {
578 dev_err(dp->dev, "get dpcd failed!\n");
583 static void cdn_dp_enter_standy(struct cdn_dp_device *dp,
584 struct cdn_dp_port *port)
588 if (port->phy_status) {
589 ret = phy_power_off(port->phy);
591 dev_err(dp->dev, "phy power off failed: %d", ret);
596 port->phy_status = false;
598 for (i = 0; i < dp->ports; i++)
599 if (dp->port[i]->phy_status)
602 memset(dp->dpcd, 0, DP_RECEIVER_CAP_SIZE);
604 cdn_dp_fb_set_firmware_active(dp, false);
605 if (dp->fw_clk_enabled) {
606 cdn_dp_clk_disable(dp);
607 dp->fw_clk_enabled = false;
609 dp->hpd_status = connector_status_disconnected;
611 hpd_change(dp->dev, 0);
614 static int cdn_dp_start_work(struct cdn_dp_device *dp,
615 struct cdn_dp_port *port,
618 union extcon_property_value property;
621 if (!dp->fw_loaded) {
622 ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dp->dev);
624 if (ret == -ENOENT && dp->fw_wait <= MAX_FW_WAIT_SECS) {
625 unsigned long time = msecs_to_jiffies(dp->fw_wait * HZ);
628 * Keep trying to load the firmware for up to 1 minute,
629 * if can not find the file.
631 schedule_delayed_work(&port->event_wq, time);
634 dev_err(dp->dev, "failed to request firmware: %d\n",
640 dp->fw_loaded = true;
643 ret = cdn_dp_clk_enable(dp);
645 dev_err(dp->dev, "failed to enable clock for dp: %d\n", ret);
649 ret = phy_power_on(port->phy);
651 dev_err(dp->dev, "phy power on failed: %d\n", ret);
655 port->phy_status = true;
657 ret = cdn_dp_firmware_init(dp);
659 dev_err(dp->dev, "firmware init failed: %d", ret);
663 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26,
664 DPTX_HPD_SEL_MASK | DPTX_HPD_SEL);
668 ret = cdn_dp_fb_get_hpd_status(dp);
671 dev_err(dp->dev, "hpd does not exist\n");
675 ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
676 EXTCON_PROP_USB_TYPEC_POLARITY, &property);
678 dev_err(dp->dev, "get property failed\n");
682 ret = cdn_dp_fb_set_host_cap(dp, cap_lanes, property.intval);
684 dev_err(dp->dev, "set host capabilities failed: %d\n", ret);
688 ret = cdn_dp_get_dpcd(dp, port);
695 cdn_dp_grf_write(dp, GRF_SOC_CON26,
696 DPTX_HPD_SEL_MASK | DPTX_HPD_DEL);
700 cdn_dp_fb_set_firmware_active(dp, false);
703 if (phy_power_off(port->phy))
704 dev_err(dp->dev, "phy power off failed: %d", ret);
706 port->phy_status = false;
709 cdn_dp_clk_disable(dp);
710 dp->fw_clk_enabled = false;
714 static int cdn_dp_pd_event(struct notifier_block *nb,
715 unsigned long event, void *priv)
717 struct cdn_dp_port *port;
719 port = container_of(nb, struct cdn_dp_port, event_nb);
720 schedule_delayed_work(&port->event_wq, 0);
724 static void cdn_dp_pd_event_wq(struct work_struct *work)
726 struct cdn_dp_port *port = container_of(work, struct cdn_dp_port,
728 struct cdn_dp_device *dp = port->dp;
729 u8 new_cap_lanes, sink_count, i;
732 mutex_lock(&dp->lock);
733 wake_lock_timeout(&dp->wake_lock, msecs_to_jiffies(1000));
735 new_cap_lanes = cdn_dp_get_cap_lanes(dp, port->extcon);
737 if (new_cap_lanes == port->cap_lanes) {
738 if (!new_cap_lanes) {
739 dev_err(dp->dev, "dp lanes is 0, and same with last time\n");
744 * If HPD interrupt is triggered, and cable states is still
745 * attached, that means something on the Type-C Dock/Dongle
746 * changed, check the sink count by DPCD. If sink count became
747 * 0, this port phy can be powered off; if the sink count does
748 * not change and dp is connected, don't do anything, because
749 * dp video output maybe ongoing. if dp is not connected, that
750 * means something is wrong, we don't do anything here, just
753 cdn_dp_fb_dpcd_read(dp, DP_SINK_COUNT, &sink_count, 1);
755 if (dp->hpd_status == connector_status_connected)
757 "hpd interrupt is triggered when dp has been already connected\n");
760 "something is wrong, hpd is triggered before dp is connected\n");
768 if (dp->hpd_status == connector_status_connected && new_cap_lanes) {
769 dev_err(dp->dev, "error, dp connector has already been connected\n");
773 if (!new_cap_lanes) {
774 dev_info(dp->dev, "dp lanes is 0, enter standby\n");
775 cdn_dp_enter_standy(dp, port);
779 /* if other phy is running, do not do anything, just return */
780 for (i = 0; i < dp->ports; i++) {
781 if (dp->port[i]->phy_status) {
782 dev_warn(dp->dev, "busy, phy[%d] is running",
788 ret = cdn_dp_start_work(dp, port, new_cap_lanes);
790 dev_err(dp->dev, "dp failed to connect ,error = %d\n", ret);
793 port->cap_lanes = new_cap_lanes;
794 dp->hpd_status = connector_status_connected;
795 wake_unlock(&dp->wake_lock);
796 mutex_unlock(&dp->lock);
797 hpd_change(dp->dev, new_cap_lanes);
801 wake_unlock(&dp->wake_lock);
802 mutex_unlock(&dp->lock);
805 static int cdn_dp_bind(struct cdn_dp_device *dp)
807 struct cdn_dp_port *port;
810 ret = cdn_dp_init(dp);
814 dp->hpd_status = connector_status_disconnected;
816 cdn_dp_audio_codec_init(dp, dp->dev);
818 for (i = 0; i < dp->ports; i++) {
821 port->event_nb.notifier_call = cdn_dp_pd_event;
822 INIT_DELAYED_WORK(&port->event_wq, cdn_dp_pd_event_wq);
823 ret = extcon_register_notifier(port->extcon, EXTCON_DISP_DP,
826 dev_err(dp->dev, "regitster EXTCON_DISP_DP notifier err\n");
830 if (extcon_get_state(port->extcon, EXTCON_DISP_DP))
831 schedule_delayed_work(&port->event_wq,
832 msecs_to_jiffies(2000));
838 int cdn_dp_fb_suspend(void *dp_dev)
840 struct cdn_dp_device *dp = dp_dev;
841 struct cdn_dp_port *port;
844 for (i = 0; i < dp->ports; i++) {
846 if (port->phy_status) {
847 cdn_dp_fb_dpcd_write(dp, DP_SET_POWER, DP_SET_POWER_D3);
848 cdn_dp_enter_standy(dp, port);
853 * if dp has been suspended, need to download firmware
854 * and set fw clk again.
856 dp->fw_clk_enabled = false;
857 dp->fw_loaded = false;
862 int cdn_dp_fb_resume(void *dp_dev)
864 struct cdn_dp_device *dp = dp_dev;
865 struct cdn_dp_port *port;
869 for (i = 0; i < dp->ports; i++) {
871 schedule_delayed_work(&port->event_wq, 0);
872 flush_delayed_work(&port->event_wq);
879 static int cdn_dp_probe(struct platform_device *pdev)
881 struct device *dev = &pdev->dev;
882 const struct of_device_id *match;
883 struct cdn_dp_data *dp_data;
884 struct cdn_dp_port *port;
885 struct cdn_dp_device *dp;
886 struct extcon_dev *extcon;
890 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
896 match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node);
897 dp_data = (struct cdn_dp_data *)match->data;
899 for (i = 0; i < dp_data->max_phy; i++) {
900 extcon = extcon_get_edev_by_phandle(dev, i);
901 phy = devm_of_phy_get_by_index(dev, dev->of_node, i);
903 if (PTR_ERR(extcon) == -EPROBE_DEFER ||
904 PTR_ERR(phy) == -EPROBE_DEFER){
905 /* don't exit if there already has one port */
908 return -EPROBE_DEFER;
912 if (IS_ERR(extcon) || IS_ERR(phy))
915 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
919 port->extcon = extcon;
923 dp->port[dp->ports++] = port;
927 dev_err(dev, "missing extcon or phy\n");
932 ret = cdn_dp_fb_register(pdev, dp);
937 static struct platform_driver cdn_dp_driver = {
938 .probe = cdn_dp_probe,
941 .owner = THIS_MODULE,
942 .of_match_table = of_match_ptr(cdn_dp_dt_ids),
946 module_platform_driver(cdn_dp_driver);
948 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
949 MODULE_DESCRIPTION("cdn DP Driver");
950 MODULE_LICENSE("GPL v2");