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