Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.16-rc5 254 lines 5.6 kB view raw
1/* 2 * Copyright (C) 2012 Texas Instruments Ltd 3 * Author: Archit Taneja <archit@ti.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include <linux/kernel.h> 19#include <linux/module.h> 20#include <linux/platform_device.h> 21#include <linux/slab.h> 22 23#include <video/omapdss.h> 24 25#include "dss.h" 26 27static LIST_HEAD(output_list); 28static DEFINE_MUTEX(output_lock); 29 30int omapdss_output_set_device(struct omap_dss_device *out, 31 struct omap_dss_device *dssdev) 32{ 33 int r; 34 35 mutex_lock(&output_lock); 36 37 if (out->dst) { 38 DSSERR("output already has device %s connected to it\n", 39 out->dst->name); 40 r = -EINVAL; 41 goto err; 42 } 43 44 if (out->output_type != dssdev->type) { 45 DSSERR("output type and display type don't match\n"); 46 r = -EINVAL; 47 goto err; 48 } 49 50 out->dst = dssdev; 51 dssdev->src = out; 52 53 mutex_unlock(&output_lock); 54 55 return 0; 56err: 57 mutex_unlock(&output_lock); 58 59 return r; 60} 61EXPORT_SYMBOL(omapdss_output_set_device); 62 63int omapdss_output_unset_device(struct omap_dss_device *out) 64{ 65 int r; 66 67 mutex_lock(&output_lock); 68 69 if (!out->dst) { 70 DSSERR("output doesn't have a device connected to it\n"); 71 r = -EINVAL; 72 goto err; 73 } 74 75 if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { 76 DSSERR("device %s is not disabled, cannot unset device\n", 77 out->dst->name); 78 r = -EINVAL; 79 goto err; 80 } 81 82 out->dst->src = NULL; 83 out->dst = NULL; 84 85 mutex_unlock(&output_lock); 86 87 return 0; 88err: 89 mutex_unlock(&output_lock); 90 91 return r; 92} 93EXPORT_SYMBOL(omapdss_output_unset_device); 94 95int omapdss_register_output(struct omap_dss_device *out) 96{ 97 list_add_tail(&out->list, &output_list); 98 return 0; 99} 100EXPORT_SYMBOL(omapdss_register_output); 101 102void omapdss_unregister_output(struct omap_dss_device *out) 103{ 104 list_del(&out->list); 105} 106EXPORT_SYMBOL(omapdss_unregister_output); 107 108struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id) 109{ 110 struct omap_dss_device *out; 111 112 list_for_each_entry(out, &output_list, list) { 113 if (out->id == id) 114 return out; 115 } 116 117 return NULL; 118} 119EXPORT_SYMBOL(omap_dss_get_output); 120 121struct omap_dss_device *omap_dss_find_output(const char *name) 122{ 123 struct omap_dss_device *out; 124 125 list_for_each_entry(out, &output_list, list) { 126 if (strcmp(out->name, name) == 0) 127 return omap_dss_get_device(out); 128 } 129 130 return NULL; 131} 132EXPORT_SYMBOL(omap_dss_find_output); 133 134struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node) 135{ 136 struct omap_dss_device *out; 137 138 list_for_each_entry(out, &output_list, list) { 139 if (out->dev->of_node == node) 140 return omap_dss_get_device(out); 141 } 142 143 return NULL; 144} 145EXPORT_SYMBOL(omap_dss_find_output_by_node); 146 147struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) 148{ 149 while (dssdev->src) 150 dssdev = dssdev->src; 151 152 if (dssdev->id != 0) 153 return omap_dss_get_device(dssdev); 154 155 return NULL; 156} 157EXPORT_SYMBOL(omapdss_find_output_from_display); 158 159struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev) 160{ 161 struct omap_dss_device *out; 162 struct omap_overlay_manager *mgr; 163 164 out = omapdss_find_output_from_display(dssdev); 165 166 if (out == NULL) 167 return NULL; 168 169 mgr = out->manager; 170 171 omap_dss_put_device(out); 172 173 return mgr; 174} 175EXPORT_SYMBOL(omapdss_find_mgr_from_display); 176 177static const struct dss_mgr_ops *dss_mgr_ops; 178 179int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) 180{ 181 if (dss_mgr_ops) 182 return -EBUSY; 183 184 dss_mgr_ops = mgr_ops; 185 186 return 0; 187} 188EXPORT_SYMBOL(dss_install_mgr_ops); 189 190void dss_uninstall_mgr_ops(void) 191{ 192 dss_mgr_ops = NULL; 193} 194EXPORT_SYMBOL(dss_uninstall_mgr_ops); 195 196int dss_mgr_connect(struct omap_overlay_manager *mgr, 197 struct omap_dss_device *dst) 198{ 199 return dss_mgr_ops->connect(mgr, dst); 200} 201EXPORT_SYMBOL(dss_mgr_connect); 202 203void dss_mgr_disconnect(struct omap_overlay_manager *mgr, 204 struct omap_dss_device *dst) 205{ 206 dss_mgr_ops->disconnect(mgr, dst); 207} 208EXPORT_SYMBOL(dss_mgr_disconnect); 209 210void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 211 const struct omap_video_timings *timings) 212{ 213 dss_mgr_ops->set_timings(mgr, timings); 214} 215EXPORT_SYMBOL(dss_mgr_set_timings); 216 217void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, 218 const struct dss_lcd_mgr_config *config) 219{ 220 dss_mgr_ops->set_lcd_config(mgr, config); 221} 222EXPORT_SYMBOL(dss_mgr_set_lcd_config); 223 224int dss_mgr_enable(struct omap_overlay_manager *mgr) 225{ 226 return dss_mgr_ops->enable(mgr); 227} 228EXPORT_SYMBOL(dss_mgr_enable); 229 230void dss_mgr_disable(struct omap_overlay_manager *mgr) 231{ 232 dss_mgr_ops->disable(mgr); 233} 234EXPORT_SYMBOL(dss_mgr_disable); 235 236void dss_mgr_start_update(struct omap_overlay_manager *mgr) 237{ 238 dss_mgr_ops->start_update(mgr); 239} 240EXPORT_SYMBOL(dss_mgr_start_update); 241 242int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr, 243 void (*handler)(void *), void *data) 244{ 245 return dss_mgr_ops->register_framedone_handler(mgr, handler, data); 246} 247EXPORT_SYMBOL(dss_mgr_register_framedone_handler); 248 249void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, 250 void (*handler)(void *), void *data) 251{ 252 dss_mgr_ops->unregister_framedone_handler(mgr, handler, data); 253} 254EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);