📄 zr36060.c
字号:
zr36060_write(ptr, ZR060_SGR_HSYNC, reg); reg = norm->VStart - 1; /* BVstart */ zr36060_write(ptr, ZR060_SGR_BVSTART, reg); reg += norm->Ha / 2; /* BVend */ zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff); reg = norm->HStart - 1; /* BHstart */ zr36060_write(ptr, ZR060_SGR_BHSTART, reg); reg += norm->Wa; /* BHend */ zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff); /* active area */ reg = cap->y + norm->VStart; /* Vstart */ zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff); reg += cap->height; /* Vend */ zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff); reg = cap->x + norm->HStart; /* Hstart */ zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff); reg += cap->width; /* Hend */ zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff); /* subimage area */ reg = norm->VStart - 4; /* SVstart */ zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff); reg += norm->Ha / 2 + 8; /* SVend */ zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff); reg = norm->HStart /*+ 64 */ - 4; /* SHstart */ zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff); reg += norm->Wa + 8; /* SHend */ zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff); zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff); size = ptr->width * ptr->height; /* Target compressed field size in bits: */ size = size * 16; /* uncompressed size in bits */ /* (Ronald) by default, quality = 100 is a compression * ratio 1:2. Setting low_bitrate (insmod option) sets * it to 1:4 (instead of 1:2, zr36060 max) as limit because the * buz can't handle more at decimation=1... Use low_bitrate if * you have a Buz, unless you know what you're doing */ size = size * cap->quality / (low_bitrate ? 400 : 200); /* Lower limit (arbitrary, 1 KB) */ if (size < 8192) size = 8192; /* Upper limit: 7/8 of the code buffers */ if (size > ptr->total_code_vol * 7) size = ptr->total_code_vol * 7; ptr->real_code_vol = size >> 3; /* in bytes */ /* the MBCVR is the *maximum* block volume, according to the * JPEG ISO specs, this shouldn't be used, since that allows * for the best encoding quality. So set it to it's max value */ reg = ptr->max_block_vol; zr36060_write(ptr, ZR060_MBCVR, reg); return 0;}/* additional control functions */static intzr36060_control (struct videocodec *codec, int type, int size, void *data){ struct zr36060 *ptr = (struct zr36060 *) codec->data; int *ival = (int *) data; dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, size); switch (type) { case CODEC_G_STATUS: /* get last status */ if (size != sizeof(int)) return -EFAULT; zr36060_read_status(ptr); *ival = ptr->status; break; case CODEC_G_CODEC_MODE: if (size != sizeof(int)) return -EFAULT; *ival = CODEC_MODE_BJPG; break; case CODEC_S_CODEC_MODE: if (size != sizeof(int)) return -EFAULT; if (*ival != CODEC_MODE_BJPG) return -EINVAL; /* not needed, do nothing */ return 0; case CODEC_G_VFE: case CODEC_S_VFE: /* not needed, do nothing */ return 0; case CODEC_S_MMAP: /* not available, give an error */ return -ENXIO; case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ if (size != sizeof(int)) return -EFAULT; *ival = ptr->total_code_vol; break; case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ if (size != sizeof(int)) return -EFAULT; ptr->total_code_vol = *ival; ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; break; case CODEC_G_JPEG_SCALE: /* get scaling factor */ if (size != sizeof(int)) return -EFAULT; *ival = zr36060_read_scalefactor(ptr); break; case CODEC_S_JPEG_SCALE: /* set scaling factor */ if (size != sizeof(int)) return -EFAULT; ptr->scalefact = *ival; break; case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ struct jpeg_app_marker *app = data; if (size != sizeof(struct jpeg_app_marker)) return -EFAULT; *app = ptr->app; break; } case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ struct jpeg_app_marker *app = data; if (size != sizeof(struct jpeg_app_marker)) return -EFAULT; ptr->app = *app; break; } case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ struct jpeg_com_marker *com = data; if (size != sizeof(struct jpeg_com_marker)) return -EFAULT; *com = ptr->com; break; } case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ struct jpeg_com_marker *com = data; if (size != sizeof(struct jpeg_com_marker)) return -EFAULT; ptr->com = *com; break; } default: return -EINVAL; } return size;}/* ========================================================================= Exit and unregister function: Deinitializes Zoran's JPEG processor ========================================================================= */static intzr36060_unset (struct videocodec *codec){ struct zr36060 *ptr = codec->data; if (ptr) { /* do wee need some codec deinit here, too ???? */ dprintk(1, "%s: finished codec #%d\n", ptr->name, ptr->num); kfree(ptr); codec->data = NULL; zr36060_codecs--; return 0; } return -EFAULT;}/* ========================================================================= Setup and registry function: Initializes Zoran's JPEG processor Also sets pixel size, average code size, mode (compr./decompr.) (the given size is determined by the processor with the video interface) ========================================================================= */static intzr36060_setup (struct videocodec *codec){ struct zr36060 *ptr; int res; dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", zr36060_codecs); if (zr36060_codecs == MAX_CODECS) { dprintk(1, KERN_ERR "zr36060: Can't attach more codecs!\n"); return -ENOSPC; } //mem structure init codec->data = ptr = kmalloc(sizeof(struct zr36060), GFP_KERNEL); if (NULL == ptr) { dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n"); return -ENOMEM; } memset(ptr, 0, sizeof(struct zr36060)); snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", zr36060_codecs); ptr->num = zr36060_codecs++; ptr->codec = codec; //testing res = zr36060_basic_test(ptr); if (res < 0) { zr36060_unset(codec); return res; } //final setup memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8); memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8); ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag * (what is the difference?) */ ptr->mode = CODEC_DO_COMPRESSION; ptr->width = 384; ptr->height = 288; ptr->total_code_vol = 16000; /* CHECKME */ ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */ ptr->scalefact = 0x100; ptr->dri = 1; /* CHECKME, was 8 is 1 */ /* by default, no COM or APP markers - app should set those */ ptr->com.len = 0; ptr->app.appn = 0; ptr->app.len = 0; zr36060_init(ptr); dprintk(1, KERN_INFO "%s: codec attached and running\n", ptr->name); return 0;}static const struct videocodec zr36060_codec = { .owner = THIS_MODULE, .name = "zr36060", .magic = 0L, // magic not used .flags = CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER | CODEC_FLAG_VFE, .type = CODEC_TYPE_ZR36060, .setup = zr36060_setup, // functionality .unset = zr36060_unset, .set_mode = zr36060_set_mode, .set_video = zr36060_set_video, .control = zr36060_control, // others are not used};/* ========================================================================= HOOK IN DRIVER AS KERNEL MODULE ========================================================================= */static int __initzr36060_init_module (void){ //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION); zr36060_codecs = 0; return videocodec_register(&zr36060_codec);}static void __exitzr36060_cleanup_module (void){ if (zr36060_codecs) { dprintk(1, "zr36060: something's wrong - %d codecs left somehow.\n", zr36060_codecs); } /* however, we can't just stay alive */ videocodec_unregister(&zr36060_codec);}module_init(zr36060_init_module);module_exit(zr36060_cleanup_module);MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors " ZR060_VERSION);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -