diff options
Diffstat (limited to 'drivers/video/omap2/dss/output.c')
-rw-r--r-- | drivers/video/omap2/dss/output.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c new file mode 100644 index 000000000000..813f26682b7a --- /dev/null +++ b/drivers/video/omap2/dss/output.c | |||
@@ -0,0 +1,148 @@ | |||
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 | |||
27 | static LIST_HEAD(output_list); | ||
28 | static DEFINE_MUTEX(output_lock); | ||
29 | |||
30 | int omapdss_output_set_device(struct omap_dss_output *out, | ||
31 | struct omap_dss_device *dssdev) | ||
32 | { | ||
33 | int r; | ||
34 | |||
35 | mutex_lock(&output_lock); | ||
36 | |||
37 | if (out->device) { | ||
38 | DSSERR("output already has device %s connected to it\n", | ||
39 | out->device->name); | ||
40 | r = -EINVAL; | ||
41 | goto err; | ||
42 | } | ||
43 | |||
44 | if (out->type != dssdev->type) { | ||
45 | DSSERR("output type and display type don't match\n"); | ||
46 | r = -EINVAL; | ||
47 | goto err; | ||
48 | } | ||
49 | |||
50 | out->device = dssdev; | ||
51 | dssdev->output = out; | ||
52 | |||
53 | mutex_unlock(&output_lock); | ||
54 | |||
55 | return 0; | ||
56 | err: | ||
57 | mutex_unlock(&output_lock); | ||
58 | |||
59 | return r; | ||
60 | } | ||
61 | EXPORT_SYMBOL(omapdss_output_set_device); | ||
62 | |||
63 | int omapdss_output_unset_device(struct omap_dss_output *out) | ||
64 | { | ||
65 | int r; | ||
66 | |||
67 | mutex_lock(&output_lock); | ||
68 | |||
69 | if (!out->device) { | ||
70 | DSSERR("output doesn't have a device connected to it\n"); | ||
71 | r = -EINVAL; | ||
72 | goto err; | ||
73 | } | ||
74 | |||
75 | if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
76 | DSSERR("device %s is not disabled, cannot unset device\n", | ||
77 | out->device->name); | ||
78 | r = -EINVAL; | ||
79 | goto err; | ||
80 | } | ||
81 | |||
82 | out->device->output = NULL; | ||
83 | out->device = NULL; | ||
84 | |||
85 | mutex_unlock(&output_lock); | ||
86 | |||
87 | return 0; | ||
88 | err: | ||
89 | mutex_unlock(&output_lock); | ||
90 | |||
91 | return r; | ||
92 | } | ||
93 | EXPORT_SYMBOL(omapdss_output_unset_device); | ||
94 | |||
95 | void dss_register_output(struct omap_dss_output *out) | ||
96 | { | ||
97 | list_add_tail(&out->list, &output_list); | ||
98 | } | ||
99 | |||
100 | void dss_unregister_output(struct omap_dss_output *out) | ||
101 | { | ||
102 | list_del(&out->list); | ||
103 | } | ||
104 | |||
105 | struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id) | ||
106 | { | ||
107 | struct omap_dss_output *out; | ||
108 | |||
109 | list_for_each_entry(out, &output_list, list) { | ||
110 | if (out->id == id) | ||
111 | return out; | ||
112 | } | ||
113 | |||
114 | return NULL; | ||
115 | } | ||
116 | |||
117 | struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev) | ||
118 | { | ||
119 | struct omap_dss_output *out = NULL; | ||
120 | enum omap_dss_output_id id; | ||
121 | |||
122 | switch (dssdev->type) { | ||
123 | case OMAP_DISPLAY_TYPE_DPI: | ||
124 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI); | ||
125 | break; | ||
126 | case OMAP_DISPLAY_TYPE_DBI: | ||
127 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI); | ||
128 | break; | ||
129 | case OMAP_DISPLAY_TYPE_SDI: | ||
130 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI); | ||
131 | break; | ||
132 | case OMAP_DISPLAY_TYPE_VENC: | ||
133 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC); | ||
134 | break; | ||
135 | case OMAP_DISPLAY_TYPE_HDMI: | ||
136 | out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI); | ||
137 | break; | ||
138 | case OMAP_DISPLAY_TYPE_DSI: | ||
139 | id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 : | ||
140 | OMAP_DSS_OUTPUT_DSI2; | ||
141 | out = omap_dss_get_output(id); | ||
142 | break; | ||
143 | default: | ||
144 | break; | ||
145 | } | ||
146 | |||
147 | return out; | ||
148 | } | ||