aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/display
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/video/display
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/video/display')
-rw-r--r--drivers/video/display/Kconfig24
-rw-r--r--drivers/video/display/Makefile6
-rw-r--r--drivers/video/display/display-sysfs.c219
3 files changed, 249 insertions, 0 deletions
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
new file mode 100644
index 00000000000..f99af931d4f
--- /dev/null
+++ b/drivers/video/display/Kconfig
@@ -0,0 +1,24 @@
1#
2# Display drivers configuration
3#
4
5menu "Display device support"
6
7config DISPLAY_SUPPORT
8 tristate "Display panel/monitor support"
9 ---help---
10 This framework adds support for low-level control of a display.
11 This includes support for power.
12
13 Enable this to be able to choose the drivers for controlling the
14 physical display panel/monitor on some platforms. This not only
15 covers LCD displays for PDAs but also other types of displays
16 such as CRT, TVout etc.
17
18 To have support for your specific display panel you will have to
19 select the proper drivers which depend on this option.
20
21comment "Display hardware drivers"
22 depends on DISPLAY_SUPPORT
23
24endmenu
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
new file mode 100644
index 00000000000..c0ea832bf17
--- /dev/null
+++ b/drivers/video/display/Makefile
@@ -0,0 +1,6 @@
1# Display drivers
2
3display-objs := display-sysfs.o
4
5obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
6
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
new file mode 100644
index 00000000000..0c647d7af0e
--- /dev/null
+++ b/drivers/video/display/display-sysfs.c
@@ -0,0 +1,219 @@
1/*
2 * display-sysfs.c - Display output driver sysfs interface
3 *
4 * Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24#include <linux/module.h>
25#include <linux/display.h>
26#include <linux/ctype.h>
27#include <linux/idr.h>
28#include <linux/err.h>
29#include <linux/kdev_t.h>
30#include <linux/slab.h>
31
32static ssize_t display_show_name(struct device *dev,
33 struct device_attribute *attr, char *buf)
34{
35 struct display_device *dsp = dev_get_drvdata(dev);
36 return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
37}
38
39static ssize_t display_show_type(struct device *dev,
40 struct device_attribute *attr, char *buf)
41{
42 struct display_device *dsp = dev_get_drvdata(dev);
43 return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
44}
45
46static ssize_t display_show_contrast(struct device *dev,
47 struct device_attribute *attr, char *buf)
48{
49 struct display_device *dsp = dev_get_drvdata(dev);
50 ssize_t rc = -ENXIO;
51
52 mutex_lock(&dsp->lock);
53 if (likely(dsp->driver) && dsp->driver->get_contrast)
54 rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
55 mutex_unlock(&dsp->lock);
56 return rc;
57}
58
59static ssize_t display_store_contrast(struct device *dev,
60 struct device_attribute *attr,
61 const char *buf, size_t count)
62{
63 struct display_device *dsp = dev_get_drvdata(dev);
64 ssize_t ret = -EINVAL, size;
65 int contrast;
66 char *endp;
67
68 contrast = simple_strtoul(buf, &endp, 0);
69 size = endp - buf;
70
71 if (isspace(*endp))
72 size++;
73
74 if (size != count)
75 return ret;
76
77 mutex_lock(&dsp->lock);
78 if (likely(dsp->driver && dsp->driver->set_contrast)) {
79 pr_debug("display: set contrast to %d\n", contrast);
80 dsp->driver->set_contrast(dsp, contrast);
81 ret = count;
82 }
83 mutex_unlock(&dsp->lock);
84 return ret;
85}
86
87static ssize_t display_show_max_contrast(struct device *dev,
88 struct device_attribute *attr,
89 char *buf)
90{
91 struct display_device *dsp = dev_get_drvdata(dev);
92 ssize_t rc = -ENXIO;
93
94 mutex_lock(&dsp->lock);
95 if (likely(dsp->driver))
96 rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
97 mutex_unlock(&dsp->lock);
98 return rc;
99}
100
101static struct device_attribute display_attrs[] = {
102 __ATTR(name, S_IRUGO, display_show_name, NULL),
103 __ATTR(type, S_IRUGO, display_show_type, NULL),
104 __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
105 __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
106};
107
108static int display_suspend(struct device *dev, pm_message_t state)
109{
110 struct display_device *dsp = dev_get_drvdata(dev);
111
112 mutex_lock(&dsp->lock);
113 if (likely(dsp->driver->suspend))
114 dsp->driver->suspend(dsp, state);
115 mutex_unlock(&dsp->lock);
116 return 0;
117};
118
119static int display_resume(struct device *dev)
120{
121 struct display_device *dsp = dev_get_drvdata(dev);
122
123 mutex_lock(&dsp->lock);
124 if (likely(dsp->driver->resume))
125 dsp->driver->resume(dsp);
126 mutex_unlock(&dsp->lock);
127 return 0;
128};
129
130static struct mutex allocated_dsp_lock;
131static DEFINE_IDR(allocated_dsp);
132static struct class *display_class;
133
134struct display_device *display_device_register(struct display_driver *driver,
135 struct device *parent, void *devdata)
136{
137 struct display_device *new_dev = NULL;
138 int ret = -EINVAL;
139
140 if (unlikely(!driver))
141 return ERR_PTR(ret);
142
143 mutex_lock(&allocated_dsp_lock);
144 ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
145 mutex_unlock(&allocated_dsp_lock);
146 if (!ret)
147 return ERR_PTR(ret);
148
149 new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
150 if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
151 // Reserve the index for this display
152 mutex_lock(&allocated_dsp_lock);
153 ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
154 mutex_unlock(&allocated_dsp_lock);
155
156 if (!ret) {
157 new_dev->dev = device_create(display_class, parent,
158 MKDEV(0, 0), new_dev,
159 "display%d", new_dev->idx);
160 if (!IS_ERR(new_dev->dev)) {
161 new_dev->parent = parent;
162 new_dev->driver = driver;
163 mutex_init(&new_dev->lock);
164 return new_dev;
165 }
166 mutex_lock(&allocated_dsp_lock);
167 idr_remove(&allocated_dsp, new_dev->idx);
168 mutex_unlock(&allocated_dsp_lock);
169 ret = -EINVAL;
170 }
171 }
172 kfree(new_dev);
173 return ERR_PTR(ret);
174}
175EXPORT_SYMBOL(display_device_register);
176
177void display_device_unregister(struct display_device *ddev)
178{
179 if (!ddev)
180 return;
181 // Free device
182 mutex_lock(&ddev->lock);
183 device_unregister(ddev->dev);
184 mutex_unlock(&ddev->lock);
185 // Mark device index as available
186 mutex_lock(&allocated_dsp_lock);
187 idr_remove(&allocated_dsp, ddev->idx);
188 mutex_unlock(&allocated_dsp_lock);
189 kfree(ddev);
190}
191EXPORT_SYMBOL(display_device_unregister);
192
193static int __init display_class_init(void)
194{
195 display_class = class_create(THIS_MODULE, "display");
196 if (IS_ERR(display_class)) {
197 printk(KERN_ERR "Failed to create display class\n");
198 display_class = NULL;
199 return -EINVAL;
200 }
201 display_class->dev_attrs = display_attrs;
202 display_class->suspend = display_suspend;
203 display_class->resume = display_resume;
204 mutex_init(&allocated_dsp_lock);
205 return 0;
206}
207
208static void __exit display_class_exit(void)
209{
210 class_destroy(display_class);
211}
212
213module_init(display_class_init);
214module_exit(display_class_exit);
215
216MODULE_DESCRIPTION("Display Hardware handling");
217MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
218MODULE_LICENSE("GPL");
219