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