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