1/* 2 * Zoran ZR36060 basic configuration functions 3 * 4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be> 5 * 6 * $Id: zr36060.c,v 1.1.1.1 2007/08/03 18:52:41 Exp $ 7 * 8 * ------------------------------------------------------------------------ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 * ------------------------------------------------------------------------ 25 */ 26 27#define ZR060_VERSION "v0.7" 28 29#include <linux/module.h> 30#include <linux/init.h> 31#include <linux/slab.h> 32#include <linux/delay.h> 33 34#include <linux/types.h> 35#include <linux/wait.h> 36 37/* includes for structures and defines regarding video 38 #include<linux/videodev.h> */ 39 40/* I/O commands, error codes */ 41#include<asm/io.h> 42//#include<errno.h> 43 44/* headerfile of this module */ 45#include"zr36060.h" 46 47/* codec io API */ 48#include"videocodec.h" 49 50/* it doesn't make sense to have more than 20 or so, 51 just to prevent some unwanted loops */ 52#define MAX_CODECS 20 53 54/* amount of chips attached via this driver */ 55static int zr36060_codecs = 0; 56 57static int low_bitrate = 0; 58module_param(low_bitrate, bool, 0); 59MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); 60 61/* debugging is available via module parameter */ 62static int debug = 0; 63module_param(debug, int, 0); 64MODULE_PARM_DESC(debug, "Debug level (0-4)"); 65 66#define dprintk(num, format, args...) \ 67 do { \ 68 if (debug >= num) \ 69 printk(format, ##args); \ 70 } while (0) 71 72/* ========================================================================= 73 Local hardware I/O functions: 74 75 read/write via codec layer (registers are located in the master device) 76 ========================================================================= */ 77 78/* read and write functions */ 79static u8 80zr36060_read (struct zr36060 *ptr, 81 u16 reg) 82{ 83 u8 value = 0; 84 85 // just in case something is wrong... 86 if (ptr->codec->master_data->readreg) 87 value = (ptr->codec->master_data->readreg(ptr->codec, 88 reg)) & 0xff; 89 else 90 dprintk(1, 91 KERN_ERR "%s: invalid I/O setup, nothing read!\n", 92 ptr->name); 93 94 //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value); 95 96 return value; 97} 98 99static void 100zr36060_write(struct zr36060 *ptr, 101 u16 reg, 102 u8 value) 103{ 104 //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg); 105 dprintk(4, "0x%02x @0x%04x\n", value, reg); 106 107 // just in case something is wrong... 108 if (ptr->codec->master_data->writereg) 109 ptr->codec->master_data->writereg(ptr->codec, reg, value); 110 else 111 dprintk(1, 112 KERN_ERR 113 "%s: invalid I/O setup, nothing written!\n", 114 ptr->name); 115} 116 117/* ========================================================================= 118 Local helper function: 119 120 status read 121 ========================================================================= */ 122 123/* status is kept in datastructure */ 124static u8 125zr36060_read_status (struct zr36060 *ptr) 126{ 127 ptr->status = zr36060_read(ptr, ZR060_CFSR); 128 129 zr36060_read(ptr, 0); 130 return ptr->status; 131} 132 133/* ========================================================================= 134 Local helper function: 135 136 scale factor read 137 ========================================================================= */ 138 139/* scale factor is kept in datastructure */ 140static u16 141zr36060_read_scalefactor (struct zr36060 *ptr) 142{ 143 ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) | 144 (zr36060_read(ptr, ZR060_SF_LO) & 0xFF); 145 146 /* leave 0 selected for an eventually GO from master */ 147 zr36060_read(ptr, 0); 148 return ptr->scalefact; 149} 150 151/* ========================================================================= 152 Local helper function: 153 154 wait if codec is ready to proceed (end of processing) or time is over 155 ========================================================================= */ 156 157static void 158zr36060_wait_end (struct zr36060 *ptr) 159{ 160 int i = 0; 161 162 while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) { 163 udelay(1); 164 if (i++ > 200000) { // 200ms, there is for sure something wrong!!! 165 dprintk(1, 166 "%s: timout at wait_end (last status: 0x%02x)\n", 167 ptr->name, ptr->status); 168 break; 169 } 170 } 171} 172 173/* ========================================================================= 174 Local helper function: 175 176 basic test of "connectivity", writes/reads to/from memory the SOF marker 177 ========================================================================= */ 178 179static int 180zr36060_basic_test (struct zr36060 *ptr) 181{ 182 if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) && 183 (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) { 184 dprintk(1, 185 KERN_ERR 186 "%s: attach failed, can't connect to jpeg processor!\n", 187 ptr->name); 188 return -ENXIO; 189 } 190 191 zr36060_wait_end(ptr); 192 if (ptr->status & ZR060_CFSR_Busy) { 193 dprintk(1, 194 KERN_ERR 195 "%s: attach failed, jpeg processor failed (end flag)!\n", 196 ptr->name); 197 return -EBUSY; 198 } 199 200 return 0; /* looks good! */ 201} 202 203/* ========================================================================= 204 Local helper function: 205 206 simple loop for pushing the init datasets 207 ========================================================================= */ 208 209static int 210zr36060_pushit (struct zr36060 *ptr, 211 u16 startreg, 212 u16 len, 213 const char *data) 214{ 215 int i = 0; 216 217 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, 218 startreg, len); 219 while (i < len) { 220 zr36060_write(ptr, startreg++, data[i++]); 221 } 222 223 return i; 224} 225 226/* ========================================================================= 227 Basic datasets: 228 229 jpeg baseline setup data (you find it on lots places in internet, or just 230 extract it from any regular .jpg image...) 231 232 Could be variable, but until it's not needed it they are just fixed to save 233 memory. Otherwise expand zr36060 structure with arrays, push the values to 234 it and initalize from there, as e.g. the linux zr36057/60 driver does it. 235 ========================================================================= */ 236 237static const char zr36060_dqt[0x86] = { 238 0xff, 0xdb, //Marker: DQT 239 0x00, 0x84, //Length: 2*65+2 240 0x00, //Pq,Tq first table 241 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 242 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 243 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 244 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, 245 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, 246 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 247 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 248 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, 249 0x01, //Pq,Tq second table 250 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, 251 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, 252 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 253 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 254 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 255 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 256 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 257 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 258}; 259 260static const char zr36060_dht[0x1a4] = { 261 0xff, 0xc4, //Marker: DHT 262 0x01, 0xa2, //Length: 2*AC, 2*DC 263 0x00, //DC first table 264 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 265 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 266 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 267 0x01, //DC second table 268 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 269 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 270 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 271 0x10, //AC first table 272 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 273 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 274 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 275 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 276 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 277 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 278 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 279 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 280 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 281 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 282 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 283 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 284 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 285 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 286 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 287 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 288 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 289 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 290 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 291 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 292 0xF8, 0xF9, 0xFA, 293 0x11, //AC second table 294 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 295 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 296 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 297 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 298 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 299 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 300 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 301 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 302 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 303 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 304 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 305 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 306 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 307 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 308 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 309 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 310 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 311 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 312 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 313 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 314 0xF9, 0xFA 315}; 316 317/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */ 318#define NO_OF_COMPONENTS 0x3 //Y,U,V 319#define BASELINE_PRECISION 0x8 //MCU size (?) 320static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT 321static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC 322static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC 323 324/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */ 325static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; 326static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; 327 328/* ========================================================================= 329 Local helper functions: 330 331 calculation and setup of parameter-dependent JPEG baseline segments 332 (needed for compression only) 333 ========================================================================= */ 334 335/* ------------------------------------------------------------------------- */ 336 337/* SOF (start of frame) segment depends on width, height and sampling ratio 338 of each color component */ 339 340static int 341zr36060_set_sof (struct zr36060 *ptr) 342{ 343 char sof_data[34]; // max. size of register set 344 int i; 345 346 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, 347 ptr->width, ptr->height, NO_OF_COMPONENTS); 348 sof_data[0] = 0xff; 349 sof_data[1] = 0xc0; 350 sof_data[2] = 0x00; 351 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8; 352 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060 353 sof_data[5] = (ptr->height) >> 8; 354 sof_data[6] = (ptr->height) & 0xff; 355 sof_data[7] = (ptr->width) >> 8; 356 sof_data[8] = (ptr->width) & 0xff; 357 sof_data[9] = NO_OF_COMPONENTS; 358 for (i = 0; i < NO_OF_COMPONENTS; i++) { 359 sof_data[10 + (i * 3)] = i; // index identifier 360 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | 361 (ptr->v_samp_ratio[i]); // sampling ratios 362 sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection 363 } 364 return zr36060_pushit(ptr, ZR060_SOF_IDX, 365 (3 * NO_OF_COMPONENTS) + 10, sof_data); 366} 367 368/* ------------------------------------------------------------------------- */ 369 370/* SOS (start of scan) segment depends on the used scan components 371 of each color component */ 372 373static int 374zr36060_set_sos (struct zr36060 *ptr) 375{ 376 char sos_data[16]; // max. size of register set 377 int i; 378 379 dprintk(3, "%s: write SOS\n", ptr->name); 380 sos_data[0] = 0xff; 381 sos_data[1] = 0xda; 382 sos_data[2] = 0x00; 383 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3; 384 sos_data[4] = NO_OF_COMPONENTS; 385 for (i = 0; i < NO_OF_COMPONENTS; i++) { 386 sos_data[5 + (i * 2)] = i; // index 387 sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) | 388 zr36060_ta[i]; // AC/DC tbl.sel. 389 } 390 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start 391 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f; 392 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00; 393 return zr36060_pushit(ptr, ZR060_SOS_IDX, 394 4 + 1 + (2 * NO_OF_COMPONENTS) + 3, 395 sos_data); 396} 397 398/* ------------------------------------------------------------------------- */ 399 400/* DRI (define restart interval) */ 401 402static int 403zr36060_set_dri (struct zr36060 *ptr) 404{ 405 char dri_data[6]; // max. size of register set 406 407 dprintk(3, "%s: write DRI\n", ptr->name); 408 dri_data[0] = 0xff; 409 dri_data[1] = 0xdd; 410 dri_data[2] = 0x00; 411 dri_data[3] = 0x04; 412 dri_data[4] = (ptr->dri) >> 8; 413 dri_data[5] = (ptr->dri) & 0xff; 414 return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data); 415} 416 417/* ========================================================================= 418 Setup function: 419 420 Setup compression/decompression of Zoran's JPEG processor 421 ( see also zoran 36060 manual ) 422 423 ... sorry for the spaghetti code ... 424 ========================================================================= */ 425static void 426zr36060_init (struct zr36060 *ptr) 427{ 428 int sum = 0; 429 long bitcnt, tmp; 430 431 if (ptr->mode == CODEC_DO_COMPRESSION) { 432 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); 433 434 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); 435 436 /* 060 communicates with 067 in master mode */ 437 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); 438 439 /* Compression with or without variable scale factor */ 440 zr36060_write(ptr, ZR060_CMR, 441 ZR060_CMR_Comp | ZR060_CMR_Pass2 | 442 ZR060_CMR_BRB); 443 444 /* Must be zero */ 445 zr36060_write(ptr, ZR060_MBZ, 0x00); 446 zr36060_write(ptr, ZR060_TCR_HI, 0x00); 447 zr36060_write(ptr, ZR060_TCR_LO, 0x00); 448 449 /* Disable all IRQs - no DataErr means autoreset */ 450 zr36060_write(ptr, ZR060_IMR, 0); 451 452 /* volume control settings */ 453 zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8); 454 zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff); 455 456 zr36060_write(ptr, ZR060_AF_HI, 0xff); 457 zr36060_write(ptr, ZR060_AF_M, 0xff); 458 zr36060_write(ptr, ZR060_AF_LO, 0xff); 459 460 /* setup the variable jpeg tables */ 461 sum += zr36060_set_sof(ptr); 462 sum += zr36060_set_sos(ptr); 463 sum += zr36060_set_dri(ptr); 464 465 /* setup the fixed jpeg tables - maybe variable, though - 466 * (see table init section above) */ 467 sum += 468 zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), 469 zr36060_dqt); 470 sum += 471 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), 472 zr36060_dht); 473 zr36060_write(ptr, ZR060_APP_IDX, 0xff); 474 zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn); 475 zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00); 476 zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2); 477 sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, 478 ptr->app.data) + 4; 479 zr36060_write(ptr, ZR060_COM_IDX, 0xff); 480 zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe); 481 zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00); 482 zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2); 483 sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, 484 ptr->com.data) + 4; 485 486 /* setup misc. data for compression (target code sizes) */ 487 488 /* size of compressed code to reach without header data */ 489 sum = ptr->real_code_vol - sum; 490 bitcnt = sum << 3; /* need the size in bits */ 491 492 tmp = bitcnt >> 16; 493 dprintk(3, 494 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", 495 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); 496 zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8); 497 zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff); 498 tmp = bitcnt & 0xffff; 499 zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8); 500 zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff); 501 502 bitcnt -= bitcnt >> 7; // bits without stuffing 503 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob 504 505 tmp = bitcnt >> 16; 506 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", 507 ptr->name, bitcnt, tmp); 508 zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8); 509 zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff); 510 tmp = bitcnt & 0xffff; 511 zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8); 512 zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff); 513 514 /* JPEG markers to be included in the compressed stream */ 515 zr36060_write(ptr, ZR060_MER, 516 ZR060_MER_DQT | ZR060_MER_DHT | 517 ((ptr->com.len > 0) ? ZR060_MER_Com : 0) | 518 ((ptr->app.len > 0) ? ZR060_MER_App : 0)); 519 520 /* Setup the Video Frontend */ 521 /* Limit pixel range to 16..235 as per CCIR-601 */ 522 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); 523 524 } else { 525 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); 526 527 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); 528 529 /* 060 communicates with 067 in master mode */ 530 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); 531 532 /* Decompression */ 533 zr36060_write(ptr, ZR060_CMR, 0); 534 535 /* Must be zero */ 536 zr36060_write(ptr, ZR060_MBZ, 0x00); 537 zr36060_write(ptr, ZR060_TCR_HI, 0x00); 538 zr36060_write(ptr, ZR060_TCR_LO, 0x00); 539 540 /* Disable all IRQs - no DataErr means autoreset */ 541 zr36060_write(ptr, ZR060_IMR, 0); 542 543 /* setup misc. data for expansion */ 544 zr36060_write(ptr, ZR060_MER, 0); 545 546 /* setup the fixed jpeg tables - maybe variable, though - 547 * (see table init section above) */ 548 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), 549 zr36060_dht); 550 551 /* Setup the Video Frontend */ 552 //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt); 553 //this doesn't seem right and doesn't work... 554 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); 555 } 556 557 /* Load the tables */ 558 zr36060_write(ptr, ZR060_LOAD, 559 ZR060_LOAD_SyncRst | ZR060_LOAD_Load); 560 zr36060_wait_end(ptr); 561 dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name, 562 ptr->status); 563 564 if (ptr->status & ZR060_CFSR_Busy) { 565 dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name); 566 return; // something is wrong, its timed out!!!! 567 } 568} 569 570/* ========================================================================= 571 CODEC API FUNCTIONS 572 573 this functions are accessed by the master via the API structure 574 ========================================================================= */ 575 576/* set compression/expansion mode and launches codec - 577 this should be the last call from the master before starting processing */ 578static int 579zr36060_set_mode (struct videocodec *codec, 580 int mode) 581{ 582 struct zr36060 *ptr = (struct zr36060 *) codec->data; 583 584 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); 585 586 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) 587 return -EINVAL; 588 589 ptr->mode = mode; 590 zr36060_init(ptr); 591 592 return 0; 593} 594 595/* set picture size (norm is ignored as the codec doesn't know about it) */ 596static int 597zr36060_set_video (struct videocodec *codec, 598 struct tvnorm *norm, 599 struct vfe_settings *cap, 600 struct vfe_polarity *pol) 601{ 602 struct zr36060 *ptr = (struct zr36060 *) codec->data; 603 u32 reg; 604 int size; 605 606 dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name, 607 cap->x, cap->y, cap->width, cap->height, cap->decimation); 608 609 /* if () return -EINVAL; 610 * trust the master driver that it knows what it does - so 611 * we allow invalid startx/y and norm for now ... */ 612 ptr->width = cap->width / (cap->decimation & 0xff); 613 ptr->height = cap->height / (cap->decimation >> 8); 614 615 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); 616 617 /* Note that VSPol/HSPol bits in zr36060 have the opposite 618 * meaning of their zr360x7 counterparts with the same names 619 * N.b. for VSPol this is only true if FIVEdge = 0 (default, 620 * left unchanged here - in accordance with datasheet). 621 */ 622 reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0) 623 | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0) 624 | (pol->field_pol ? ZR060_VPR_FIPol : 0) 625 | (pol->blank_pol ? ZR060_VPR_BLPol : 0) 626 | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0) 627 | (pol->poe_pol ? ZR060_VPR_PoePol : 0) 628 | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0) 629 | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0); 630 zr36060_write(ptr, ZR060_VPR, reg); 631 632 reg = 0; 633 switch (cap->decimation & 0xff) { 634 default: 635 case 1: 636 break; 637 638 case 2: 639 reg |= ZR060_SR_HScale2; 640 break; 641 642 case 4: 643 reg |= ZR060_SR_HScale4; 644 break; 645 } 646 647 switch (cap->decimation >> 8) { 648 default: 649 case 1: 650 break; 651 652 case 2: 653 reg |= ZR060_SR_VScale; 654 break; 655 } 656 zr36060_write(ptr, ZR060_SR, reg); 657 658 zr36060_write(ptr, ZR060_BCR_Y, 0x00); 659 zr36060_write(ptr, ZR060_BCR_U, 0x80); 660 zr36060_write(ptr, ZR060_BCR_V, 0x80); 661 662 /* sync generator */ 663 664 reg = norm->Ht - 1; /* Vtotal */ 665 zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff); 666 zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff); 667 668 reg = norm->Wt - 1; /* Htotal */ 669 zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff); 670 zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff); 671 672 reg = 6 - 1; /* VsyncSize */ 673 zr36060_write(ptr, ZR060_SGR_VSYNC, reg); 674 675 //reg = 30 - 1; /* HsyncSize */ 676///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68); 677 reg = 68; 678 zr36060_write(ptr, ZR060_SGR_HSYNC, reg); 679 680 reg = norm->VStart - 1; /* BVstart */ 681 zr36060_write(ptr, ZR060_SGR_BVSTART, reg); 682 683 reg += norm->Ha / 2; /* BVend */ 684 zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff); 685 zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff); 686 687 reg = norm->HStart - 1; /* BHstart */ 688 zr36060_write(ptr, ZR060_SGR_BHSTART, reg); 689 690 reg += norm->Wa; /* BHend */ 691 zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff); 692 zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff); 693 694 /* active area */ 695 reg = cap->y + norm->VStart; /* Vstart */ 696 zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff); 697 zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff); 698 699 reg += cap->height; /* Vend */ 700 zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff); 701 zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff); 702 703 reg = cap->x + norm->HStart; /* Hstart */ 704 zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff); 705 zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff); 706 707 reg += cap->width; /* Hend */ 708 zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff); 709 zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff); 710 711 /* subimage area */ 712 reg = norm->VStart - 4; /* SVstart */ 713 zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff); 714 zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff); 715 716 reg += norm->Ha / 2 + 8; /* SVend */ 717 zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff); 718 zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff); 719 720 reg = norm->HStart /*+ 64 */ - 4; /* SHstart */ 721 zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff); 722 zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff); 723 724 reg += norm->Wa + 8; /* SHend */ 725 zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff); 726 zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff); 727 728 size = ptr->width * ptr->height; 729 /* Target compressed field size in bits: */ 730 size = size * 16; /* uncompressed size in bits */ 731 /* (Ronald) by default, quality = 100 is a compression 732 * ratio 1:2. Setting low_bitrate (insmod option) sets 733 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the 734 * buz can't handle more at decimation=1... Use low_bitrate if 735 * you have a Buz, unless you know what you're doing */ 736 size = size * cap->quality / (low_bitrate ? 400 : 200); 737 /* Lower limit (arbitrary, 1 KB) */ 738 if (size < 8192) 739 size = 8192; 740 /* Upper limit: 7/8 of the code buffers */ 741 if (size > ptr->total_code_vol * 7) 742 size = ptr->total_code_vol * 7; 743 744 ptr->real_code_vol = size >> 3; /* in bytes */ 745 746 /* the MBCVR is the *maximum* block volume, according to the 747 * JPEG ISO specs, this shouldn't be used, since that allows 748 * for the best encoding quality. So set it to it's max value */ 749 reg = ptr->max_block_vol; 750 zr36060_write(ptr, ZR060_MBCVR, reg); 751 752 return 0; 753} 754 755/* additional control functions */ 756static int 757zr36060_control (struct videocodec *codec, 758 int type, 759 int size, 760 void *data) 761{ 762 struct zr36060 *ptr = (struct zr36060 *) codec->data; 763 int *ival = (int *) data; 764 765 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, 766 size); 767 768 switch (type) { 769 case CODEC_G_STATUS: /* get last status */ 770 if (size != sizeof(int)) 771 return -EFAULT; 772 zr36060_read_status(ptr); 773 *ival = ptr->status; 774 break; 775 776 case CODEC_G_CODEC_MODE: 777 if (size != sizeof(int)) 778 return -EFAULT; 779 *ival = CODEC_MODE_BJPG; 780 break; 781 782 case CODEC_S_CODEC_MODE: 783 if (size != sizeof(int)) 784 return -EFAULT; 785 if (*ival != CODEC_MODE_BJPG) 786 return -EINVAL; 787 /* not needed, do nothing */ 788 return 0; 789 790 case CODEC_G_VFE: 791 case CODEC_S_VFE: 792 /* not needed, do nothing */ 793 return 0; 794 795 case CODEC_S_MMAP: 796 /* not available, give an error */ 797 return -ENXIO; 798 799 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ 800 if (size != sizeof(int)) 801 return -EFAULT; 802 *ival = ptr->total_code_vol; 803 break; 804 805 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ 806 if (size != sizeof(int)) 807 return -EFAULT; 808 ptr->total_code_vol = *ival; 809 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; 810 break; 811 812 case CODEC_G_JPEG_SCALE: /* get scaling factor */ 813 if (size != sizeof(int)) 814 return -EFAULT; 815 *ival = zr36060_read_scalefactor(ptr); 816 break; 817 818 case CODEC_S_JPEG_SCALE: /* set scaling factor */ 819 if (size != sizeof(int)) 820 return -EFAULT; 821 ptr->scalefact = *ival; 822 break; 823 824 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ 825 struct jpeg_app_marker *app = data; 826 827 if (size != sizeof(struct jpeg_app_marker)) 828 return -EFAULT; 829 830 *app = ptr->app; 831 break; 832 } 833 834 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ 835 struct jpeg_app_marker *app = data; 836 837 if (size != sizeof(struct jpeg_app_marker)) 838 return -EFAULT; 839 840 ptr->app = *app; 841 break; 842 } 843 844 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ 845 struct jpeg_com_marker *com = data; 846 847 if (size != sizeof(struct jpeg_com_marker)) 848 return -EFAULT; 849 850 *com = ptr->com; 851 break; 852 } 853 854 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ 855 struct jpeg_com_marker *com = data; 856 857 if (size != sizeof(struct jpeg_com_marker)) 858 return -EFAULT; 859 860 ptr->com = *com; 861 break; 862 } 863 864 default: 865 return -EINVAL; 866 } 867 868 return size; 869} 870 871/* ========================================================================= 872 Exit and unregister function: 873 874 Deinitializes Zoran's JPEG processor 875 ========================================================================= */ 876 877static int 878zr36060_unset (struct videocodec *codec) 879{ 880 struct zr36060 *ptr = codec->data; 881 882 if (ptr) { 883 /* do wee need some codec deinit here, too ???? */ 884 885 dprintk(1, "%s: finished codec #%d\n", ptr->name, 886 ptr->num); 887 kfree(ptr); 888 codec->data = NULL; 889 890 zr36060_codecs--; 891 return 0; 892 } 893 894 return -EFAULT; 895} 896 897/* ========================================================================= 898 Setup and registry function: 899 900 Initializes Zoran's JPEG processor 901 902 Also sets pixel size, average code size, mode (compr./decompr.) 903 (the given size is determined by the processor with the video interface) 904 ========================================================================= */ 905 906static int 907zr36060_setup (struct videocodec *codec) 908{ 909 struct zr36060 *ptr; 910 int res; 911 912 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", 913 zr36060_codecs); 914 915 if (zr36060_codecs == MAX_CODECS) { 916 dprintk(1, 917 KERN_ERR "zr36060: Can't attach more codecs!\n"); 918 return -ENOSPC; 919 } 920 //mem structure init 921 codec->data = ptr = kzalloc(sizeof(struct zr36060), GFP_KERNEL); 922 if (NULL == ptr) { 923 dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n"); 924 return -ENOMEM; 925 } 926 927 snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", 928 zr36060_codecs); 929 ptr->num = zr36060_codecs++; 930 ptr->codec = codec; 931 932 //testing 933 res = zr36060_basic_test(ptr); 934 if (res < 0) { 935 zr36060_unset(codec); 936 return res; 937 } 938 //final setup 939 memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8); 940 memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8); 941 942 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag 943 * (what is the difference?) */ 944 ptr->mode = CODEC_DO_COMPRESSION; 945 ptr->width = 384; 946 ptr->height = 288; 947 ptr->total_code_vol = 16000; /* CHECKME */ 948 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; 949 ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */ 950 ptr->scalefact = 0x100; 951 ptr->dri = 1; /* CHECKME, was 8 is 1 */ 952 953 /* by default, no COM or APP markers - app should set those */ 954 ptr->com.len = 0; 955 ptr->app.appn = 0; 956 ptr->app.len = 0; 957 958 zr36060_init(ptr); 959 960 dprintk(1, KERN_INFO "%s: codec attached and running\n", 961 ptr->name); 962 963 return 0; 964} 965 966static const struct videocodec zr36060_codec = { 967 .owner = THIS_MODULE, 968 .name = "zr36060", 969 .magic = 0L, // magic not used 970 .flags = 971 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | 972 CODEC_FLAG_DECODER | CODEC_FLAG_VFE, 973 .type = CODEC_TYPE_ZR36060, 974 .setup = zr36060_setup, // functionality 975 .unset = zr36060_unset, 976 .set_mode = zr36060_set_mode, 977 .set_video = zr36060_set_video, 978 .control = zr36060_control, 979 // others are not used 980}; 981 982/* ========================================================================= 983 HOOK IN DRIVER AS KERNEL MODULE 984 ========================================================================= */ 985 986static int __init 987zr36060_init_module (void) 988{ 989 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION); 990 zr36060_codecs = 0; 991 return videocodec_register(&zr36060_codec); 992} 993 994static void __exit 995zr36060_cleanup_module (void) 996{ 997 if (zr36060_codecs) { 998 dprintk(1, 999 "zr36060: something's wrong - %d codecs left somehow.\n", 1000 zr36060_codecs); 1001 } 1002 1003 /* however, we can't just stay alive */ 1004 videocodec_unregister(&zr36060_codec); 1005} 1006 1007module_init(zr36060_init_module); 1008module_exit(zr36060_cleanup_module); 1009 1010MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>"); 1011MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors " 1012 ZR060_VERSION); 1013MODULE_LICENSE("GPL"); 1014