aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/dss/display-sysfs.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2015-12-09 13:26:00 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-12-29 04:07:48 -0500
commit9960aa7cb58caadef8edf3a2582e30664a6b68dd (patch)
treeff7cfe2855cca84c59beccba9f2ca7cea36541c2 /drivers/gpu/drm/omapdrm/dss/display-sysfs.c
parent5ca28914b8b4371cfa56b6ee2dec68debb99718f (diff)
drm/omap: move omapdss & displays under omapdrm
Now that omapfb has its own copy of omapdss and display drivers, we can move omapdss and display drivers which omapdrm uses to omapdrm's directory. We also need to change the main drm Makefile so that omapdrm directory is always entered, because omapdss has a file that can't be built as a module. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Dave Airlie <airlied@gmail.com> Acked-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/display-sysfs.c')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/display-sysfs.c356
1 files changed, 356 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/display-sysfs.c b/drivers/gpu/drm/omapdrm/dss/display-sysfs.c
new file mode 100644
index 000000000000..6ad0991f8259
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/display-sysfs.c
@@ -0,0 +1,356 @@
1/*
2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
4 *
5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define DSS_SUBSYS_NAME "DISPLAY"
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/sysfs.h>
27
28#include <video/omapdss.h>
29#include "dss.h"
30
31static ssize_t display_name_show(struct omap_dss_device *dssdev, char *buf)
32{
33 return snprintf(buf, PAGE_SIZE, "%s\n",
34 dssdev->name ?
35 dssdev->name : "");
36}
37
38static ssize_t display_enabled_show(struct omap_dss_device *dssdev, char *buf)
39{
40 return snprintf(buf, PAGE_SIZE, "%d\n",
41 omapdss_device_is_enabled(dssdev));
42}
43
44static ssize_t display_enabled_store(struct omap_dss_device *dssdev,
45 const char *buf, size_t size)
46{
47 int r;
48 bool enable;
49
50 r = strtobool(buf, &enable);
51 if (r)
52 return r;
53
54 if (enable == omapdss_device_is_enabled(dssdev))
55 return size;
56
57 if (omapdss_device_is_connected(dssdev) == false)
58 return -ENODEV;
59
60 if (enable) {
61 r = dssdev->driver->enable(dssdev);
62 if (r)
63 return r;
64 } else {
65 dssdev->driver->disable(dssdev);
66 }
67
68 return size;
69}
70
71static ssize_t display_tear_show(struct omap_dss_device *dssdev, char *buf)
72{
73 return snprintf(buf, PAGE_SIZE, "%d\n",
74 dssdev->driver->get_te ?
75 dssdev->driver->get_te(dssdev) : 0);
76}
77
78static ssize_t display_tear_store(struct omap_dss_device *dssdev,
79 const char *buf, size_t size)
80{
81 int r;
82 bool te;
83
84 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
85 return -ENOENT;
86
87 r = strtobool(buf, &te);
88 if (r)
89 return r;
90
91 r = dssdev->driver->enable_te(dssdev, te);
92 if (r)
93 return r;
94
95 return size;
96}
97
98static ssize_t display_timings_show(struct omap_dss_device *dssdev, char *buf)
99{
100 struct omap_video_timings t;
101
102 if (!dssdev->driver->get_timings)
103 return -ENOENT;
104
105 dssdev->driver->get_timings(dssdev, &t);
106
107 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
108 t.pixelclock,
109 t.x_res, t.hfp, t.hbp, t.hsw,
110 t.y_res, t.vfp, t.vbp, t.vsw);
111}
112
113static ssize_t display_timings_store(struct omap_dss_device *dssdev,
114 const char *buf, size_t size)
115{
116 struct omap_video_timings t = dssdev->panel.timings;
117 int r, found;
118
119 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
120 return -ENOENT;
121
122 found = 0;
123#ifdef CONFIG_OMAP2_DSS_VENC
124 if (strncmp("pal", buf, 3) == 0) {
125 t = omap_dss_pal_timings;
126 found = 1;
127 } else if (strncmp("ntsc", buf, 4) == 0) {
128 t = omap_dss_ntsc_timings;
129 found = 1;
130 }
131#endif
132 if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
133 &t.pixelclock,
134 &t.x_res, &t.hfp, &t.hbp, &t.hsw,
135 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
136 return -EINVAL;
137
138 r = dssdev->driver->check_timings(dssdev, &t);
139 if (r)
140 return r;
141
142 dssdev->driver->disable(dssdev);
143 dssdev->driver->set_timings(dssdev, &t);
144 r = dssdev->driver->enable(dssdev);
145 if (r)
146 return r;
147
148 return size;
149}
150
151static ssize_t display_rotate_show(struct omap_dss_device *dssdev, char *buf)
152{
153 int rotate;
154 if (!dssdev->driver->get_rotate)
155 return -ENOENT;
156 rotate = dssdev->driver->get_rotate(dssdev);
157 return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
158}
159
160static ssize_t display_rotate_store(struct omap_dss_device *dssdev,
161 const char *buf, size_t size)
162{
163 int rot, r;
164
165 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
166 return -ENOENT;
167
168 r = kstrtoint(buf, 0, &rot);
169 if (r)
170 return r;
171
172 r = dssdev->driver->set_rotate(dssdev, rot);
173 if (r)
174 return r;
175
176 return size;
177}
178
179static ssize_t display_mirror_show(struct omap_dss_device *dssdev, char *buf)
180{
181 int mirror;
182 if (!dssdev->driver->get_mirror)
183 return -ENOENT;
184 mirror = dssdev->driver->get_mirror(dssdev);
185 return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
186}
187
188static ssize_t display_mirror_store(struct omap_dss_device *dssdev,
189 const char *buf, size_t size)
190{
191 int r;
192 bool mirror;
193
194 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
195 return -ENOENT;
196
197 r = strtobool(buf, &mirror);
198 if (r)
199 return r;
200
201 r = dssdev->driver->set_mirror(dssdev, mirror);
202 if (r)
203 return r;
204
205 return size;
206}
207
208static ssize_t display_wss_show(struct omap_dss_device *dssdev, char *buf)
209{
210 unsigned int wss;
211
212 if (!dssdev->driver->get_wss)
213 return -ENOENT;
214
215 wss = dssdev->driver->get_wss(dssdev);
216
217 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
218}
219
220static ssize_t display_wss_store(struct omap_dss_device *dssdev,
221 const char *buf, size_t size)
222{
223 u32 wss;
224 int r;
225
226 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
227 return -ENOENT;
228
229 r = kstrtou32(buf, 0, &wss);
230 if (r)
231 return r;
232
233 if (wss > 0xfffff)
234 return -EINVAL;
235
236 r = dssdev->driver->set_wss(dssdev, wss);
237 if (r)
238 return r;
239
240 return size;
241}
242
243struct display_attribute {
244 struct attribute attr;
245 ssize_t (*show)(struct omap_dss_device *, char *);
246 ssize_t (*store)(struct omap_dss_device *, const char *, size_t);
247};
248
249#define DISPLAY_ATTR(_name, _mode, _show, _store) \
250 struct display_attribute display_attr_##_name = \
251 __ATTR(_name, _mode, _show, _store)
252
253static DISPLAY_ATTR(name, S_IRUGO, display_name_show, NULL);
254static DISPLAY_ATTR(display_name, S_IRUGO, display_name_show, NULL);
255static DISPLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
256 display_enabled_show, display_enabled_store);
257static DISPLAY_ATTR(tear_elim, S_IRUGO|S_IWUSR,
258 display_tear_show, display_tear_store);
259static DISPLAY_ATTR(timings, S_IRUGO|S_IWUSR,
260 display_timings_show, display_timings_store);
261static DISPLAY_ATTR(rotate, S_IRUGO|S_IWUSR,
262 display_rotate_show, display_rotate_store);
263static DISPLAY_ATTR(mirror, S_IRUGO|S_IWUSR,
264 display_mirror_show, display_mirror_store);
265static DISPLAY_ATTR(wss, S_IRUGO|S_IWUSR,
266 display_wss_show, display_wss_store);
267
268static struct attribute *display_sysfs_attrs[] = {
269 &display_attr_name.attr,
270 &display_attr_display_name.attr,
271 &display_attr_enabled.attr,
272 &display_attr_tear_elim.attr,
273 &display_attr_timings.attr,
274 &display_attr_rotate.attr,
275 &display_attr_mirror.attr,
276 &display_attr_wss.attr,
277 NULL
278};
279
280static ssize_t display_attr_show(struct kobject *kobj, struct attribute *attr,
281 char *buf)
282{
283 struct omap_dss_device *dssdev;
284 struct display_attribute *display_attr;
285
286 dssdev = container_of(kobj, struct omap_dss_device, kobj);
287 display_attr = container_of(attr, struct display_attribute, attr);
288
289 if (!display_attr->show)
290 return -ENOENT;
291
292 return display_attr->show(dssdev, buf);
293}
294
295static ssize_t display_attr_store(struct kobject *kobj, struct attribute *attr,
296 const char *buf, size_t size)
297{
298 struct omap_dss_device *dssdev;
299 struct display_attribute *display_attr;
300
301 dssdev = container_of(kobj, struct omap_dss_device, kobj);
302 display_attr = container_of(attr, struct display_attribute, attr);
303
304 if (!display_attr->store)
305 return -ENOENT;
306
307 return display_attr->store(dssdev, buf, size);
308}
309
310static const struct sysfs_ops display_sysfs_ops = {
311 .show = display_attr_show,
312 .store = display_attr_store,
313};
314
315static struct kobj_type display_ktype = {
316 .sysfs_ops = &display_sysfs_ops,
317 .default_attrs = display_sysfs_attrs,
318};
319
320int display_init_sysfs(struct platform_device *pdev)
321{
322 struct omap_dss_device *dssdev = NULL;
323 int r;
324
325 for_each_dss_dev(dssdev) {
326 r = kobject_init_and_add(&dssdev->kobj, &display_ktype,
327 &pdev->dev.kobj, "%s", dssdev->alias);
328 if (r) {
329 DSSERR("failed to create sysfs files\n");
330 omap_dss_put_device(dssdev);
331 goto err;
332 }
333 }
334
335 return 0;
336
337err:
338 display_uninit_sysfs(pdev);
339
340 return r;
341}
342
343void display_uninit_sysfs(struct platform_device *pdev)
344{
345 struct omap_dss_device *dssdev = NULL;
346
347 for_each_dss_dev(dssdev) {
348 if (kobject_name(&dssdev->kobj) == NULL)
349 continue;
350
351 kobject_del(&dssdev->kobj);
352 kobject_put(&dssdev->kobj);
353
354 memset(&dssdev->kobj, 0, sizeof(dssdev->kobj));
355 }
356}