2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
5 * Some code and ideas taken from drivers/video/omap/ driver
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.
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
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/>.
21 #define DSS_SUBSYS_NAME "DISPLAY"
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26 #include <linux/sysfs.h>
28 #include <video/omapdss.h>
31 static struct omap_dss_device
*to_dss_device_sysfs(struct device
*dev
)
33 struct omap_dss_device
*dssdev
= NULL
;
35 for_each_dss_dev(dssdev
) {
36 if (dssdev
->dev
== dev
) {
37 omap_dss_put_device(dssdev
);
45 static ssize_t
display_name_show(struct device
*dev
,
46 struct device_attribute
*attr
, char *buf
)
48 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
50 return snprintf(buf
, PAGE_SIZE
, "%s\n",
55 static ssize_t
display_enabled_show(struct device
*dev
,
56 struct device_attribute
*attr
, char *buf
)
58 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
60 return snprintf(buf
, PAGE_SIZE
, "%d\n",
61 omapdss_device_is_enabled(dssdev
));
64 static ssize_t
display_enabled_store(struct device
*dev
,
65 struct device_attribute
*attr
,
66 const char *buf
, size_t size
)
68 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
72 r
= strtobool(buf
, &enable
);
76 if (enable
== omapdss_device_is_enabled(dssdev
))
79 if (omapdss_device_is_connected(dssdev
) == false)
83 r
= dssdev
->driver
->enable(dssdev
);
87 dssdev
->driver
->disable(dssdev
);
93 static ssize_t
display_tear_show(struct device
*dev
,
94 struct device_attribute
*attr
, char *buf
)
96 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
97 return snprintf(buf
, PAGE_SIZE
, "%d\n",
98 dssdev
->driver
->get_te
?
99 dssdev
->driver
->get_te(dssdev
) : 0);
102 static ssize_t
display_tear_store(struct device
*dev
,
103 struct device_attribute
*attr
, const char *buf
, size_t size
)
105 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
109 if (!dssdev
->driver
->enable_te
|| !dssdev
->driver
->get_te
)
112 r
= strtobool(buf
, &te
);
116 r
= dssdev
->driver
->enable_te(dssdev
, te
);
123 static ssize_t
display_timings_show(struct device
*dev
,
124 struct device_attribute
*attr
, char *buf
)
126 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
127 struct omap_video_timings t
;
129 if (!dssdev
->driver
->get_timings
)
132 dssdev
->driver
->get_timings(dssdev
, &t
);
134 return snprintf(buf
, PAGE_SIZE
, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
136 t
.x_res
, t
.hfp
, t
.hbp
, t
.hsw
,
137 t
.y_res
, t
.vfp
, t
.vbp
, t
.vsw
);
140 static ssize_t
display_timings_store(struct device
*dev
,
141 struct device_attribute
*attr
, const char *buf
, size_t size
)
143 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
144 struct omap_video_timings t
= dssdev
->panel
.timings
;
147 if (!dssdev
->driver
->set_timings
|| !dssdev
->driver
->check_timings
)
151 #ifdef CONFIG_OMAP2_DSS_VENC
152 if (strncmp("pal", buf
, 3) == 0) {
153 t
= omap_dss_pal_timings
;
155 } else if (strncmp("ntsc", buf
, 4) == 0) {
156 t
= omap_dss_ntsc_timings
;
160 if (!found
&& sscanf(buf
, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
162 &t
.x_res
, &t
.hfp
, &t
.hbp
, &t
.hsw
,
163 &t
.y_res
, &t
.vfp
, &t
.vbp
, &t
.vsw
) != 9)
166 r
= dssdev
->driver
->check_timings(dssdev
, &t
);
170 dssdev
->driver
->disable(dssdev
);
171 dssdev
->driver
->set_timings(dssdev
, &t
);
172 r
= dssdev
->driver
->enable(dssdev
);
179 static ssize_t
display_rotate_show(struct device
*dev
,
180 struct device_attribute
*attr
, char *buf
)
182 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
184 if (!dssdev
->driver
->get_rotate
)
186 rotate
= dssdev
->driver
->get_rotate(dssdev
);
187 return snprintf(buf
, PAGE_SIZE
, "%u\n", rotate
);
190 static ssize_t
display_rotate_store(struct device
*dev
,
191 struct device_attribute
*attr
, const char *buf
, size_t size
)
193 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
196 if (!dssdev
->driver
->set_rotate
|| !dssdev
->driver
->get_rotate
)
199 r
= kstrtoint(buf
, 0, &rot
);
203 r
= dssdev
->driver
->set_rotate(dssdev
, rot
);
210 static ssize_t
display_mirror_show(struct device
*dev
,
211 struct device_attribute
*attr
, char *buf
)
213 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
215 if (!dssdev
->driver
->get_mirror
)
217 mirror
= dssdev
->driver
->get_mirror(dssdev
);
218 return snprintf(buf
, PAGE_SIZE
, "%u\n", mirror
);
221 static ssize_t
display_mirror_store(struct device
*dev
,
222 struct device_attribute
*attr
, const char *buf
, size_t size
)
224 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
228 if (!dssdev
->driver
->set_mirror
|| !dssdev
->driver
->get_mirror
)
231 r
= strtobool(buf
, &mirror
);
235 r
= dssdev
->driver
->set_mirror(dssdev
, mirror
);
242 static ssize_t
display_wss_show(struct device
*dev
,
243 struct device_attribute
*attr
, char *buf
)
245 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
248 if (!dssdev
->driver
->get_wss
)
251 wss
= dssdev
->driver
->get_wss(dssdev
);
253 return snprintf(buf
, PAGE_SIZE
, "0x%05x\n", wss
);
256 static ssize_t
display_wss_store(struct device
*dev
,
257 struct device_attribute
*attr
, const char *buf
, size_t size
)
259 struct omap_dss_device
*dssdev
= to_dss_device_sysfs(dev
);
263 if (!dssdev
->driver
->get_wss
|| !dssdev
->driver
->set_wss
)
266 r
= kstrtou32(buf
, 0, &wss
);
273 r
= dssdev
->driver
->set_wss(dssdev
, wss
);
280 static DEVICE_ATTR(name
, S_IRUGO
, display_name_show
, NULL
);
281 static DEVICE_ATTR(enabled
, S_IRUGO
|S_IWUSR
,
282 display_enabled_show
, display_enabled_store
);
283 static DEVICE_ATTR(tear_elim
, S_IRUGO
|S_IWUSR
,
284 display_tear_show
, display_tear_store
);
285 static DEVICE_ATTR(timings
, S_IRUGO
|S_IWUSR
,
286 display_timings_show
, display_timings_store
);
287 static DEVICE_ATTR(rotate
, S_IRUGO
|S_IWUSR
,
288 display_rotate_show
, display_rotate_store
);
289 static DEVICE_ATTR(mirror
, S_IRUGO
|S_IWUSR
,
290 display_mirror_show
, display_mirror_store
);
291 static DEVICE_ATTR(wss
, S_IRUGO
|S_IWUSR
,
292 display_wss_show
, display_wss_store
);
294 static const struct attribute
*display_sysfs_attrs
[] = {
296 &dev_attr_enabled
.attr
,
297 &dev_attr_tear_elim
.attr
,
298 &dev_attr_timings
.attr
,
299 &dev_attr_rotate
.attr
,
300 &dev_attr_mirror
.attr
,
305 int display_init_sysfs(struct platform_device
*pdev
)
307 struct omap_dss_device
*dssdev
= NULL
;
310 for_each_dss_dev(dssdev
) {
311 struct kobject
*kobj
= &dssdev
->dev
->kobj
;
313 r
= sysfs_create_files(kobj
, display_sysfs_attrs
);
315 DSSERR("failed to create sysfs files\n");
319 r
= sysfs_create_link(&pdev
->dev
.kobj
, kobj
, dssdev
->alias
);
321 sysfs_remove_files(kobj
, display_sysfs_attrs
);
323 DSSERR("failed to create sysfs display link\n");
331 display_uninit_sysfs(pdev
);
336 void display_uninit_sysfs(struct platform_device
*pdev
)
338 struct omap_dss_device
*dssdev
= NULL
;
340 for_each_dss_dev(dssdev
) {
341 sysfs_remove_link(&pdev
->dev
.kobj
, dssdev
->alias
);
342 sysfs_remove_files(&dssdev
->dev
->kobj
,
343 display_sysfs_attrs
);