video: tegra: dc: add sysfs interface for hdmi settings
[linux-3.10.git] / drivers / video / tegra / dc / dc_sysfs.c
1 /*
2  * drivers/video/tegra/dc/dc_sysfs.c
3  *
4  * Copyright (c) 2011-2013, NVIDIA CORPORATION, All rights reserved.
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/fb.h>
22 #include <linux/platform_device.h>
23 #include <linux/kernel.h>
24
25 #include <mach/dc.h>
26 #include <mach/fb.h>
27
28 #include <linux/nvmap.h>
29 #include "dc_reg.h"
30 #include "dc_priv.h"
31 #include "nvsd.h"
32 #include "hdmi.h"
33
34 static ssize_t mode_show(struct device *device,
35         struct device_attribute *attr, char *buf)
36 {
37         struct platform_device *ndev = to_platform_device(device);
38         struct tegra_dc *dc = platform_get_drvdata(ndev);
39         struct tegra_dc_mode *m;
40         ssize_t res;
41
42         mutex_lock(&dc->lock);
43         m = &dc->mode;
44         res = snprintf(buf, PAGE_SIZE,
45                 "pclk: %d\n"
46                 "h_ref_to_sync: %d\n"
47                 "v_ref_to_sync: %d\n"
48                 "h_sync_width: %d\n"
49                 "v_sync_width: %d\n"
50                 "h_back_porch: %d\n"
51                 "v_back_porch: %d\n"
52                 "h_active: %d\n"
53                 "v_active: %d\n"
54                 "h_front_porch: %d\n"
55                 "v_front_porch: %d\n"
56                 "stereo_mode: %d\n",
57                 m->pclk, m->h_ref_to_sync, m->v_ref_to_sync,
58                 m->h_sync_width, m->v_sync_width,
59                 m->h_back_porch, m->v_back_porch,
60                 m->h_active, m->v_active,
61                 m->h_front_porch, m->v_front_porch,
62                 m->stereo_mode);
63         mutex_unlock(&dc->lock);
64
65         return res;
66 }
67
68 static DEVICE_ATTR(mode, S_IRUGO, mode_show, NULL);
69
70 static ssize_t stats_enable_show(struct device *dev,
71         struct device_attribute *attr, char *buf)
72 {
73         struct platform_device *ndev = to_platform_device(dev);
74         struct tegra_dc *dc = platform_get_drvdata(ndev);
75         bool enabled;
76
77         if (mutex_lock_killable(&dc->lock))
78                 return -EINTR;
79         enabled = tegra_dc_stats_get(dc);
80         mutex_unlock(&dc->lock);
81
82         return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
83 }
84
85 static ssize_t stats_enable_store(struct device *dev,
86         struct device_attribute *attr, const char *buf, size_t count)
87 {
88         struct platform_device *ndev = to_platform_device(dev);
89         struct tegra_dc *dc = platform_get_drvdata(ndev);
90         unsigned long val = 0;
91
92         if (strict_strtoul(buf, 10, &val) < 0)
93                 return -EINVAL;
94
95         if (mutex_lock_killable(&dc->lock))
96                 return -EINTR;
97         tegra_dc_stats_enable(dc, !!val);
98         mutex_unlock(&dc->lock);
99
100         return count;
101 }
102
103 static DEVICE_ATTR(stats_enable, S_IRUGO|S_IWUSR,
104         stats_enable_show, stats_enable_store);
105
106 static ssize_t enable_show(struct device *device,
107         struct device_attribute *attr, char *buf)
108 {
109         struct platform_device *ndev = to_platform_device(device);
110         struct tegra_dc *dc = platform_get_drvdata(ndev);
111         ssize_t res;
112
113         mutex_lock(&dc->lock);
114         res = snprintf(buf, PAGE_SIZE, "%d\n", dc->enabled);
115         mutex_unlock(&dc->lock);
116         return res;
117 }
118
119 static ssize_t enable_store(struct device *dev,
120         struct device_attribute *attr, const char *buf, size_t count)
121 {
122         struct platform_device *ndev = to_platform_device(dev);
123         struct tegra_dc *dc = platform_get_drvdata(ndev);
124         unsigned long val = 0;
125
126         if (strict_strtoul(buf, 10, &val) < 0)
127                 return -EINVAL;
128
129         if (val) {
130                 tegra_dc_enable(dc);
131         } else {
132                 tegra_dc_disable(dc);
133         }
134
135         return count;
136 }
137
138 static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, enable_show, enable_store);
139
140 #ifdef CONFIG_TEGRA_DC_WIN_H
141 static ssize_t win_h_show(struct device *device,
142         struct device_attribute *attr, char *buf)
143 {
144         struct platform_device *ndev = to_platform_device(device);
145         struct tegra_dc *dc = platform_get_drvdata(ndev);
146         unsigned long val = 0;
147
148         mutex_lock(&dc->lock);
149         tegra_dc_io_start(dc);
150
151         val = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL);
152
153         tegra_dc_io_end(dc);
154         mutex_unlock(&dc->lock);
155
156         return snprintf(buf, PAGE_SIZE, "%u\n", !!(val & WINH_CURS_SELECT(1)));
157 }
158
159 /* win_h sysfs controls hybrid window.
160  *
161  * 0 = cursor mode and 1 = window mode (default on T14x) */
162 static ssize_t win_h_store(struct device *dev,
163         struct device_attribute *attr, const char *buf, size_t count)
164 {
165         struct platform_device *ndev = to_platform_device(dev);
166         struct tegra_dc *dc = platform_get_drvdata(ndev);
167         unsigned int val = 0;
168         unsigned long cursor_val = 0;
169
170         if (!dc->enabled) {
171                 dev_err(&dc->ndev->dev, "%s: DC not enabled.\n", __func__);
172                 return -EFAULT;
173         }
174
175         if (kstrtouint(buf, 10, &val) < 0)
176                 return -EINVAL;
177
178         mutex_lock(&dc->lock);
179         tegra_dc_io_start(dc);
180
181         cursor_val = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL);
182         cursor_val &= ~WINH_CURS_SELECT(1);
183         if (val)
184                 cursor_val |= WINH_CURS_SELECT(1);
185         tegra_dc_writel(dc, cursor_val, DC_DISP_BLEND_CURSOR_CONTROL);
186
187         tegra_dc_io_end(dc);
188         mutex_unlock(&dc->lock);
189
190         return count;
191 }
192
193 static DEVICE_ATTR(win_h, S_IRUGO|S_IWUSR, win_h_show, win_h_store);
194 #endif
195
196 static ssize_t crc_checksum_latched_show(struct device *device,
197         struct device_attribute *attr, char *buf)
198 {
199         struct platform_device *ndev = to_platform_device(device);
200         struct tegra_dc *dc = platform_get_drvdata(ndev);
201
202         u32 crc;
203
204         if (!dc->enabled) {
205                 dev_err(&dc->ndev->dev, "%s: DC not enabled.\n", __func__);
206                 return -EFAULT;
207         }
208
209         crc = tegra_dc_read_checksum_latched(dc);
210
211         return snprintf(buf, PAGE_SIZE, "%u\n", crc);
212 }
213
214 static ssize_t crc_checksum_latched_store(struct device *dev,
215         struct device_attribute *attr, const char *buf, size_t count)
216 {
217         struct platform_device *ndev = to_platform_device(dev);
218         struct tegra_dc *dc = platform_get_drvdata(ndev);
219         unsigned long val = 0;
220
221         if (!dc->enabled) {
222                 dev_err(&dc->ndev->dev, "%s: DC not enabled.\n", __func__);
223                 return -EFAULT;
224         }
225
226         if (strict_strtoul(buf, 10, &val) < 0)
227                 return -EINVAL;
228
229         if (val == 1) {
230                 tegra_dc_enable_crc(dc);
231                 dev_dbg(&dc->ndev->dev, "crc is enabled.\n");
232         } else if (val == 0) {
233                 tegra_dc_disable_crc(dc);
234                 dev_dbg(&dc->ndev->dev, "crc is disabled.\n");
235         } else
236                 dev_err(&dc->ndev->dev, "Invalid input.\n");
237
238         return count;
239 }
240 static DEVICE_ATTR(crc_checksum_latched, S_IRUGO|S_IWUSR,
241                 crc_checksum_latched_show, crc_checksum_latched_store);
242
243 #define ORIENTATION_PORTRAIT    "portrait"
244 #define ORIENTATION_LANDSCAPE   "landscape"
245
246 static ssize_t orientation_3d_show(struct device *dev,
247         struct device_attribute *attr, char *buf)
248 {
249         struct platform_device *ndev = to_platform_device(dev);
250         struct tegra_dc *dc = platform_get_drvdata(ndev);
251         struct tegra_dc_out *dc_out = dc->out;
252         const char *orientation;
253         switch (dc_out->stereo->orientation) {
254         case TEGRA_DC_STEREO_LANDSCAPE:
255                 orientation = ORIENTATION_LANDSCAPE;
256                 break;
257         case TEGRA_DC_STEREO_PORTRAIT:
258                 orientation = ORIENTATION_PORTRAIT;
259                 break;
260         default:
261                 pr_err("Invalid value is stored for stereo_orientation.\n");
262                 return -EINVAL;
263         }
264         return snprintf(buf, PAGE_SIZE, "%s\n", orientation);
265 }
266
267 static ssize_t orientation_3d_store(struct device *dev,
268         struct device_attribute *attr, const char *buf, size_t cnt)
269 {
270         struct platform_device *ndev = to_platform_device(dev);
271         struct tegra_dc *dc = platform_get_drvdata(ndev);
272         struct tegra_dc_out *dc_out = dc->out;
273         struct tegra_stereo_out *stereo = dc_out->stereo;
274         int orientation;
275
276         if (0 == strncmp(buf, ORIENTATION_PORTRAIT,
277                         min(cnt, ARRAY_SIZE(ORIENTATION_PORTRAIT) - 1))) {
278                 orientation = TEGRA_DC_STEREO_PORTRAIT;
279         } else if (0 == strncmp(buf, ORIENTATION_LANDSCAPE,
280                         min(cnt, ARRAY_SIZE(ORIENTATION_LANDSCAPE) - 1))) {
281                 orientation = TEGRA_DC_STEREO_LANDSCAPE;
282         } else {
283                 pr_err("Invalid property value for stereo_orientation.\n");
284                 return -EINVAL;
285         }
286         stereo->orientation = orientation;
287         stereo->set_orientation(orientation);
288         return cnt;
289 }
290
291 static DEVICE_ATTR(stereo_orientation,
292         S_IRUGO|S_IWUSR, orientation_3d_show, orientation_3d_store);
293
294 #define MODE_2D         "2d"
295 #define MODE_3D         "3d"
296
297 static ssize_t mode_3d_show(struct device *dev,
298         struct device_attribute *attr, char *buf)
299 {
300         struct platform_device *ndev = to_platform_device(dev);
301         struct tegra_dc *dc = platform_get_drvdata(ndev);
302         struct tegra_dc_out *dc_out = dc->out;
303         const char *mode;
304         switch (dc_out->stereo->mode_2d_3d) {
305         case TEGRA_DC_STEREO_MODE_2D:
306                 mode = MODE_2D;
307                 break;
308         case TEGRA_DC_STEREO_MODE_3D:
309                 mode = MODE_3D;
310                 break;
311         default:
312                 pr_err("Invalid value is stored for stereo_mode.\n");
313                 return -EINVAL;
314         }
315         return snprintf(buf, PAGE_SIZE, "%s\n", mode);
316 }
317
318 static ssize_t mode_3d_store(struct device *dev,
319         struct device_attribute *attr, const char *buf, size_t cnt)
320 {
321         struct platform_device *ndev = to_platform_device(dev);
322         struct tegra_dc *dc = platform_get_drvdata(ndev);
323         struct tegra_dc_out *dc_out = dc->out;
324         struct tegra_stereo_out *stereo = dc_out->stereo;
325         int mode;
326
327         if (0 == strncmp(buf, MODE_2D, min(cnt, ARRAY_SIZE(MODE_2D) - 1))) {
328                 mode = TEGRA_DC_STEREO_MODE_2D;
329         } else if (0 == strncmp(buf, MODE_3D,
330                         min(cnt, ARRAY_SIZE(MODE_3D) - 1))) {
331                 mode = TEGRA_DC_STEREO_MODE_3D;
332         } else {
333                 pr_err("Invalid property value for stereo_mode.\n");
334                 return -EINVAL;
335         }
336         stereo->mode_2d_3d = mode;
337         stereo->set_mode(mode);
338         return cnt;
339 }
340
341 static DEVICE_ATTR(stereo_mode,
342         S_IRUGO|S_IWUSR, mode_3d_show, mode_3d_store);
343
344 static ssize_t nvdps_show(struct device *device,
345         struct device_attribute *attr, char *buf)
346 {
347         int refresh_rate;
348         struct platform_device *ndev = to_platform_device(device);
349         struct tegra_dc *dc = platform_get_drvdata(ndev);
350
351         refresh_rate = tegra_fb_get_mode(dc);
352         return snprintf(buf, PAGE_SIZE, "%d\n", refresh_rate);
353 }
354
355
356 static ssize_t nvdps_store(struct device *dev,
357         struct device_attribute *attr, const char *buf, size_t count)
358 {
359         struct platform_device *ndev = to_platform_device(dev);
360         struct tegra_dc *dc = platform_get_drvdata(ndev);
361         int refresh_rate;
362         int e;
363
364         e = kstrtoint(buf, 10, &refresh_rate);
365         if (e)
366                 return e;
367         e = tegra_fb_set_mode(dc, refresh_rate);
368
369         return count;
370 }
371
372 static DEVICE_ATTR(nvdps, S_IRUGO|S_IWUSR, nvdps_show, nvdps_store);
373
374 #ifdef CONFIG_TEGRA_DC_CMU
375 static ssize_t cmu_enable_store(struct device *dev,
376         struct device_attribute *attr, const char *buf, size_t count)
377 {
378         int val;
379         int e;
380         struct platform_device *ndev = to_platform_device(dev);
381         struct tegra_dc *dc = platform_get_drvdata(ndev);
382
383         e = kstrtoint(buf, 10, &val);
384         if (e)
385                 return e;
386
387         tegra_dc_cmu_enable(dc, val);
388
389         return count;
390 }
391
392 static ssize_t cmu_enable_show(struct device *dev,
393         struct device_attribute *attr, char *buf)
394 {
395         struct platform_device *ndev = to_platform_device(dev);
396         struct tegra_dc *dc = platform_get_drvdata(ndev);
397
398         return snprintf(buf, PAGE_SIZE, "%d\n", dc->pdata->cmu_enable);
399 }
400
401 static DEVICE_ATTR(cmu_enable,
402                 S_IRUGO|S_IWUSR, cmu_enable_show, cmu_enable_store);
403 #endif
404 static ssize_t smart_panel_show(struct device *device,
405         struct device_attribute *attr, char  *buf)
406 {
407         return snprintf(buf, PAGE_SIZE, "1\n");
408 }
409
410 static DEVICE_ATTR(smart_panel, S_IRUGO, smart_panel_show, NULL);
411
412 static ssize_t pclk_show(struct device *device,
413         struct device_attribute *attr, char *buf)
414 {
415         struct platform_device *ndev = to_platform_device(device);
416         struct tegra_dc *dc = platform_get_drvdata(ndev);
417         ssize_t res = 0;
418         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
419
420         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
421                 mutex_lock(&dc->lock);
422                 res = snprintf(buf, PAGE_SIZE, "%d\n",
423                                 hdmi_out->tmds_config[0].pclk);
424                 mutex_unlock(&dc->lock);
425         }
426
427         return res;
428 }
429
430 static ssize_t pclk_store(struct device *dev,
431         struct device_attribute *attr, const char *buf, size_t count)
432 {
433         struct platform_device *ndev = to_platform_device(dev);
434         struct tegra_dc *dc = platform_get_drvdata(ndev);
435         long val = 0;
436         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
437
438         if (kstrtol(buf, 10, &val) < 0)
439                 return -EINVAL;
440
441         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
442                 hdmi_out->tmds_config[0].pclk = val;
443
444         return count;
445 }
446
447 static DEVICE_ATTR(pclk, S_IRUGO|S_IWUSR, pclk_show, pclk_store);
448
449 static ssize_t pll0_show(struct device *device,
450         struct device_attribute *attr, char *buf)
451 {
452         struct platform_device *ndev = to_platform_device(device);
453         struct tegra_dc *dc = platform_get_drvdata(ndev);
454         ssize_t res = 0;
455         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
456
457         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
458                 mutex_lock(&dc->lock);
459                 res = snprintf(buf, PAGE_SIZE, "%d\n",
460                         hdmi_out->tmds_config[0].pll0);
461                 mutex_unlock(&dc->lock);
462         }
463
464         return res;
465 }
466
467 static ssize_t pll0_store(struct device *dev,
468         struct device_attribute *attr, const char *buf, size_t count)
469 {
470         struct platform_device *ndev = to_platform_device(dev);
471         struct tegra_dc *dc = platform_get_drvdata(ndev);
472         unsigned long val = 0;
473         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
474
475         if (kstrtoul(buf, 10, &val) < 0)
476                 return -EINVAL;
477
478         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
479                 hdmi_out->tmds_config[0].pll0 = val;
480
481         return count;
482 }
483
484 static DEVICE_ATTR(pll0, S_IRUGO|S_IWUSR, pll0_show, pll0_store);
485 static ssize_t pll1_show(struct device *device,
486         struct device_attribute *attr, char *buf)
487 {
488         struct platform_device *ndev = to_platform_device(device);
489         struct tegra_dc *dc = platform_get_drvdata(ndev);
490         ssize_t res = 0;
491         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
492
493         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
494                 mutex_lock(&dc->lock);
495                 res = snprintf(buf, PAGE_SIZE, "%d\n",
496                         hdmi_out->tmds_config[0].pll1);
497                 mutex_unlock(&dc->lock);
498         }
499
500         return res;
501 }
502
503 static ssize_t pll1_store(struct device *dev,
504         struct device_attribute *attr, const char *buf, size_t count)
505 {
506         struct platform_device *ndev = to_platform_device(dev);
507         struct tegra_dc *dc = platform_get_drvdata(ndev);
508         unsigned long val = 0;
509         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
510
511         if (kstrtoul(buf, 10, &val) < 0)
512                 return -EINVAL;
513
514         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
515                 hdmi_out->tmds_config[0].pll1 = val;
516
517         return count;
518 }
519
520 static DEVICE_ATTR(pll1, S_IRUGO|S_IWUSR, pll1_show, pll1_store);
521 static ssize_t pe_current_show(struct device *device,
522         struct device_attribute *attr, char *buf)
523 {
524         struct platform_device *ndev = to_platform_device(device);
525         struct tegra_dc *dc = platform_get_drvdata(ndev);
526         ssize_t res = 0;
527         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
528
529         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
530                 mutex_lock(&dc->lock);
531                 res = snprintf(buf, PAGE_SIZE, "%d\n",
532                                 hdmi_out->tmds_config[0].pe_current);
533                 mutex_unlock(&dc->lock);
534         }
535
536         return res;
537 }
538
539 static ssize_t pe_current_store(struct device *dev,
540         struct device_attribute *attr, const char *buf, size_t count)
541 {
542         struct platform_device *ndev = to_platform_device(dev);
543         struct tegra_dc *dc = platform_get_drvdata(ndev);
544         unsigned long val = 0;
545         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
546
547         if (kstrtoul(buf, 10, &val) < 0)
548                 return -EINVAL;
549
550         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
551                 hdmi_out->tmds_config[0].pe_current = val;
552
553         return count;
554 }
555
556 static DEVICE_ATTR(pe_current, S_IRUGO|S_IWUSR, pe_current_show,
557                 pe_current_store);
558
559 static ssize_t drive_current_show(struct device *device,
560         struct device_attribute *attr, char *buf)
561 {
562         struct platform_device *ndev = to_platform_device(device);
563         struct tegra_dc *dc = platform_get_drvdata(ndev);
564         ssize_t res = 0;
565         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
566
567         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
568                 mutex_lock(&dc->lock);
569                 res = snprintf(buf, PAGE_SIZE, "%d\n",
570                                 hdmi_out->tmds_config[0].drive_current);
571                 mutex_unlock(&dc->lock);
572         }
573         return res;
574 }
575
576 static ssize_t drive_current_store(struct device *dev,
577         struct device_attribute *attr, const char *buf, size_t count)
578 {
579         struct platform_device *ndev = to_platform_device(dev);
580         struct tegra_dc *dc = platform_get_drvdata(ndev);
581         unsigned long val = 0;
582         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
583
584         if (kstrtoul(buf, 10, &val) < 0)
585                 return -EINVAL;
586
587         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
588                 hdmi_out->tmds_config[0].drive_current = val;
589
590         return count;
591 }
592
593 static DEVICE_ATTR(drive_current, S_IRUGO|S_IWUSR, drive_current_show,
594                 drive_current_store);
595
596 static ssize_t peak_current_show(struct device *device,
597         struct device_attribute *attr, char *buf)
598 {
599         struct platform_device *ndev = to_platform_device(device);
600         struct tegra_dc *dc = platform_get_drvdata(ndev);
601         ssize_t res = 0;
602         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
603
604         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
605                 mutex_lock(&dc->lock);
606                 res = snprintf(buf, PAGE_SIZE, "%d\n",
607                                 hdmi_out->tmds_config[0].peak_current);
608                 mutex_unlock(&dc->lock);
609         }
610         return res;
611 }
612
613 static ssize_t peak_current_store(struct device *dev,
614         struct device_attribute *attr, const char *buf, size_t count)
615 {
616         struct platform_device *ndev = to_platform_device(dev);
617         struct tegra_dc *dc = platform_get_drvdata(ndev);
618         unsigned long val = 0;
619         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
620
621         if (kstrtoul(buf, 10, &val) < 0)
622                 return -EINVAL;
623
624         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
625                 hdmi_out->tmds_config[0].peak_current = val;
626
627         return count;
628 }
629
630 static DEVICE_ATTR(peak_current, S_IRUGO|S_IWUSR, peak_current_show,
631                 peak_current_store);
632
633 static ssize_t dump_config_show(struct device *device,
634         struct device_attribute *attr, char *buf)
635 {
636         struct platform_device *ndev = to_platform_device(device);
637         struct tegra_dc *dc = platform_get_drvdata(ndev);
638         struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
639         ssize_t res = 0;
640
641         if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
642                 mutex_lock(&dc->lock);
643                 res = snprintf(buf, PAGE_SIZE,
644                         "pclk: %d\n"
645                         "pll0: %d\n"
646                         "pll1: %d\n"
647                         "pe_current: %d\n"
648                         "drive_current: %d\n"
649                         "peak_current: %d\n",
650                         hdmi_out->tmds_config[0].pclk,
651                         hdmi_out->tmds_config[0].pll0,
652                         hdmi_out->tmds_config[0].pll1,
653                         hdmi_out->tmds_config[0].pe_current,
654                         hdmi_out->tmds_config[0].drive_current,
655                         hdmi_out->tmds_config[0].peak_current
656                         );
657                 mutex_unlock(&dc->lock);
658         }
659
660         return res;
661 }
662
663 static DEVICE_ATTR(dump_config, S_IRUGO, dump_config_show, NULL);
664
665 static struct attribute *hdmi_config_attrs[] = {
666         &dev_attr_pclk.attr,
667         &dev_attr_pll0.attr,
668         &dev_attr_pll1.attr,
669         &dev_attr_pe_current.attr,
670         &dev_attr_drive_current.attr,
671         &dev_attr_peak_current.attr,
672         &dev_attr_dump_config.attr,
673         NULL
674 };
675
676 static struct attribute_group hdmi_config_attr_group = {
677         .attrs = hdmi_config_attrs,
678         .name = "hdmi_config"
679 };
680
681 void tegra_dc_remove_sysfs(struct device *dev)
682 {
683         struct platform_device *ndev = to_platform_device(dev);
684         struct tegra_dc *dc = platform_get_drvdata(ndev);
685         struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings;
686
687         device_remove_file(dev, &dev_attr_mode);
688         device_remove_file(dev, &dev_attr_nvdps);
689         device_remove_file(dev, &dev_attr_enable);
690         device_remove_file(dev, &dev_attr_stats_enable);
691         device_remove_file(dev, &dev_attr_crc_checksum_latched);
692 #ifdef CONFIG_TEGRA_DC_WIN_H
693         device_remove_file(dev, &dev_attr_win_h);
694 #endif
695 #ifdef CONFIG_TEGRA_DC_CMU
696         device_remove_file(dev, &dev_attr_cmu_enable);
697 #endif
698
699         if (dc->out->stereo) {
700                 device_remove_file(dev, &dev_attr_stereo_orientation);
701                 device_remove_file(dev, &dev_attr_stereo_mode);
702         }
703
704         if (sd_settings)
705                 nvsd_remove_sysfs(dev);
706
707         if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
708                 device_remove_file(dev, &dev_attr_smart_panel);
709
710         if (dc->out->type == TEGRA_DC_OUT_HDMI)
711                 sysfs_remove_group(&dev->kobj, &hdmi_config_attr_group);
712 }
713
714 void tegra_dc_create_sysfs(struct device *dev)
715 {
716         struct platform_device *ndev = to_platform_device(dev);
717         struct tegra_dc *dc = platform_get_drvdata(ndev);
718         struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings;
719         int error = 0;
720
721         error |= device_create_file(dev, &dev_attr_mode);
722         error |= device_create_file(dev, &dev_attr_nvdps);
723         error |= device_create_file(dev, &dev_attr_enable);
724         error |= device_create_file(dev, &dev_attr_stats_enable);
725         error |= device_create_file(dev, &dev_attr_crc_checksum_latched);
726 #ifdef CONFIG_TEGRA_DC_WIN_H
727         error |= device_create_file(dev, &dev_attr_win_h);
728 #endif
729 #ifdef CONFIG_TEGRA_DC_CMU
730         error |= device_create_file(dev, &dev_attr_cmu_enable);
731 #endif
732
733         if (dc->out->stereo) {
734                 error |= device_create_file(dev, &dev_attr_stereo_orientation);
735                 error |= device_create_file(dev, &dev_attr_stereo_mode);
736         }
737
738         if (sd_settings)
739                 error |= nvsd_create_sysfs(dev);
740
741         if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
742                 error |= device_create_file(dev, &dev_attr_smart_panel);
743         if (dc->out->type == TEGRA_DC_OUT_HDMI)
744                 error |= sysfs_create_group(&dev->kobj,
745                                         &hdmi_config_attr_group);
746
747         if (error)
748                 dev_err(&ndev->dev, "Failed to create sysfs attributes!\n");
749 }