Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.8-rc5 321 lines 7.8 kB view raw
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/jiffies.h> 26#include <linux/platform_device.h> 27 28#include <video/omapdss.h> 29#include "dss.h" 30#include "dss_features.h" 31 32static ssize_t display_enabled_show(struct device *dev, 33 struct device_attribute *attr, char *buf) 34{ 35 struct omap_dss_device *dssdev = to_dss_device(dev); 36 bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED; 37 38 return snprintf(buf, PAGE_SIZE, "%d\n", enabled); 39} 40 41static ssize_t display_enabled_store(struct device *dev, 42 struct device_attribute *attr, 43 const char *buf, size_t size) 44{ 45 struct omap_dss_device *dssdev = to_dss_device(dev); 46 int r; 47 bool enabled; 48 49 r = strtobool(buf, &enabled); 50 if (r) 51 return r; 52 53 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 54 if (enabled) { 55 r = dssdev->driver->enable(dssdev); 56 if (r) 57 return r; 58 } else { 59 dssdev->driver->disable(dssdev); 60 } 61 } 62 63 return size; 64} 65 66static ssize_t display_tear_show(struct device *dev, 67 struct device_attribute *attr, char *buf) 68{ 69 struct omap_dss_device *dssdev = to_dss_device(dev); 70 return snprintf(buf, PAGE_SIZE, "%d\n", 71 dssdev->driver->get_te ? 72 dssdev->driver->get_te(dssdev) : 0); 73} 74 75static ssize_t display_tear_store(struct device *dev, 76 struct device_attribute *attr, const char *buf, size_t size) 77{ 78 struct omap_dss_device *dssdev = to_dss_device(dev); 79 int r; 80 bool te; 81 82 if (!dssdev->driver->enable_te || !dssdev->driver->get_te) 83 return -ENOENT; 84 85 r = strtobool(buf, &te); 86 if (r) 87 return r; 88 89 r = dssdev->driver->enable_te(dssdev, te); 90 if (r) 91 return r; 92 93 return size; 94} 95 96static ssize_t display_timings_show(struct device *dev, 97 struct device_attribute *attr, char *buf) 98{ 99 struct omap_dss_device *dssdev = to_dss_device(dev); 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.pixel_clock, 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 device *dev, 114 struct device_attribute *attr, const char *buf, size_t size) 115{ 116 struct omap_dss_device *dssdev = to_dss_device(dev); 117 struct omap_video_timings t = dssdev->panel.timings; 118 int r, found; 119 120 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings) 121 return -ENOENT; 122 123 found = 0; 124#ifdef CONFIG_OMAP2_DSS_VENC 125 if (strncmp("pal", buf, 3) == 0) { 126 t = omap_dss_pal_timings; 127 found = 1; 128 } else if (strncmp("ntsc", buf, 4) == 0) { 129 t = omap_dss_ntsc_timings; 130 found = 1; 131 } 132#endif 133 if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu", 134 &t.pixel_clock, 135 &t.x_res, &t.hfp, &t.hbp, &t.hsw, 136 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9) 137 return -EINVAL; 138 139 r = dssdev->driver->check_timings(dssdev, &t); 140 if (r) 141 return r; 142 143 dssdev->driver->disable(dssdev); 144 dssdev->driver->set_timings(dssdev, &t); 145 r = dssdev->driver->enable(dssdev); 146 if (r) 147 return r; 148 149 return size; 150} 151 152static ssize_t display_rotate_show(struct device *dev, 153 struct device_attribute *attr, char *buf) 154{ 155 struct omap_dss_device *dssdev = to_dss_device(dev); 156 int rotate; 157 if (!dssdev->driver->get_rotate) 158 return -ENOENT; 159 rotate = dssdev->driver->get_rotate(dssdev); 160 return snprintf(buf, PAGE_SIZE, "%u\n", rotate); 161} 162 163static ssize_t display_rotate_store(struct device *dev, 164 struct device_attribute *attr, const char *buf, size_t size) 165{ 166 struct omap_dss_device *dssdev = to_dss_device(dev); 167 int rot, r; 168 169 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) 170 return -ENOENT; 171 172 r = kstrtoint(buf, 0, &rot); 173 if (r) 174 return r; 175 176 r = dssdev->driver->set_rotate(dssdev, rot); 177 if (r) 178 return r; 179 180 return size; 181} 182 183static ssize_t display_mirror_show(struct device *dev, 184 struct device_attribute *attr, char *buf) 185{ 186 struct omap_dss_device *dssdev = to_dss_device(dev); 187 int mirror; 188 if (!dssdev->driver->get_mirror) 189 return -ENOENT; 190 mirror = dssdev->driver->get_mirror(dssdev); 191 return snprintf(buf, PAGE_SIZE, "%u\n", mirror); 192} 193 194static ssize_t display_mirror_store(struct device *dev, 195 struct device_attribute *attr, const char *buf, size_t size) 196{ 197 struct omap_dss_device *dssdev = to_dss_device(dev); 198 int r; 199 bool mirror; 200 201 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) 202 return -ENOENT; 203 204 r = strtobool(buf, &mirror); 205 if (r) 206 return r; 207 208 r = dssdev->driver->set_mirror(dssdev, mirror); 209 if (r) 210 return r; 211 212 return size; 213} 214 215static ssize_t display_wss_show(struct device *dev, 216 struct device_attribute *attr, char *buf) 217{ 218 struct omap_dss_device *dssdev = to_dss_device(dev); 219 unsigned int wss; 220 221 if (!dssdev->driver->get_wss) 222 return -ENOENT; 223 224 wss = dssdev->driver->get_wss(dssdev); 225 226 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); 227} 228 229static ssize_t display_wss_store(struct device *dev, 230 struct device_attribute *attr, const char *buf, size_t size) 231{ 232 struct omap_dss_device *dssdev = to_dss_device(dev); 233 u32 wss; 234 int r; 235 236 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss) 237 return -ENOENT; 238 239 r = kstrtou32(buf, 0, &wss); 240 if (r) 241 return r; 242 243 if (wss > 0xfffff) 244 return -EINVAL; 245 246 r = dssdev->driver->set_wss(dssdev, wss); 247 if (r) 248 return r; 249 250 return size; 251} 252 253static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, 254 display_enabled_show, display_enabled_store); 255static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, 256 display_tear_show, display_tear_store); 257static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR, 258 display_timings_show, display_timings_store); 259static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR, 260 display_rotate_show, display_rotate_store); 261static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR, 262 display_mirror_show, display_mirror_store); 263static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, 264 display_wss_show, display_wss_store); 265 266static struct device_attribute *display_sysfs_attrs[] = { 267 &dev_attr_enabled, 268 &dev_attr_tear_elim, 269 &dev_attr_timings, 270 &dev_attr_rotate, 271 &dev_attr_mirror, 272 &dev_attr_wss, 273 NULL 274}; 275 276int display_init_sysfs(struct platform_device *pdev, 277 struct omap_dss_device *dssdev) 278{ 279 struct device_attribute *attr; 280 int i, r; 281 282 /* create device sysfs files */ 283 i = 0; 284 while ((attr = display_sysfs_attrs[i++]) != NULL) { 285 r = device_create_file(&dssdev->dev, attr); 286 if (r) { 287 for (i = i - 2; i >= 0; i--) { 288 attr = display_sysfs_attrs[i]; 289 device_remove_file(&dssdev->dev, attr); 290 } 291 292 DSSERR("failed to create sysfs file\n"); 293 return r; 294 } 295 } 296 297 /* create display? sysfs links */ 298 r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj, 299 dev_name(&dssdev->dev)); 300 if (r) { 301 while ((attr = display_sysfs_attrs[i++]) != NULL) 302 device_remove_file(&dssdev->dev, attr); 303 304 DSSERR("failed to create sysfs display link\n"); 305 return r; 306 } 307 308 return 0; 309} 310 311void display_uninit_sysfs(struct platform_device *pdev, 312 struct omap_dss_device *dssdev) 313{ 314 struct device_attribute *attr; 315 int i = 0; 316 317 sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev)); 318 319 while ((attr = display_sysfs_attrs[i++]) != NULL) 320 device_remove_file(&dssdev->dev, attr); 321}