1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7#define LOG_CATEGORY UCLASS_VIDEO_BRIDGE 8 9#include <common.h> 10#include <dm.h> 11#include <errno.h> 12#include <edid.h> 13#include <log.h> 14#include <video_bridge.h> 15#include <linux/delay.h> 16 17int video_bridge_set_backlight(struct udevice *dev, int percent) 18{ 19 struct video_bridge_ops *ops = video_bridge_get_ops(dev); 20 21 if (!ops->set_backlight) 22 return -ENOSYS; 23 24 return ops->set_backlight(dev, percent); 25} 26 27int video_bridge_attach(struct udevice *dev) 28{ 29 struct video_bridge_ops *ops = video_bridge_get_ops(dev); 30 31 if (!ops->attach) 32 return -ENOSYS; 33 34 return ops->attach(dev); 35} 36 37int video_bridge_check_attached(struct udevice *dev) 38{ 39 struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev); 40 struct video_bridge_ops *ops = video_bridge_get_ops(dev); 41 int ret; 42 43 if (!ops->check_attached) { 44 ret = dm_gpio_get_value(&uc_priv->hotplug); 45 46 return ret > 0 ? 0 : ret == 0 ? -ENOTCONN : ret; 47 } 48 49 return ops->check_attached(dev); 50} 51 52int video_bridge_read_edid(struct udevice *dev, u8 *buf, int buf_size) 53{ 54 struct video_bridge_ops *ops = video_bridge_get_ops(dev); 55 56 if (!ops || !ops->read_edid) 57 return -ENOSYS; 58 return ops->read_edid(dev, buf, buf_size); 59} 60 61static int video_bridge_pre_probe(struct udevice *dev) 62{ 63 struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev); 64 int ret; 65 66 debug("%s\n", __func__); 67 ret = gpio_request_by_name(dev, "sleep-gpios", 0, 68 &uc_priv->sleep, GPIOD_IS_OUT); 69 if (ret) { 70 debug("%s: Could not decode sleep-gpios (%d)\n", __func__, ret); 71 if (ret != -ENOENT) 72 return ret; 73 } 74 /* 75 * Drop this for now as we do not have driver model pinctrl support 76 * 77 * ret = dm_gpio_set_pull(&uc_priv->sleep, GPIO_PULL_NONE); 78 * if (ret) { 79 * debug("%s: Could not set sleep pull value\n", __func__); 80 * return ret; 81 * } 82 */ 83 ret = gpio_request_by_name(dev, "reset-gpios", 0, &uc_priv->reset, 84 GPIOD_IS_OUT); 85 if (ret) { 86 debug("%s: Could not decode reset-gpios (%d)\n", __func__, ret); 87 if (ret != -ENOENT) 88 return ret; 89 } 90 /* 91 * Drop this for now as we do not have driver model pinctrl support 92 * 93 * ret = dm_gpio_set_pull(&uc_priv->reset, GPIO_PULL_NONE); 94 * if (ret) { 95 * debug("%s: Could not set reset pull value\n", __func__); 96 * return ret; 97 * } 98 */ 99 ret = gpio_request_by_name(dev, "hotplug-gpios", 0, &uc_priv->hotplug, 100 GPIOD_IS_IN); 101 if (ret) { 102 debug("%s: Could not decode hotplug (%d)\n", __func__, ret); 103 if (ret != -ENOENT) 104 return ret; 105 } 106 107 return 0; 108} 109 110int video_bridge_set_active(struct udevice *dev, bool active) 111{ 112 struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev); 113 int ret = 0; 114 115 debug("%s: %d\n", __func__, active); 116 if (uc_priv->sleep.dev) { 117 ret = dm_gpio_set_value(&uc_priv->sleep, !active); 118 if (ret) 119 return ret; 120 } 121 122 if (!active) 123 return 0; 124 125 if (uc_priv->reset.dev) { 126 ret = dm_gpio_set_value(&uc_priv->reset, true); 127 if (ret) 128 return ret; 129 udelay(10); 130 ret = dm_gpio_set_value(&uc_priv->reset, false); 131 } 132 133 return ret; 134} 135 136UCLASS_DRIVER(video_bridge) = { 137 .id = UCLASS_VIDEO_BRIDGE, 138 .name = "video_bridge", 139 .per_device_auto = sizeof(struct video_bridge_priv), 140 .pre_probe = video_bridge_pre_probe, 141}; 142