xref: /rk3399_rockchip-uboot/drivers/video/bridge/video-bridge-uclass.c (revision 75eb6fceb584d246c2b7cfac79b4fe43d0ec0ecd)
1801ab9e9SSimon Glass /*
2801ab9e9SSimon Glass  * Copyright (C) 2015 Google, Inc
3801ab9e9SSimon Glass  * Written by Simon Glass <sjg@chromium.org>
4801ab9e9SSimon Glass  *
5801ab9e9SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
6801ab9e9SSimon Glass  */
7801ab9e9SSimon Glass 
8801ab9e9SSimon Glass #include <common.h>
9801ab9e9SSimon Glass #include <dm.h>
10801ab9e9SSimon Glass #include <errno.h>
11d2bb07b7SVasily Khoruzhick #include <edid.h>
12801ab9e9SSimon Glass #include <video_bridge.h>
13801ab9e9SSimon Glass 
video_bridge_set_backlight(struct udevice * dev,int percent)14801ab9e9SSimon Glass int video_bridge_set_backlight(struct udevice *dev, int percent)
15801ab9e9SSimon Glass {
16801ab9e9SSimon Glass 	struct video_bridge_ops *ops = video_bridge_get_ops(dev);
17801ab9e9SSimon Glass 
18801ab9e9SSimon Glass 	if (!ops->set_backlight)
19801ab9e9SSimon Glass 		return -ENOSYS;
20801ab9e9SSimon Glass 
21801ab9e9SSimon Glass 	return ops->set_backlight(dev, percent);
22801ab9e9SSimon Glass }
23801ab9e9SSimon Glass 
video_bridge_attach(struct udevice * dev)24801ab9e9SSimon Glass int video_bridge_attach(struct udevice *dev)
25801ab9e9SSimon Glass {
26801ab9e9SSimon Glass 	struct video_bridge_ops *ops = video_bridge_get_ops(dev);
27801ab9e9SSimon Glass 
28801ab9e9SSimon Glass 	if (!ops->attach)
29801ab9e9SSimon Glass 		return -ENOSYS;
30801ab9e9SSimon Glass 
31801ab9e9SSimon Glass 	return ops->attach(dev);
32801ab9e9SSimon Glass }
33801ab9e9SSimon Glass 
video_bridge_check_attached(struct udevice * dev)34801ab9e9SSimon Glass int video_bridge_check_attached(struct udevice *dev)
35801ab9e9SSimon Glass {
36801ab9e9SSimon Glass 	struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
37801ab9e9SSimon Glass 	struct video_bridge_ops *ops = video_bridge_get_ops(dev);
38801ab9e9SSimon Glass 	int ret;
39801ab9e9SSimon Glass 
40801ab9e9SSimon Glass 	if (!ops->check_attached) {
41801ab9e9SSimon Glass 		ret = dm_gpio_get_value(&uc_priv->hotplug);
42801ab9e9SSimon Glass 
43801ab9e9SSimon Glass 		return ret > 0 ? 0 : ret == 0 ? -ENOTCONN : ret;
44801ab9e9SSimon Glass 	}
45801ab9e9SSimon Glass 
46801ab9e9SSimon Glass 	return ops->check_attached(dev);
47801ab9e9SSimon Glass }
48801ab9e9SSimon Glass 
video_bridge_read_edid(struct udevice * dev,u8 * buf,int buf_size)49d2bb07b7SVasily Khoruzhick int video_bridge_read_edid(struct udevice *dev, u8 *buf, int buf_size)
50d2bb07b7SVasily Khoruzhick {
51d2bb07b7SVasily Khoruzhick 	struct video_bridge_ops *ops = video_bridge_get_ops(dev);
52d2bb07b7SVasily Khoruzhick 
53d2bb07b7SVasily Khoruzhick 	if (!ops || !ops->read_edid)
54d2bb07b7SVasily Khoruzhick 		return -ENOSYS;
55d2bb07b7SVasily Khoruzhick 	return ops->read_edid(dev, buf, buf_size);
56d2bb07b7SVasily Khoruzhick }
57d2bb07b7SVasily Khoruzhick 
video_bridge_get_timing(struct udevice * dev)58*75eb6fceSAlgea Cao int video_bridge_get_timing(struct udevice *dev)
59*75eb6fceSAlgea Cao {
60*75eb6fceSAlgea Cao 	struct video_bridge_ops *ops = video_bridge_get_ops(dev);
61*75eb6fceSAlgea Cao 
62*75eb6fceSAlgea Cao 	if (!ops || !ops->get_timing)
63*75eb6fceSAlgea Cao 		return -ENOSYS;
64*75eb6fceSAlgea Cao 	return ops->get_timing(dev);
65*75eb6fceSAlgea Cao }
66*75eb6fceSAlgea Cao 
video_bridge_pre_probe(struct udevice * dev)67801ab9e9SSimon Glass static int video_bridge_pre_probe(struct udevice *dev)
68801ab9e9SSimon Glass {
69801ab9e9SSimon Glass 	struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
70801ab9e9SSimon Glass 	int ret;
71801ab9e9SSimon Glass 
72801ab9e9SSimon Glass 	debug("%s\n", __func__);
73801ab9e9SSimon Glass 	ret = gpio_request_by_name(dev, "sleep-gpios", 0,
74801ab9e9SSimon Glass 				   &uc_priv->sleep, GPIOD_IS_OUT);
75801ab9e9SSimon Glass 	if (ret) {
76801ab9e9SSimon Glass 		debug("%s: Could not decode sleep-gpios (%d)\n", __func__, ret);
77d4bf91adSSimon Glass 		if (ret != -ENOENT)
78801ab9e9SSimon Glass 			return ret;
79801ab9e9SSimon Glass 	}
805eaeadaaSSimon Glass 	/*
815eaeadaaSSimon Glass 	 * Drop this for now as we do not have driver model pinctrl support
825eaeadaaSSimon Glass 	 *
835eaeadaaSSimon Glass 	 * ret = dm_gpio_set_pull(&uc_priv->sleep, GPIO_PULL_NONE);
845eaeadaaSSimon Glass 	 * if (ret) {
855eaeadaaSSimon Glass 	 *	debug("%s: Could not set sleep pull value\n", __func__);
865eaeadaaSSimon Glass 	 *	return ret;
875eaeadaaSSimon Glass 	 * }
885eaeadaaSSimon Glass 	 */
89801ab9e9SSimon Glass 	ret = gpio_request_by_name(dev, "reset-gpios", 0, &uc_priv->reset,
90801ab9e9SSimon Glass 				   GPIOD_IS_OUT);
91801ab9e9SSimon Glass 	if (ret) {
92801ab9e9SSimon Glass 		debug("%s: Could not decode reset-gpios (%d)\n", __func__, ret);
93d4bf91adSSimon Glass 		if (ret != -ENOENT)
94801ab9e9SSimon Glass 			return ret;
95801ab9e9SSimon Glass 	}
965eaeadaaSSimon Glass 	/*
975eaeadaaSSimon Glass 	 * Drop this for now as we do not have driver model pinctrl support
985eaeadaaSSimon Glass 	 *
995eaeadaaSSimon Glass 	 * ret = dm_gpio_set_pull(&uc_priv->reset, GPIO_PULL_NONE);
1005eaeadaaSSimon Glass 	 * if (ret) {
1015eaeadaaSSimon Glass 	 *	debug("%s: Could not set reset pull value\n", __func__);
1025eaeadaaSSimon Glass 	 *	return ret;
1035eaeadaaSSimon Glass 	 * }
1045eaeadaaSSimon Glass 	 */
105801ab9e9SSimon Glass 	ret = gpio_request_by_name(dev, "hotplug-gpios", 0, &uc_priv->hotplug,
106801ab9e9SSimon Glass 				   GPIOD_IS_IN);
107d4bf91adSSimon Glass 	if (ret) {
108801ab9e9SSimon Glass 		debug("%s: Could not decode hotplug (%d)\n", __func__, ret);
109d4bf91adSSimon Glass 		if (ret != -ENOENT)
110801ab9e9SSimon Glass 			return ret;
111801ab9e9SSimon Glass 	}
112801ab9e9SSimon Glass 
113801ab9e9SSimon Glass 	return 0;
114801ab9e9SSimon Glass }
115801ab9e9SSimon Glass 
video_bridge_set_active(struct udevice * dev,bool active)116801ab9e9SSimon Glass int video_bridge_set_active(struct udevice *dev, bool active)
117801ab9e9SSimon Glass {
118801ab9e9SSimon Glass 	struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
1197587ed89SVasily Khoruzhick 	int ret = 0;
120801ab9e9SSimon Glass 
121801ab9e9SSimon Glass 	debug("%s: %d\n", __func__, active);
1227587ed89SVasily Khoruzhick 	if (uc_priv->sleep.dev) {
123801ab9e9SSimon Glass 		ret = dm_gpio_set_value(&uc_priv->sleep, !active);
124801ab9e9SSimon Glass 		if (ret)
125801ab9e9SSimon Glass 			return ret;
1267587ed89SVasily Khoruzhick 	}
1277587ed89SVasily Khoruzhick 
1287587ed89SVasily Khoruzhick 	if (!active)
1297587ed89SVasily Khoruzhick 		return 0;
1307587ed89SVasily Khoruzhick 
1317587ed89SVasily Khoruzhick 	if (uc_priv->reset.dev) {
132801ab9e9SSimon Glass 		ret = dm_gpio_set_value(&uc_priv->reset, true);
133801ab9e9SSimon Glass 		if (ret)
134801ab9e9SSimon Glass 			return ret;
135801ab9e9SSimon Glass 		udelay(10);
136801ab9e9SSimon Glass 		ret = dm_gpio_set_value(&uc_priv->reset, false);
137801ab9e9SSimon Glass 	}
138801ab9e9SSimon Glass 
139801ab9e9SSimon Glass 	return ret;
140801ab9e9SSimon Glass }
141801ab9e9SSimon Glass 
142801ab9e9SSimon Glass UCLASS_DRIVER(video_bridge) = {
143801ab9e9SSimon Glass 	.id		= UCLASS_VIDEO_BRIDGE,
144801ab9e9SSimon Glass 	.name		= "video_bridge",
145801ab9e9SSimon Glass 	.per_device_auto_alloc_size	= sizeof(struct video_bridge_priv),
146801ab9e9SSimon Glass 	.pre_probe	= video_bridge_pre_probe,
147801ab9e9SSimon Glass };
148