![]() |
|
|||
0001 /* 0002 * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. 0003 * 0004 * Permission is hereby granted, free of charge, to any person obtaining a 0005 * copy of this software and associated documentation files (the "Software"), 0006 * to deal in the Software without restriction, including without limitation 0007 * the rights to use, copy, modify, merge, publish, distribute, sub license, 0008 * and/or sell copies of the Software, and to permit persons to whom the 0009 * Software is furnished to do so, subject to the following conditions: 0010 * 0011 * The above copyright notice and this permission notice (including the 0012 * next paragraph) shall be included in all copies or substantial portions 0013 * of the Software. 0014 * 0015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0017 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 0018 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 0020 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 0021 * DEALINGS IN THE SOFTWARE. 0022 */ 0023 0024 #include <linux/backlight.h> 0025 #include <linux/err.h> 0026 #include <linux/module.h> 0027 0028 #include <drm/drm_crtc.h> 0029 #include <drm/drm_panel.h> 0030 #include <drm/drm_print.h> 0031 0032 static DEFINE_MUTEX(panel_lock); 0033 static LIST_HEAD(panel_list); 0034 0035 /** 0036 * DOC: drm panel 0037 * 0038 * The DRM panel helpers allow drivers to register panel objects with a 0039 * central registry and provide functions to retrieve those panels in display 0040 * drivers. 0041 * 0042 * For easy integration into drivers using the &drm_bridge infrastructure please 0043 * take look at drm_panel_bridge_add() and devm_drm_panel_bridge_add(). 0044 */ 0045 0046 /** 0047 * drm_panel_init - initialize a panel 0048 * @panel: DRM panel 0049 * @dev: parent device of the panel 0050 * @funcs: panel operations 0051 * @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to 0052 * the panel interface 0053 * 0054 * Initialize the panel structure for subsequent registration with 0055 * drm_panel_add(). 0056 */ 0057 void drm_panel_init(struct drm_panel *panel, struct device *dev, 0058 const struct drm_panel_funcs *funcs, int connector_type) 0059 { 0060 INIT_LIST_HEAD(&panel->list); 0061 panel->dev = dev; 0062 panel->funcs = funcs; 0063 panel->connector_type = connector_type; 0064 } 0065 EXPORT_SYMBOL(drm_panel_init); 0066 0067 /** 0068 * drm_panel_add - add a panel to the global registry 0069 * @panel: panel to add 0070 * 0071 * Add a panel to the global registry so that it can be looked up by display 0072 * drivers. 0073 */ 0074 void drm_panel_add(struct drm_panel *panel) 0075 { 0076 mutex_lock(&panel_lock); 0077 list_add_tail(&panel->list, &panel_list); 0078 mutex_unlock(&panel_lock); 0079 } 0080 EXPORT_SYMBOL(drm_panel_add); 0081 0082 /** 0083 * drm_panel_remove - remove a panel from the global registry 0084 * @panel: DRM panel 0085 * 0086 * Removes a panel from the global registry. 0087 */ 0088 void drm_panel_remove(struct drm_panel *panel) 0089 { 0090 mutex_lock(&panel_lock); 0091 list_del_init(&panel->list); 0092 mutex_unlock(&panel_lock); 0093 } 0094 EXPORT_SYMBOL(drm_panel_remove); 0095 0096 /** 0097 * drm_panel_prepare - power on a panel 0098 * @panel: DRM panel 0099 * 0100 * Calling this function will enable power and deassert any reset signals to 0101 * the panel. After this has completed it is possible to communicate with any 0102 * integrated circuitry via a command bus. 0103 * 0104 * Return: 0 on success or a negative error code on failure. 0105 */ 0106 int drm_panel_prepare(struct drm_panel *panel) 0107 { 0108 if (!panel) 0109 return -EINVAL; 0110 0111 if (panel->funcs && panel->funcs->prepare) 0112 return panel->funcs->prepare(panel); 0113 0114 return 0; 0115 } 0116 EXPORT_SYMBOL(drm_panel_prepare); 0117 0118 /** 0119 * drm_panel_unprepare - power off a panel 0120 * @panel: DRM panel 0121 * 0122 * Calling this function will completely power off a panel (assert the panel's 0123 * reset, turn off power supplies, ...). After this function has completed, it 0124 * is usually no longer possible to communicate with the panel until another 0125 * call to drm_panel_prepare(). 0126 * 0127 * Return: 0 on success or a negative error code on failure. 0128 */ 0129 int drm_panel_unprepare(struct drm_panel *panel) 0130 { 0131 if (!panel) 0132 return -EINVAL; 0133 0134 if (panel->funcs && panel->funcs->unprepare) 0135 return panel->funcs->unprepare(panel); 0136 0137 return 0; 0138 } 0139 EXPORT_SYMBOL(drm_panel_unprepare); 0140 0141 /** 0142 * drm_panel_enable - enable a panel 0143 * @panel: DRM panel 0144 * 0145 * Calling this function will cause the panel display drivers to be turned on 0146 * and the backlight to be enabled. Content will be visible on screen after 0147 * this call completes. 0148 * 0149 * Return: 0 on success or a negative error code on failure. 0150 */ 0151 int drm_panel_enable(struct drm_panel *panel) 0152 { 0153 int ret; 0154 0155 if (!panel) 0156 return -EINVAL; 0157 0158 if (panel->funcs && panel->funcs->enable) { 0159 ret = panel->funcs->enable(panel); 0160 if (ret < 0) 0161 return ret; 0162 } 0163 0164 ret = backlight_enable(panel->backlight); 0165 if (ret < 0) 0166 DRM_DEV_INFO(panel->dev, "failed to enable backlight: %d\n", 0167 ret); 0168 0169 return 0; 0170 } 0171 EXPORT_SYMBOL(drm_panel_enable); 0172 0173 /** 0174 * drm_panel_disable - disable a panel 0175 * @panel: DRM panel 0176 * 0177 * This will typically turn off the panel's backlight or disable the display 0178 * drivers. For smart panels it should still be possible to communicate with 0179 * the integrated circuitry via any command bus after this call. 0180 * 0181 * Return: 0 on success or a negative error code on failure. 0182 */ 0183 int drm_panel_disable(struct drm_panel *panel) 0184 { 0185 int ret; 0186 0187 if (!panel) 0188 return -EINVAL; 0189 0190 ret = backlight_disable(panel->backlight); 0191 if (ret < 0) 0192 DRM_DEV_INFO(panel->dev, "failed to disable backlight: %d\n", 0193 ret); 0194 0195 if (panel->funcs && panel->funcs->disable) 0196 return panel->funcs->disable(panel); 0197 0198 return 0; 0199 } 0200 EXPORT_SYMBOL(drm_panel_disable); 0201 0202 /** 0203 * drm_panel_get_modes - probe the available display modes of a panel 0204 * @panel: DRM panel 0205 * @connector: DRM connector 0206 * 0207 * The modes probed from the panel are automatically added to the connector 0208 * that the panel is attached to. 0209 * 0210 * Return: The number of modes available from the panel on success or a 0211 * negative error code on failure. 0212 */ 0213 int drm_panel_get_modes(struct drm_panel *panel, 0214 struct drm_connector *connector) 0215 { 0216 if (!panel) 0217 return -EINVAL; 0218 0219 if (panel->funcs && panel->funcs->get_modes) 0220 return panel->funcs->get_modes(panel, connector); 0221 0222 return -EOPNOTSUPP; 0223 } 0224 EXPORT_SYMBOL(drm_panel_get_modes); 0225 0226 #ifdef CONFIG_OF 0227 /** 0228 * of_drm_find_panel - look up a panel using a device tree node 0229 * @np: device tree node of the panel 0230 * 0231 * Searches the set of registered panels for one that matches the given device 0232 * tree node. If a matching panel is found, return a pointer to it. 0233 * 0234 * Return: A pointer to the panel registered for the specified device tree 0235 * node or an ERR_PTR() if no panel matching the device tree node can be found. 0236 * 0237 * Possible error codes returned by this function: 0238 * 0239 * - EPROBE_DEFER: the panel device has not been probed yet, and the caller 0240 * should retry later 0241 * - ENODEV: the device is not available (status != "okay" or "ok") 0242 */ 0243 struct drm_panel *of_drm_find_panel(const struct device_node *np) 0244 { 0245 struct drm_panel *panel; 0246 0247 if (!of_device_is_available(np)) 0248 return ERR_PTR(-ENODEV); 0249 0250 mutex_lock(&panel_lock); 0251 0252 list_for_each_entry(panel, &panel_list, list) { 0253 if (panel->dev->of_node == np) { 0254 mutex_unlock(&panel_lock); 0255 return panel; 0256 } 0257 } 0258 0259 mutex_unlock(&panel_lock); 0260 return ERR_PTR(-EPROBE_DEFER); 0261 } 0262 EXPORT_SYMBOL(of_drm_find_panel); 0263 0264 /** 0265 * of_drm_get_panel_orientation - look up the orientation of the panel through 0266 * the "rotation" binding from a device tree node 0267 * @np: device tree node of the panel 0268 * @orientation: orientation enum to be filled in 0269 * 0270 * Looks up the rotation of a panel in the device tree. The orientation of the 0271 * panel is expressed as a property name "rotation" in the device tree. The 0272 * rotation in the device tree is counter clockwise. 0273 * 0274 * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the 0275 * rotation property doesn't exist. Return a negative error code on failure. 0276 */ 0277 int of_drm_get_panel_orientation(const struct device_node *np, 0278 enum drm_panel_orientation *orientation) 0279 { 0280 int rotation, ret; 0281 0282 ret = of_property_read_u32(np, "rotation", &rotation); 0283 if (ret == -EINVAL) { 0284 /* Don't return an error if there's no rotation property. */ 0285 *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; 0286 return 0; 0287 } 0288 0289 if (ret < 0) 0290 return ret; 0291 0292 if (rotation == 0) 0293 *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; 0294 else if (rotation == 90) 0295 *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; 0296 else if (rotation == 180) 0297 *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; 0298 else if (rotation == 270) 0299 *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP; 0300 else 0301 return -EINVAL; 0302 0303 return 0; 0304 } 0305 EXPORT_SYMBOL(of_drm_get_panel_orientation); 0306 #endif 0307 0308 #if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE) 0309 /** 0310 * drm_panel_of_backlight - use backlight device node for backlight 0311 * @panel: DRM panel 0312 * 0313 * Use this function to enable backlight handling if your panel 0314 * uses device tree and has a backlight phandle. 0315 * 0316 * When the panel is enabled backlight will be enabled after a 0317 * successful call to &drm_panel_funcs.enable() 0318 * 0319 * When the panel is disabled backlight will be disabled before the 0320 * call to &drm_panel_funcs.disable(). 0321 * 0322 * A typical implementation for a panel driver supporting device tree 0323 * will call this function at probe time. Backlight will then be handled 0324 * transparently without requiring any intervention from the driver. 0325 * drm_panel_of_backlight() must be called after the call to drm_panel_init(). 0326 * 0327 * Return: 0 on success or a negative error code on failure. 0328 */ 0329 int drm_panel_of_backlight(struct drm_panel *panel) 0330 { 0331 struct backlight_device *backlight; 0332 0333 if (!panel || !panel->dev) 0334 return -EINVAL; 0335 0336 backlight = devm_of_find_backlight(panel->dev); 0337 0338 if (IS_ERR(backlight)) 0339 return PTR_ERR(backlight); 0340 0341 panel->backlight = backlight; 0342 return 0; 0343 } 0344 EXPORT_SYMBOL(drm_panel_of_backlight); 0345 #endif 0346 0347 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 0348 MODULE_DESCRIPTION("DRM panel infrastructure"); 0349 MODULE_LICENSE("GPL and additional rights");
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |