/* ========================================================================= * Local hardware I/O functions: * read/write via codec layer (registers are located in the master device) * =========================================================================
*/
// just in case something is wrong... if (ptr->codec->master_data->readreg)
value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xff; else
zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
// just in case something is wrong... if (ptr->codec->master_data->writereg)
ptr->codec->master_data->writereg(ptr->codec, reg, value); else
zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name);
}
/* ========================================================================= * Local helper function: * status read * =========================================================================
*/
/* status is kept in datastructure */ static u8 zr36060_read_status(struct zr36060 *ptr)
{
ptr->status = zr36060_read(ptr, ZR060_CFSR);
/* leave 0 selected for an eventually GO from master */
zr36060_read(ptr, 0); return ptr->scalefact;
}
/* wait if codec is ready to proceed (end of processing) or time is over */ staticvoid zr36060_wait_end(struct zr36060 *ptr)
{ struct zoran *zr = videocodec_to_zoran(ptr->codec); int i = 0;
while (zr36060_read_status(ptr) & ZR060_CFSR_BUSY) {
udelay(1); if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
zrdev_dbg(zr, "%s: timeout at wait_end (last status: 0x%02x)\n",
ptr->name, ptr->status); break;
}
}
}
/* Basic test of "connectivity", writes/reads to/from memory the SOF marker */ staticint zr36060_basic_test(struct zr36060 *ptr)
{ struct zoran *zr = videocodec_to_zoran(ptr->codec);
/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */ staticconstchar zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; staticconstchar zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
/* * SOF (start of frame) segment depends on width, height and sampling ratio * of each color component
*/ staticint zr36060_set_sof(struct zr36060 *ptr)
{ struct zoran *zr = videocodec_to_zoran(ptr->codec); char sof_data[34]; // max. size of register set int i;
/* SOS (start of scan) segment depends on the used scan components of each color component */ staticint zr36060_set_sos(struct zr36060 *ptr)
{ struct zoran *zr = videocodec_to_zoran(ptr->codec); char sos_data[16]; // max. size of register set int i;
/* Setup compression/decompression of Zoran's JPEG processor ( see also zoran 36060 manual ) * ... sorry for the spaghetti code ...
*/ staticvoid zr36060_init(struct zr36060 *ptr)
{ int sum = 0; long bitcnt, tmp; struct zoran *zr = videocodec_to_zoran(ptr->codec);
if (ptr->mode == CODEC_DO_COMPRESSION) {
zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name);
/* 060 communicates with 067 in master mode */
zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
/* Compression with or without variable scale factor */ /*FIXME: What about ptr->bitrate_ctrl? */
zr36060_write(ptr, ZR060_CMR, ZR060_CMR_COMP | ZR060_CMR_PASS2 | ZR060_CMR_BRB);
/* Must be zero */
zr36060_write(ptr, ZR060_MBZ, 0x00);
zr36060_write(ptr, ZR060_TCR_HI, 0x00);
zr36060_write(ptr, ZR060_TCR_LO, 0x00);
/* Disable all IRQs - no DataErr means autoreset */
zr36060_write(ptr, ZR060_IMR, 0);
/* Must be zero */
zr36060_write(ptr, ZR060_MBZ, 0x00);
zr36060_write(ptr, ZR060_TCR_HI, 0x00);
zr36060_write(ptr, ZR060_TCR_LO, 0x00);
/* Disable all IRQs - no DataErr means autoreset */
zr36060_write(ptr, ZR060_IMR, 0);
/* setup misc. data for expansion */
zr36060_write(ptr, ZR060_MER, 0);
/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
/* Setup the Video Frontend */ //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FI_EXT); //this doesn't seem right and doesn't work...
zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
}
/* Load the tables */
zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST | ZR060_LOAD_LOAD);
zr36060_wait_end(ptr);
zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
ptr->name, ptr->status);
if (ptr->status & ZR060_CFSR_BUSY) {
zrdev_err(zr, "%s: init aborted!\n", ptr->name); return; // something is wrong, its timed out!!!!
}
}
/* ========================================================================= * CODEC API FUNCTIONS * this functions are accessed by the master via the API structure * =========================================================================
*/
/* set compressiion/expansion mode and launches codec - * this should be the last call from the master before starting processing
*/ staticint zr36060_set_mode(struct videocodec *codec, int mode)
{ struct zr36060 *ptr = (struct zr36060 *)codec->data; struct zoran *zr = videocodec_to_zoran(codec);
/* if () return -EINVAL; * trust the master driver that it knows what it does - so * we allow invalid startx/y and norm for now ...
*/
ptr->width = cap->width / (cap->decimation & 0xff);
ptr->height = cap->height / (cap->decimation >> 8);
/* Note that VSPol/HSPol bits in zr36060 have the opposite * meaning of their zr360x7 counterparts with the same names * N.b. for VSPol this is only true if FIVEdge = 0 (default, * left unchanged here - in accordance with datasheet).
*/
reg = (!pol->vsync_pol ? ZR060_VPR_VS_POL : 0)
| (!pol->hsync_pol ? ZR060_VPR_HS_POL : 0)
| (pol->field_pol ? ZR060_VPR_FI_POL : 0)
| (pol->blank_pol ? ZR060_VPR_BL_POL : 0)
| (pol->subimg_pol ? ZR060_VPR_S_IMG_POL : 0)
| (pol->poe_pol ? ZR060_VPR_POE_POL : 0)
| (pol->pvalid_pol ? ZR060_VPR_P_VAL_POL : 0)
| (pol->vclk_pol ? ZR060_VPR_VCLK_POL : 0);
zr36060_write(ptr, ZR060_VPR, reg);
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 */ staticint zr36060_control(struct videocodec *codec, int type, int size, void *data)
{ struct zr36060 *ptr = (struct zr36060 *)codec->data; struct zoran *zr = videocodec_to_zoran(codec); int *ival = (int *)data;
zrdev_dbg(zr, "%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;
/* ========================================================================= * 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) * =========================================================================
*/ staticint zr36060_setup(struct videocodec *codec)
{ struct zr36060 *ptr; struct zoran *zr = videocodec_to_zoran(codec); int res;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.