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

Staging: udlfb: update to version 0.2.3

This updates the udlfb to the 0.2.3 version.

From: Roberto De Ioris <roberto@unbit.it>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Roberto De Ioris and committed by
Greg Kroah-Hartman
7316bc55 4b6a4856

+304 -93
+276 -92
drivers/staging/udlfb/udlfb.c
··· 7 7 * Based on the amazing work of Florian Echtler and libdlo 0.1 * 8 8 * * 9 9 * * 10 + * 10.06.09 release 0.2.3 (edid ioctl, fallback for unsupported modes) * 11 + * 05.06.09 release 0.2.2 (real screen blanking, rle compression, double buffer) * 10 12 * 31.05.09 release 0.2 * 11 13 * 22.05.09 First public (ugly) release * 12 14 *****************************************************************************/ ··· 101 99 struct dloarea { 102 100 int x, y; 103 101 int w, h; 102 + int x2, y2; 104 103 }; 105 104 106 105 /* ··· 119 116 120 117 static struct usb_driver dlfb_driver; 121 118 119 + // thanks to Henrik Bjerregaard Pedersen for this function 120 + static char *rle_compress16(uint16_t * src, char *dst, int rem) 121 + { 122 + 123 + int rl; 124 + uint16_t pix0; 125 + char *end_if_raw = dst + 6 + 2 * rem; 126 + 127 + dst += 6; // header will be filled in if RLE is worth it 128 + 129 + while (rem && dst < end_if_raw) { 130 + char *start = (char *)src; 131 + 132 + pix0 = *src++; 133 + rl = 1; 134 + rem--; 135 + while (rem && *src == pix0) 136 + rem--, rl++, src++; 137 + *dst++ = rl; 138 + *dst++ = start[1]; 139 + *dst++ = start[0]; 140 + } 141 + 142 + return dst; 143 + } 144 + 145 + /* 146 + Thanks to Henrik Bjerregaard Pedersen for rle implementation and code refactoring. 147 + Next step is huffman compression. 148 + */ 149 + 122 150 static int 123 151 image_blit(struct dlfb_data *dev_info, int x, int y, int width, int height, 124 152 char *data) ··· 159 125 int rem = width; 160 126 int ret; 161 127 162 - int diff; 128 + int firstdiff, thistime; 163 129 164 130 char *bufptr; 165 131 ··· 171 137 172 138 mutex_lock(&dev_info->bulk_mutex); 173 139 174 - base = dev_info->base16 + (dev_info->info->var.xres * 2 * y) + (x * 2); 140 + base = 141 + dev_info->base16 + ((dev_info->info->var.xres * 2 * y) + (x * 2)); 175 142 176 143 data += (dev_info->info->var.xres * 2 * y) + (x * 2); 177 144 ··· 199 164 bufptr - dev_info->buf); 200 165 bufptr = dev_info->buf; 201 166 } 167 + // number of pixels to consider this time 168 + thistime = rem; 169 + if (thistime > 255) 170 + thistime = 255; 202 171 203 - if (rem > 255) { 204 - 205 - diff = 0; 206 - for (j = 0; j < 510; j++) { 207 - if (dev_info-> 208 - backing_buffer[base + j] != 209 - data[j]) { 210 - diff = 1; 211 - break; 212 - } 172 + // find position of first pixel that has changed 173 + firstdiff = -1; 174 + for (j = 0; j < thistime * 2; j++) { 175 + if (dev_info->backing_buffer 176 + [base - dev_info->base16 + j] != data[j]) { 177 + firstdiff = j / 2; 178 + break; 213 179 } 214 - 215 - if (diff == 1) { 216 - *bufptr++ = 0xAF; 217 - *bufptr++ = 0x68; 218 - 219 - *bufptr++ = (char)(base >> 16); 220 - *bufptr++ = (char)(base >> 8); 221 - *bufptr++ = (char)(base); 222 - *bufptr++ = 255; 223 - /* PUT COMPRESSION HERE */ 224 - for (j = 0; j < 510; j += 2) { 225 - bufptr[j] = data[j + 1]; 226 - bufptr[j + 1] = data[j]; 227 - } 228 - bufptr += 510; 229 - } 230 - 231 - rem -= 255; 232 - base += 510; 233 - data += 510; 234 - } else { 235 - 236 - diff = 0; 237 - 238 - for (j = 0; j < rem * 2; j++) { 239 - if (dev_info-> 240 - backing_buffer[base + j] != 241 - data[j]) { 242 - diff = 1; 243 - break; 244 - } 245 - } 246 - 247 - if (diff == 1) { 248 - 249 - *bufptr++ = 0xAF; 250 - *bufptr++ = 0x68; 251 - 252 - *bufptr++ = (char)(base >> 16); 253 - *bufptr++ = (char)(base >> 8); 254 - *bufptr++ = (char)(base); 255 - *bufptr++ = rem; 256 - /* PUT COMPRESSION HERE */ 257 - for (j = 0; j < rem * 2; j += 2) { 258 - bufptr[j] = data[j + 1]; 259 - bufptr[j + 1] = data[j]; 260 - } 261 - bufptr += rem * 2; 262 - 263 - } 264 - 265 - base += rem * 2; 266 - data += rem * 2; 267 - rem = 0; 268 180 } 269 181 182 + if (firstdiff >= 0) { 183 + char *end_of_rle; 184 + 185 + end_of_rle = 186 + rle_compress16((uint16_t *) (data + 187 + firstdiff * 2), 188 + bufptr, 189 + thistime - firstdiff); 190 + 191 + if (end_of_rle < 192 + bufptr + 6 + 2 * (thistime - firstdiff)) { 193 + bufptr[0] = 0xAF; 194 + bufptr[1] = 0x69; 195 + 196 + bufptr[2] = 197 + (char)((base + 198 + firstdiff * 2) >> 16); 199 + bufptr[3] = 200 + (char)((base + firstdiff * 2) >> 8); 201 + bufptr[4] = 202 + (char)(base + firstdiff * 2); 203 + bufptr[5] = thistime - firstdiff; 204 + 205 + bufptr = end_of_rle; 206 + 207 + } else { 208 + // fallback to raw (or some other encoding?) 209 + *bufptr++ = 0xAF; 210 + *bufptr++ = 0x68; 211 + 212 + *bufptr++ = 213 + (char)((base + 214 + firstdiff * 2) >> 16); 215 + *bufptr++ = 216 + (char)((base + firstdiff * 2) >> 8); 217 + *bufptr++ = 218 + (char)(base + firstdiff * 2); 219 + *bufptr++ = thistime - firstdiff; 220 + // PUT COMPRESSION HERE 221 + for (j = firstdiff * 2; 222 + j < thistime * 2; j += 2) { 223 + *bufptr++ = data[j + 1]; 224 + *bufptr++ = data[j]; 225 + } 226 + } 227 + } 228 + 229 + base += thistime * 2; 230 + data += thistime * 2; 231 + rem -= thistime; 270 232 } 271 233 272 - memcpy(dev_info->backing_buffer + base - (width * 2), 273 - data - (width * 2), width * 2); 234 + memcpy(dev_info->backing_buffer + (base - dev_info->base16) - 235 + (width * 2), data - (width * 2), width * 2); 274 236 275 237 base += (dev_info->info->var.xres * 2) - (width * 2); 276 238 data += (dev_info->info->var.xres * 2) - (width * 2); 277 239 278 240 } 279 241 280 - if (bufptr > dev_info->buf) 242 + if (bufptr > dev_info->buf) { 281 243 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 244 + } 282 245 283 246 mutex_unlock(&dev_info->bulk_mutex); 284 247 ··· 313 280 for (i = y; i < y + height; i++) { 314 281 315 282 for (j = 0; j < width * 2; j += 2) { 316 - dev_info->backing_buffer[base + j] = (char)(col >> 8); 317 - dev_info->backing_buffer[base + j + 1] = (char)(col); 283 + dev_info->backing_buffer[base - dev_info->base16 + j] = 284 + (char)(col >> 8); 285 + dev_info->backing_buffer[base - dev_info->base16 + j + 286 + 1] = (char)(col); 318 287 } 319 288 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 320 289 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); ··· 370 335 return 1; 371 336 } 372 337 338 + static void swapfb(struct dlfb_data *dev_info) 339 + { 340 + 341 + int tmpbase; 342 + char *bufptr; 343 + 344 + mutex_lock(&dev_info->bulk_mutex); 345 + 346 + tmpbase = dev_info->base16; 347 + 348 + dev_info->base16 = dev_info->base16d; 349 + dev_info->base16d = tmpbase; 350 + 351 + bufptr = dev_info->buf; 352 + 353 + bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 354 + 355 + // set addresses 356 + bufptr = 357 + dlfb_set_register(bufptr, 0x20, (char)(dev_info->base16 >> 16)); 358 + bufptr = dlfb_set_register(bufptr, 0x21, (char)(dev_info->base16 >> 8)); 359 + bufptr = dlfb_set_register(bufptr, 0x22, (char)(dev_info->base16)); 360 + 361 + bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 362 + 363 + dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 364 + 365 + mutex_unlock(&dev_info->bulk_mutex); 366 + } 367 + 368 + static int copyfb(struct dlfb_data *dev_info) 369 + { 370 + int base; 371 + int source; 372 + int rem; 373 + int i, ret; 374 + 375 + char *bufptr; 376 + 377 + base = dev_info->base16d; 378 + 379 + mutex_lock(&dev_info->bulk_mutex); 380 + 381 + source = dev_info->base16; 382 + 383 + bufptr = dev_info->buf; 384 + 385 + for (i = 0; i < dev_info->info->var.yres; i++) { 386 + 387 + if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 388 + ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 389 + bufptr = dev_info->buf; 390 + } 391 + 392 + rem = dev_info->info->var.xres; 393 + 394 + while (rem) { 395 + 396 + if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 397 + ret = 398 + dlfb_bulk_msg(dev_info, 399 + bufptr - dev_info->buf); 400 + bufptr = dev_info->buf; 401 + 402 + } 403 + 404 + *bufptr++ = 0xAF; 405 + *bufptr++ = 0x6A; 406 + 407 + *bufptr++ = (char)(base >> 16); 408 + *bufptr++ = (char)(base >> 8); 409 + *bufptr++ = (char)(base); 410 + 411 + if (rem > 255) { 412 + *bufptr++ = 255; 413 + *bufptr++ = (char)(source >> 16); 414 + *bufptr++ = (char)(source >> 8); 415 + *bufptr++ = (char)(source); 416 + 417 + rem -= 255; 418 + base += 255 * 2; 419 + source += 255 * 2; 420 + 421 + } else { 422 + *bufptr++ = rem; 423 + *bufptr++ = (char)(source >> 16); 424 + *bufptr++ = (char)(source >> 8); 425 + *bufptr++ = (char)(source); 426 + 427 + base += rem * 2; 428 + source += rem * 2; 429 + rem = 0; 430 + } 431 + } 432 + } 433 + 434 + if (bufptr > dev_info->buf) 435 + ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 436 + 437 + mutex_unlock(&dev_info->bulk_mutex); 438 + 439 + return 1; 440 + 441 + } 442 + 373 443 static int 374 444 copyarea(struct dlfb_data *dev_info, int dx, int dy, int sx, int sy, 375 445 int width, int height) ··· 502 362 503 363 for (i = sy; i < sy + height; i++) { 504 364 505 - memcpy(dev_info->backing_buffer + base, 365 + memcpy(dev_info->backing_buffer + base - dev_info->base16, 506 366 dev_info->backing_buffer + source, width * 2); 507 367 508 368 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { ··· 587 447 /* printk("IMAGE BLIT (2) %d %d %d %d DEPTH %d {%p} %d!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev, ret); */ 588 448 } 589 449 590 - static void dlfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) 450 + static void dlfb_fillrect(struct fb_info *info, 451 + const struct fb_fillrect *region) 591 452 { 592 453 593 454 unsigned char red, green, blue; ··· 607 466 { 608 467 609 468 struct dlfb_data *dev_info = info->par; 610 - struct dloarea *area; 469 + struct dloarea *area = NULL; 611 470 612 - if (cmd == 0xAA) { 471 + if (cmd == 0xAD) { 472 + char *edid = (char *)arg; 473 + dlfb_edid(dev_info); 474 + if (copy_to_user(edid, dev_info->edid, 128)) { 475 + return -EFAULT; 476 + } 477 + return 0; 478 + } 479 + 480 + if (cmd == 0xAA || cmd == 0xAB || cmd == 0xAC) { 613 481 614 482 area = (struct dloarea *)arg; 615 483 ··· 633 483 634 484 if (area->y > info->var.yres) 635 485 area->y = info->var.yres; 486 + } 636 487 488 + if (cmd == 0xAA) { 637 489 image_blit(dev_info, area->x, area->y, area->w, area->h, 638 490 info->screen_base); 491 + } 492 + if (cmd == 0xAC) { 493 + copyfb(dev_info); 494 + image_blit(dev_info, area->x, area->y, area->w, area->h, 495 + info->screen_base); 496 + swapfb(dev_info); 497 + } else if (cmd == 0xAB) { 498 + 499 + if (area->x2 < 0) 500 + area->x2 = 0; 501 + 502 + if (area->y2 < 0) 503 + area->y2 = 0; 504 + 505 + copyarea(dev_info, 506 + area->x2, area->y2, area->x, area->y, area->w, 507 + area->h); 639 508 } 640 509 return 0; 641 510 } ··· 697 528 698 529 static int dlfb_blank(int blank_mode, struct fb_info *info) 699 530 { 531 + struct dlfb_data *dev_info = info->par; 532 + char *bufptr = dev_info->buf; 533 + 534 + bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 535 + if (blank_mode != FB_BLANK_UNBLANK) { 536 + bufptr = dlfb_set_register(bufptr, 0x1F, 0x01); 537 + } else { 538 + bufptr = dlfb_set_register(bufptr, 0x1F, 0x00); 539 + } 540 + bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF); 541 + 542 + dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 543 + 700 544 return 0; 701 545 } 702 546 ··· 729 547 { 730 548 struct dlfb_data *dev_info; 731 549 struct fb_info *info; 732 - int i; 733 550 734 551 int ret; 735 552 char rbuf[4]; ··· 769 588 printk("ret control msg 0: %d %x%x%x%x\n", ret, rbuf[0], rbuf[1], 770 589 rbuf[2], rbuf[3]); 771 590 772 - for (i = 0; i < 128; i++) { 773 - ret = 774 - usb_control_msg(dev_info->udev, 775 - usb_rcvctrlpipe(dev_info->udev, 0), (0x02), 776 - (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, 777 - 0); 778 - /* printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */ 779 - dev_info->edid[i] = rbuf[1]; 780 - } 591 + dlfb_edid(dev_info); 781 592 782 593 info = framebuffer_alloc(sizeof(u32) * 256, &dev_info->udev->dev); 783 594 ··· 782 609 783 610 printk("EDID XRES %d YRES %d\n", info->var.xres, info->var.yres); 784 611 785 - if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) 786 - goto out; 612 + if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) { 613 + info->var.xres = 1280; 614 + info->var.yres = 1024; 615 + if (dlfb_set_video_mode 616 + (dev_info, info->var.xres, info->var.yres) != 0) { 617 + goto out; 618 + } 619 + } 787 620 788 621 printk("found valid mode...%d\n", info->var.pixclock); 789 622 ··· 840 661 841 662 info->fix.smem_start = (unsigned long)info->screen_base; 842 663 info->fix.smem_len = PAGE_ALIGN(dev_info->screen_size); 843 - memcpy(info->fix.id, "DisplayLink FB", 14); 664 + if (strlen(dev_info->udev->product) > 15) { 665 + memcpy(info->fix.id, dev_info->udev->product, 15); 666 + } else { 667 + memcpy(info->fix.id, dev_info->udev->product, 668 + strlen(dev_info->udev->product)); 669 + } 844 670 info->fix.type = FB_TYPE_PACKED_PIXELS; 845 671 info->fix.visual = FB_VISUAL_TRUECOLOR; 846 672 info->fix.accel = info->flags; ··· 863 679 864 680 return 0; 865 681 866 - out2: 682 + out2: 867 683 fb_dealloc_cmap(&info->cmap); 868 - out1: 684 + out1: 869 685 rvfree(info->screen_base, dev_info->screen_size); 870 - out0: 686 + out0: 871 687 framebuffer_release(info); 872 - out: 688 + out: 873 689 usb_set_intfdata(interface, NULL); 874 690 usb_put_dev(dev_info->udev); 875 691 kfree(dev_info);
+28 -1
drivers/staging/udlfb/udlfb.h
··· 26 26 int line_length; 27 27 struct completion done; 28 28 int base16; 29 + int base16d; 29 30 int base8; 31 + int base8d; 30 32 }; 31 33 32 34 struct dlfb_video_mode { ··· 48 46 { 49 47 struct dlfb_data *dev_info = urb->context; 50 48 complete(&dev_info->done); 49 + } 50 + 51 + static void dlfb_edid(struct dlfb_data *dev_info) 52 + { 53 + int i; 54 + int ret; 55 + char rbuf[2]; 56 + 57 + for (i = 0; i < 128; i++) { 58 + ret = 59 + usb_control_msg(dev_info->udev, 60 + usb_rcvctrlpipe(dev_info->udev, 0), (0x02), 61 + (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, 62 + 0); 63 + /*printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */ 64 + dev_info->edid[i] = rbuf[1]; 65 + } 66 + 51 67 } 52 68 53 69 static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len) ··· 149 129 && dlfb_video_modes[i].yres == height) { 150 130 151 131 dev_info->base16 = 0; 132 + dev_info->base16d = width * height * (FB_BPP / 8); 152 133 153 - dev_info->base8 = width * height * (FB_BPP / 8);; 134 + //dev_info->base8 = width * height * (FB_BPP / 8); 135 + 136 + dev_info->base8 = dev_info->base16; 137 + dev_info->base8d = dev_info->base16d; 154 138 155 139 /* set encryption key (null) */ 156 140 memcpy(dev_info->buf, STD_CHANNEL, 16); ··· 167 143 168 144 /* set registers */ 169 145 bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 146 + 147 + /* set color depth */ 148 + bufptr = dlfb_set_register(bufptr, 0x00, 0x00); 170 149 171 150 /* set addresses */ 172 151 bufptr =