aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dc_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/dc/dc_sysfs.c')
-rw-r--r--drivers/video/tegra/dc/dc_sysfs.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/dc_sysfs.c b/drivers/video/tegra/dc/dc_sysfs.c
new file mode 100644
index 00000000000..6bb18382e6e
--- /dev/null
+++ b/drivers/video/tegra/dc/dc_sysfs.c
@@ -0,0 +1,327 @@
1/*
2 * drivers/video/tegra/dc/dc_sysfs.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/platform_device.h>
22#include <linux/kernel.h>
23
24#include <mach/dc.h>
25#include <mach/fb.h>
26
27#include "dc_reg.h"
28#include "dc_priv.h"
29#include "nvsd.h"
30
31static ssize_t mode_show(struct device *device,
32 struct device_attribute *attr, char *buf)
33{
34 struct nvhost_device *ndev = to_nvhost_device(device);
35 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
36 struct tegra_dc_mode *m;
37 ssize_t res;
38
39 mutex_lock(&dc->lock);
40 m = &dc->mode;
41 res = snprintf(buf, PAGE_SIZE,
42 "pclk: %d\n"
43 "h_ref_to_sync: %d\n"
44 "v_ref_to_sync: %d\n"
45 "h_sync_width: %d\n"
46 "v_sync_width: %d\n"
47 "h_back_porch: %d\n"
48 "v_back_porch: %d\n"
49 "h_active: %d\n"
50 "v_active: %d\n"
51 "h_front_porch: %d\n"
52 "v_front_porch: %d\n"
53 "stereo_mode: %d\n",
54 m->pclk, m->h_ref_to_sync, m->v_ref_to_sync,
55 m->h_sync_width, m->v_sync_width,
56 m->h_back_porch, m->v_back_porch,
57 m->h_active, m->v_active,
58 m->h_front_porch, m->v_front_porch,
59 m->stereo_mode);
60 mutex_unlock(&dc->lock);
61
62 return res;
63}
64
65static DEVICE_ATTR(mode, S_IRUGO, mode_show, NULL);
66
67static ssize_t stats_enable_show(struct device *dev,
68 struct device_attribute *attr, char *buf)
69{
70 struct nvhost_device *ndev = to_nvhost_device(dev);
71 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
72 bool enabled;
73
74 if (mutex_lock_killable(&dc->lock))
75 return -EINTR;
76 enabled = tegra_dc_stats_get(dc);
77 mutex_unlock(&dc->lock);
78
79 return snprintf(buf, PAGE_SIZE, "%d", enabled);
80}
81
82static ssize_t stats_enable_store(struct device *dev,
83 struct device_attribute *attr, const char *buf, size_t count)
84{
85 struct nvhost_device *ndev = to_nvhost_device(dev);
86 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
87 unsigned long val = 0;
88
89 if (strict_strtoul(buf, 10, &val) < 0)
90 return -EINVAL;
91
92 if (mutex_lock_killable(&dc->lock))
93 return -EINTR;
94 tegra_dc_stats_enable(dc, !!val);
95 mutex_unlock(&dc->lock);
96
97 return count;
98}
99
100static DEVICE_ATTR(stats_enable, S_IRUGO|S_IWUSR,
101 stats_enable_show, stats_enable_store);
102
103static ssize_t enable_show(struct device *device,
104 struct device_attribute *attr, char *buf)
105{
106 struct nvhost_device *ndev = to_nvhost_device(device);
107 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
108 ssize_t res;
109
110 mutex_lock(&dc->lock);
111 res = snprintf(buf, PAGE_SIZE, "%d\n", dc->enabled);
112 mutex_unlock(&dc->lock);
113 return res;
114}
115
116static ssize_t enable_store(struct device *dev,
117 struct device_attribute *attr, const char *buf, size_t count)
118{
119 struct nvhost_device *ndev = to_nvhost_device(dev);
120 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
121 unsigned long val = 0;
122
123 if (strict_strtoul(buf, 10, &val) < 0)
124 return -EINVAL;
125
126 if (val) {
127 tegra_dc_enable(dc);
128 } else {
129 tegra_dc_disable(dc);
130 }
131
132 return count;
133}
134
135static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, enable_show, enable_store);
136
137static ssize_t crc_checksum_latched_show(struct device *device,
138 struct device_attribute *attr, char *buf)
139{
140 struct nvhost_device *ndev = to_nvhost_device(device);
141 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
142
143 u32 crc;
144
145 if (!dc->enabled) {
146 dev_err(&dc->ndev->dev, "Failed to get dc.\n");
147 return -EFAULT;
148 }
149
150 crc = tegra_dc_read_checksum_latched(dc);
151
152 return snprintf(buf, PAGE_SIZE, "%u", crc);
153}
154
155static ssize_t crc_checksum_latched_store(struct device *dev,
156 struct device_attribute *attr, const char *buf, size_t count)
157{
158 struct nvhost_device *ndev = to_nvhost_device(dev);
159 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
160 unsigned long val = 0;
161
162 if (!dc->enabled) {
163 dev_err(&dc->ndev->dev, "Failed to get dc.\n");
164 return -EFAULT;
165 }
166
167 if (strict_strtoul(buf, 10, &val) < 0)
168 return -EINVAL;
169
170 if (val == 1) {
171 tegra_dc_enable_crc(dc);
172 dev_err(&dc->ndev->dev, "crc is enabled.\n");
173 } else if (val == 0) {
174 tegra_dc_disable_crc(dc);
175 dev_err(&dc->ndev->dev, "crc is disabled.\n");
176 } else
177 dev_err(&dc->ndev->dev, "Invalid input.\n");
178
179 return count;
180}
181static DEVICE_ATTR(crc_checksum_latched, S_IRUGO|S_IWUSR,
182 crc_checksum_latched_show, crc_checksum_latched_store);
183
184#define ORIENTATION_PORTRAIT "portrait"
185#define ORIENTATION_LANDSCAPE "landscape"
186
187static ssize_t orientation_3d_show(struct device *dev,
188 struct device_attribute *attr, char *buf)
189{
190 struct nvhost_device *ndev = to_nvhost_device(dev);
191 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
192 struct tegra_dc_out *dc_out = dc->out;
193 const char *orientation;
194 switch (dc_out->stereo->orientation) {
195 case TEGRA_DC_STEREO_LANDSCAPE:
196 orientation = ORIENTATION_LANDSCAPE;
197 break;
198 case TEGRA_DC_STEREO_PORTRAIT:
199 orientation = ORIENTATION_PORTRAIT;
200 break;
201 default:
202 pr_err("Invalid value is stored for stereo_orientation.\n");
203 return -EINVAL;
204 }
205 return snprintf(buf, PAGE_SIZE, "%s\n", orientation);
206}
207
208static ssize_t orientation_3d_store(struct device *dev,
209 struct device_attribute *attr, const char *buf, size_t cnt)
210{
211 struct nvhost_device *ndev = to_nvhost_device(dev);
212 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
213 struct tegra_dc_out *dc_out = dc->out;
214 struct tegra_stereo_out *stereo = dc_out->stereo;
215 int orientation;
216
217 if (0 == strncmp(buf, ORIENTATION_PORTRAIT,
218 min(cnt, ARRAY_SIZE(ORIENTATION_PORTRAIT) - 1))) {
219 orientation = TEGRA_DC_STEREO_PORTRAIT;
220 } else if (0 == strncmp(buf, ORIENTATION_LANDSCAPE,
221 min(cnt, ARRAY_SIZE(ORIENTATION_LANDSCAPE) - 1))) {
222 orientation = TEGRA_DC_STEREO_LANDSCAPE;
223 } else {
224 pr_err("Invalid property value for stereo_orientation.\n");
225 return -EINVAL;
226 }
227 stereo->orientation = orientation;
228 stereo->set_orientation(orientation);
229 return cnt;
230}
231
232static DEVICE_ATTR(stereo_orientation,
233 S_IRUGO|S_IWUSR, orientation_3d_show, orientation_3d_store);
234
235#define MODE_2D "2d"
236#define MODE_3D "3d"
237
238static ssize_t mode_3d_show(struct device *dev,
239 struct device_attribute *attr, char *buf)
240{
241 struct nvhost_device *ndev = to_nvhost_device(dev);
242 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
243 struct tegra_dc_out *dc_out = dc->out;
244 const char *mode;
245 switch (dc_out->stereo->mode_2d_3d) {
246 case TEGRA_DC_STEREO_MODE_2D:
247 mode = MODE_2D;
248 break;
249 case TEGRA_DC_STEREO_MODE_3D:
250 mode = MODE_3D;
251 break;
252 default:
253 pr_err("Invalid value is stored for stereo_mode.\n");
254 return -EINVAL;
255 }
256 return snprintf(buf, PAGE_SIZE, "%s\n", mode);
257}
258
259static ssize_t mode_3d_store(struct device *dev,
260 struct device_attribute *attr, const char *buf, size_t cnt)
261{
262 struct nvhost_device *ndev = to_nvhost_device(dev);
263 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
264 struct tegra_dc_out *dc_out = dc->out;
265 struct tegra_stereo_out *stereo = dc_out->stereo;
266 int mode;
267
268 if (0 == strncmp(buf, MODE_2D, min(cnt, ARRAY_SIZE(MODE_2D) - 1))) {
269 mode = TEGRA_DC_STEREO_MODE_2D;
270 } else if (0 == strncmp(buf, MODE_3D,
271 min(cnt, ARRAY_SIZE(MODE_3D) - 1))) {
272 mode = TEGRA_DC_STEREO_MODE_3D;
273 } else {
274 pr_err("Invalid property value for stereo_mode.\n");
275 return -EINVAL;
276 }
277 stereo->mode_2d_3d = mode;
278 stereo->set_mode(mode);
279 return cnt;
280}
281
282static DEVICE_ATTR(stereo_mode,
283 S_IRUGO|S_IWUSR, mode_3d_show, mode_3d_store);
284
285void __devexit tegra_dc_remove_sysfs(struct device *dev)
286{
287 struct nvhost_device *ndev = to_nvhost_device(dev);
288 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
289 struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings;
290
291 device_remove_file(dev, &dev_attr_mode);
292 device_remove_file(dev, &dev_attr_enable);
293 device_remove_file(dev, &dev_attr_stats_enable);
294 device_remove_file(dev, &dev_attr_crc_checksum_latched);
295
296 if (dc->out->stereo) {
297 device_remove_file(dev, &dev_attr_stereo_orientation);
298 device_remove_file(dev, &dev_attr_stereo_mode);
299 }
300
301 if (sd_settings)
302 nvsd_remove_sysfs(dev);
303}
304
305void tegra_dc_create_sysfs(struct device *dev)
306{
307 struct nvhost_device *ndev = to_nvhost_device(dev);
308 struct tegra_dc *dc = nvhost_get_drvdata(ndev);
309 struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings;
310 int error = 0;
311
312 error |= device_create_file(dev, &dev_attr_mode);
313 error |= device_create_file(dev, &dev_attr_enable);
314 error |= device_create_file(dev, &dev_attr_stats_enable);
315 error |= device_create_file(dev, &dev_attr_crc_checksum_latched);
316
317 if (dc->out->stereo) {
318 error |= device_create_file(dev, &dev_attr_stereo_orientation);
319 error |= device_create_file(dev, &dev_attr_stereo_mode);
320 }
321
322 if (sd_settings)
323 error |= nvsd_create_sysfs(dev);
324
325 if (error)
326 dev_err(&ndev->dev, "Failed to create sysfs attributes!\n");
327}