aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Grzeschik <m.grzeschik@pengutronix.de>2010-01-23 03:40:28 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-23 03:40:28 +0100
commit24dc9ab2f4da202770b9680f663244f113e1a32b (patch)
tree5fe8f3c7744567a89d026acee2e4527ddab7e795
parent9882b34fe22ad55d554fd4451387e472fcc69e8b (diff)
downloadbusybox-w32-24dc9ab2f4da202770b9680f663244f113e1a32b.tar.gz
busybox-w32-24dc9ab2f4da202770b9680f663244f113e1a32b.tar.bz2
busybox-w32-24dc9ab2f4da202770b9680f663244f113e1a32b.zip
fbset: add possibility to set timing and sync polarity
function old new delta copy_changed_values - 48 +48 copy_if_gt0 - 27 +27 fbset_main 1268 1235 -33 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/1 up/down: 75/-33) Total: 42 bytes Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--util-linux/fbset.c269
1 files changed, 172 insertions, 97 deletions
diff --git a/util-linux/fbset.c b/util-linux/fbset.c
index 6e497c6ea..dc3245baf 100644
--- a/util-linux/fbset.c
+++ b/util-linux/fbset.c
@@ -17,52 +17,13 @@
17#define DEFAULTFBDEV FB_0 17#define DEFAULTFBDEV FB_0
18#define DEFAULTFBMODE "/etc/fb.modes" 18#define DEFAULTFBMODE "/etc/fb.modes"
19 19
20enum {
21 CMD_FB = 1,
22 CMD_DB = 2,
23 CMD_GEOMETRY = 3,
24 CMD_TIMING = 4,
25 CMD_ACCEL = 5,
26 CMD_HSYNC = 6,
27 CMD_VSYNC = 7,
28 CMD_LACED = 8,
29 CMD_DOUBLE = 9,
30/* CMD_XCOMPAT = 10, */
31 CMD_ALL = 11,
32 CMD_INFO = 12,
33 CMD_SHOW = 13,
34 CMD_CHANGE = 14,
35
36#if ENABLE_FEATURE_FBSET_FANCY
37 CMD_XRES = 100,
38 CMD_YRES = 101,
39 CMD_VXRES = 102,
40 CMD_VYRES = 103,
41 CMD_DEPTH = 104,
42 CMD_MATCH = 105,
43 CMD_PIXCLOCK = 106,
44 CMD_LEFT = 107,
45 CMD_RIGHT = 108,
46 CMD_UPPER = 109,
47 CMD_LOWER = 110,
48 CMD_HSLEN = 111,
49 CMD_VSLEN = 112,
50 CMD_CSYNC = 113,
51 CMD_GSYNC = 114,
52 CMD_EXTSYNC = 115,
53 CMD_BCAST = 116,
54 CMD_RGBA = 117,
55 CMD_STEP = 118,
56 CMD_MOVE = 119,
57#endif
58};
59
60/* Stuff stolen from the kernel's fb.h */ 20/* Stuff stolen from the kernel's fb.h */
61#define FB_ACTIVATE_ALL 64 21#define FB_ACTIVATE_ALL 64
62enum { 22enum {
63 FBIOGET_VSCREENINFO = 0x4600, 23 FBIOGET_VSCREENINFO = 0x4600,
64 FBIOPUT_VSCREENINFO = 0x4601 24 FBIOPUT_VSCREENINFO = 0x4601
65}; 25};
26
66struct fb_bitfield { 27struct fb_bitfield {
67 uint32_t offset; /* beginning of bitfield */ 28 uint32_t offset; /* beginning of bitfield */
68 uint32_t length; /* length of bitfield */ 29 uint32_t length; /* length of bitfield */
@@ -106,6 +67,81 @@ struct fb_var_screeninfo {
106 uint32_t reserved[6]; /* Reserved for future compatibility */ 67 uint32_t reserved[6]; /* Reserved for future compatibility */
107}; 68};
108 69
70static void copy_if_gt0(uint32_t *src, uint32_t *dst, unsigned cnt)
71{
72 do {
73 if ((int32_t) *src > 0)
74 *dst = *src;
75 src++;
76 dst++;
77 } while (--cnt);
78}
79
80static NOINLINE void copy_changed_values(
81 struct fb_var_screeninfo *base,
82 struct fb_var_screeninfo *set)
83{
84 //if ((int32_t) set->xres > 0) base->xres = set->xres;
85 //if ((int32_t) set->yres > 0) base->yres = set->yres;
86 //if ((int32_t) set->xres_virtual > 0) base->xres_virtual = set->xres_virtual;
87 //if ((int32_t) set->yres_virtual > 0) base->yres_virtual = set->yres_virtual;
88 copy_if_gt0(&set->xres, &base->xres, 4);
89
90 if ((int32_t) set->bits_per_pixel > 0) base->bits_per_pixel = set->bits_per_pixel;
91 //copy_if_gt0(&set->bits_per_pixel, &base->bits_per_pixel, 1);
92
93 //if ((int32_t) set->pixclock > 0) base->pixclock = set->pixclock;
94 //if ((int32_t) set->left_margin > 0) base->left_margin = set->left_margin;
95 //if ((int32_t) set->right_margin > 0) base->right_margin = set->right_margin;
96 //if ((int32_t) set->upper_margin > 0) base->upper_margin = set->upper_margin;
97 //if ((int32_t) set->lower_margin > 0) base->lower_margin = set->lower_margin;
98 //if ((int32_t) set->hsync_len > 0) base->hsync_len = set->hsync_len;
99 //if ((int32_t) set->vsync_len > 0) base->vsync_len = set->vsync_len;
100 //if ((int32_t) set->sync > 0) base->sync = set->sync;
101 //if ((int32_t) set->vmode > 0) base->vmode = set->vmode;
102 copy_if_gt0(&set->pixclock, &base->pixclock, 9);
103}
104
105
106enum {
107 CMD_FB = 1,
108 CMD_DB = 2,
109 CMD_GEOMETRY = 3,
110 CMD_TIMING = 4,
111 CMD_ACCEL = 5,
112 CMD_HSYNC = 6,
113 CMD_VSYNC = 7,
114 CMD_LACED = 8,
115 CMD_DOUBLE = 9,
116/* CMD_XCOMPAT = 10, */
117 CMD_ALL = 11,
118 CMD_INFO = 12,
119 CMD_SHOW = 13,
120 CMD_CHANGE = 14,
121
122#if ENABLE_FEATURE_FBSET_FANCY
123 CMD_XRES = 100,
124 CMD_YRES = 101,
125 CMD_VXRES = 102,
126 CMD_VYRES = 103,
127 CMD_DEPTH = 104,
128 CMD_MATCH = 105,
129 CMD_PIXCLOCK = 106,
130 CMD_LEFT = 107,
131 CMD_RIGHT = 108,
132 CMD_UPPER = 109,
133 CMD_LOWER = 110,
134 CMD_HSLEN = 111,
135 CMD_VSLEN = 112,
136 CMD_CSYNC = 113,
137 CMD_GSYNC = 114,
138 CMD_EXTSYNC = 115,
139 CMD_BCAST = 116,
140 CMD_RGBA = 117,
141 CMD_STEP = 118,
142 CMD_MOVE = 119,
143#endif
144};
109 145
110static const struct cmdoptions_t { 146static const struct cmdoptions_t {
111 const char name[9]; 147 const char name[9];
@@ -174,6 +210,16 @@ static void ss(uint32_t *x, uint32_t flag, char *buf, const char *what)
174 *x |= flag; 210 *x |= flag;
175} 211}
176 212
213/* Mode db file contains mode definitions like this:
214 * mode "800x600-48-lace"
215 * # D: 36.00 MHz, H: 33.835 kHz, V: 96.39 Hz
216 * geometry 800 600 800 600 8
217 * timings 27778 56 80 79 11 128 12
218 * laced true
219 * hsync high
220 * vsync high
221 * endmode
222 */
177static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, 223static int read_mode_db(struct fb_var_screeninfo *base, const char *fn,
178 const char *mode) 224 const char *mode)
179{ 225{
@@ -214,19 +260,52 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn,
214 token[0]); 260 token[0]);
215 switch (i) { 261 switch (i) {
216 case 0: 262 case 0:
217 /* FIXME: catastrophic on arches with 64bit ints */ 263 if (sizeof(int) == sizeof(base->xres)) {
218 sscanf(p, "%d %d %d %d %d", 264 sscanf(p, "%d %d %d %d %d",
219 &(base->xres), &(base->yres), 265 &base->xres, &base->yres,
220 &(base->xres_virtual), &(base->yres_virtual), 266 &base->xres_virtual, &base->yres_virtual,
221 &(base->bits_per_pixel)); 267 &base->bits_per_pixel);
268 } else {
269 int base_xres, base_yres;
270 int base_xres_virtual, base_yres_virtual;
271 int base_bits_per_pixel;
272 sscanf(p, "%d %d %d %d %d",
273 &base_xres, &base_yres,
274 &base_xres_virtual, &base_yres_virtual,
275 &base_bits_per_pixel);
276 base->xres = base_xres;
277 base->yres = base_yres;
278 base->xres_virtual = base_xres_virtual;
279 base->yres_virtual = base_yres_virtual;
280 base->bits_per_pixel = base_bits_per_pixel;
281 }
222//bb_info_msg("GEO[%s]", p); 282//bb_info_msg("GEO[%s]", p);
223 break; 283 break;
224 case 1: 284 case 1:
225 sscanf(p, "%d %d %d %d %d %d %d", 285 if (sizeof(int) == sizeof(base->xres)) {
226 &(base->pixclock), 286 sscanf(p, "%d %d %d %d %d %d %d",
227 &(base->left_margin), &(base->right_margin), 287 &base->pixclock,
228 &(base->upper_margin), &(base->lower_margin), 288 &base->left_margin, &base->right_margin,
229 &(base->hsync_len), &(base->vsync_len)); 289 &base->upper_margin, &base->lower_margin,
290 &base->hsync_len, &base->vsync_len);
291 } else {
292 int base_pixclock;
293 int base_left_margin, base_right_margin;
294 int base_upper_margin, base_lower_margin;
295 int base_hsync_len, base_vsync_len;
296 sscanf(p, "%d %d %d %d %d %d %d",
297 &base_pixclock,
298 &base_left_margin, &base_right_margin,
299 &base_upper_margin, &base_lower_margin,
300 &base_hsync_len, &base_vsync_len);
301 base->pixclock = base_pixclock;
302 base->left_margin = base_left_margin;
303 base->right_margin = base_right_margin;
304 base->upper_margin = base_upper_margin;
305 base->lower_margin = base_lower_margin;
306 base->hsync_len = base_hsync_len;
307 base->vsync_len = base_vsync_len;
308 }
230//bb_info_msg("TIM[%s]", p); 309//bb_info_msg("TIM[%s]", p);
231 break; 310 break;
232 case 2: 311 case 2:
@@ -254,21 +333,6 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn,
254} 333}
255#endif 334#endif
256 335
257static void setfbmode(struct fb_var_screeninfo *base,
258 struct fb_var_screeninfo *set)
259{
260 if ((int32_t) set->xres > 0)
261 base->xres = set->xres;
262 if ((int32_t) set->yres > 0)
263 base->yres = set->yres;
264 if ((int32_t) set->xres_virtual > 0)
265 base->xres_virtual = set->xres_virtual;
266 if ((int32_t) set->yres_virtual > 0)
267 base->yres_virtual = set->yres_virtual;
268 if ((int32_t) set->bits_per_pixel > 0)
269 base->bits_per_pixel = set->bits_per_pixel;
270}
271
272static NOINLINE void showmode(struct fb_var_screeninfo *v) 336static NOINLINE void showmode(struct fb_var_screeninfo *v)
273{ 337{
274 double drate = 0, hrate = 0, vrate = 0; 338 double drate = 0, hrate = 0, vrate = 0;
@@ -308,15 +372,16 @@ int fbset_main(int argc, char **argv)
308 OPT_READMODE = (1 << 2), 372 OPT_READMODE = (1 << 2),
309 OPT_ALL = (1 << 9), 373 OPT_ALL = (1 << 9),
310 }; 374 };
311 struct fb_var_screeninfo var, varset; 375 struct fb_var_screeninfo var_old, var_set;
312 int fh, i; 376 int fh, i;
313 unsigned options = 0; 377 unsigned options = 0;
314 378
315 const char *fbdev = DEFAULTFBDEV; 379 const char *fbdev = DEFAULTFBDEV;
316 const char *modefile = DEFAULTFBMODE; 380 const char *modefile = DEFAULTFBMODE;
317 char *thisarg, *mode = NULL; 381 char *thisarg;
382 char *mode = mode; /* for compiler */
318 383
319 memset(&varset, 0xff, sizeof(varset)); 384 memset(&var_set, 0xff, sizeof(var_set)); /* set all to -1 */
320 385
321 /* parse cmd args.... why do they have to make things so difficult? */ 386 /* parse cmd args.... why do they have to make things so difficult? */
322 argv++; 387 argv++;
@@ -342,30 +407,38 @@ int fbset_main(int argc, char **argv)
342 options |= OPT_SHOW; 407 options |= OPT_SHOW;
343 break; 408 break;
344 case CMD_GEOMETRY: 409 case CMD_GEOMETRY:
345 varset.xres = xatou32(argv[1]); 410 var_set.xres = xatou32(argv[1]);
346 varset.yres = xatou32(argv[2]); 411 var_set.yres = xatou32(argv[2]);
347 varset.xres_virtual = xatou32(argv[3]); 412 var_set.xres_virtual = xatou32(argv[3]);
348 varset.yres_virtual = xatou32(argv[4]); 413 var_set.yres_virtual = xatou32(argv[4]);
349 varset.bits_per_pixel = xatou32(argv[5]); 414 var_set.bits_per_pixel = xatou32(argv[5]);
350 break; 415 break;
351 case CMD_TIMING: 416 case CMD_TIMING:
352 varset.pixclock = xatou32(argv[1]); 417 var_set.pixclock = xatou32(argv[1]);
353 varset.left_margin = xatou32(argv[2]); 418 var_set.left_margin = xatou32(argv[2]);
354 varset.right_margin = xatou32(argv[3]); 419 var_set.right_margin = xatou32(argv[3]);
355 varset.upper_margin = xatou32(argv[4]); 420 var_set.upper_margin = xatou32(argv[4]);
356 varset.lower_margin = xatou32(argv[5]); 421 var_set.lower_margin = xatou32(argv[5]);
357 varset.hsync_len = xatou32(argv[6]); 422 var_set.hsync_len = xatou32(argv[6]);
358 varset.vsync_len = xatou32(argv[7]); 423 var_set.vsync_len = xatou32(argv[7]);
424 break;
425 case CMD_ACCEL:
426 break;
427 case CMD_HSYNC:
428 var_set.sync |= FB_SYNC_HOR_HIGH_ACT;
429 break;
430 case CMD_VSYNC:
431 var_set.sync |= FB_SYNC_VERT_HIGH_ACT;
359 break; 432 break;
360#if ENABLE_FEATURE_FBSET_FANCY 433#if ENABLE_FEATURE_FBSET_FANCY
361 case CMD_XRES: 434 case CMD_XRES:
362 varset.xres = xatou32(argv[1]); 435 var_set.xres = xatou32(argv[1]);
363 break; 436 break;
364 case CMD_YRES: 437 case CMD_YRES:
365 varset.yres = xatou32(argv[1]); 438 var_set.yres = xatou32(argv[1]);
366 break; 439 break;
367 case CMD_DEPTH: 440 case CMD_DEPTH:
368 varset.bits_per_pixel = xatou32(argv[1]); 441 var_set.bits_per_pixel = xatou32(argv[1]);
369 break; 442 break;
370#endif 443#endif
371 } 444 }
@@ -376,13 +449,14 @@ int fbset_main(int argc, char **argv)
376 case CMD_SHOW: 449 case CMD_SHOW:
377 break; 450 break;
378 default: 451 default:
379 options |= OPT_CHANGE; /* the other commands imply changes */ 452 /* other commands imply changes */
453 options |= OPT_CHANGE;
380 } 454 }
381 argc -= g_cmdoptions[i].param_count; 455 argc -= g_cmdoptions[i].param_count;
382 argv += g_cmdoptions[i].param_count; 456 argv += g_cmdoptions[i].param_count;
383 goto contin; 457 goto contin;
384 } 458 }
385 if (argc != 1) 459 if (!ENABLE_FEATURE_FBSET_READMODE || argc != 1)
386 bb_show_usage(); 460 bb_show_usage();
387 mode = *argv; 461 mode = *argv;
388 options |= OPT_READMODE; 462 options |= OPT_READMODE;
@@ -390,27 +464,28 @@ int fbset_main(int argc, char **argv)
390 } 464 }
391 465
392 fh = xopen(fbdev, O_RDONLY); 466 fh = xopen(fbdev, O_RDONLY);
393 xioctl(fh, FBIOGET_VSCREENINFO, &var); 467 xioctl(fh, FBIOGET_VSCREENINFO, &var_old);
468
394 if (options & OPT_READMODE) { 469 if (options & OPT_READMODE) {
395#if !ENABLE_FEATURE_FBSET_READMODE 470#if ENABLE_FEATURE_FBSET_READMODE
396 bb_show_usage(); 471 if (!read_mode_db(&var_old, modefile, mode)) {
397#else
398 if (!read_mode_db(&var, modefile, mode)) {
399 bb_error_msg_and_die("unknown video mode '%s'", mode); 472 bb_error_msg_and_die("unknown video mode '%s'", mode);
400 } 473 }
401#endif 474#endif
402 } 475 }
403 476
404 if (options & OPT_CHANGE) { 477 if (options & OPT_CHANGE) {
405 setfbmode(&var, &varset); 478 copy_changed_values(&var_old, &var_set);
406 if (options & OPT_ALL) 479 if (options & OPT_ALL)
407 var.activate = FB_ACTIVATE_ALL; 480 var_old.activate = FB_ACTIVATE_ALL;
408 xioctl(fh, FBIOPUT_VSCREENINFO, &var); 481 xioctl(fh, FBIOPUT_VSCREENINFO, &var_old);
409 } 482 }
410 if (options == 0 || options & OPT_SHOW) 483
411 showmode(&var); 484 if (options == 0 || (options & OPT_SHOW))
412 /* Don't close the file, as exiting will take care of that */ 485 showmode(&var_old);
413 /* close(fh); */ 486
487 if (ENABLE_FEATURE_CLEAN_UP)
488 close(fh);
414 489
415 return EXIT_SUCCESS; 490 return EXIT_SUCCESS;
416} 491}