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 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 */ 51static int zr36060_codecs; 52 53static int low_bitrate; 54module_param(low_bitrate, bool, 0); 55MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); 56 57/* debugging is available via module parameter */ 58static int debug; 59module_param(debug, int, 0); 60MODULE_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 */ 75static u8 76zr36060_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 95static void 96zr36060_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 */ 120static u8 121zr36060_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 */ 136static u16 137zr36060_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 153static void 154zr36060_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 175static int 176zr36060_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 205static int 206zr36060_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 233static 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 256static 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 (?) 316static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT 317static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC 318static 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) */ 321static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; 322static 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 336static int 337zr36060_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 369static int 370zr36060_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 398static int 399zr36060_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 ========================================================================= */ 421static void 422zr36060_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 zr36060_write(ptr, ZR060_CMR, 437 ZR060_CMR_Comp | ZR060_CMR_Pass2 | 438 ZR060_CMR_BRB); 439 440 /* Must be zero */ 441 zr36060_write(ptr, ZR060_MBZ, 0x00); 442 zr36060_write(ptr, ZR060_TCR_HI, 0x00); 443 zr36060_write(ptr, ZR060_TCR_LO, 0x00); 444 445 /* Disable all IRQs - no DataErr means autoreset */ 446 zr36060_write(ptr, ZR060_IMR, 0); 447 448 /* volume control settings */ 449 zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8); 450 zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff); 451 452 zr36060_write(ptr, ZR060_AF_HI, 0xff); 453 zr36060_write(ptr, ZR060_AF_M, 0xff); 454 zr36060_write(ptr, ZR060_AF_LO, 0xff); 455 456 /* setup the variable jpeg tables */ 457 sum += zr36060_set_sof(ptr); 458 sum += zr36060_set_sos(ptr); 459 sum += zr36060_set_dri(ptr); 460 461 /* setup the fixed jpeg tables - maybe variable, though - 462 * (see table init section above) */ 463 sum += 464 zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), 465 zr36060_dqt); 466 sum += 467 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), 468 zr36060_dht); 469 zr36060_write(ptr, ZR060_APP_IDX, 0xff); 470 zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn); 471 zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00); 472 zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2); 473 sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, 474 ptr->app.data) + 4; 475 zr36060_write(ptr, ZR060_COM_IDX, 0xff); 476 zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe); 477 zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00); 478 zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2); 479 sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, 480 ptr->com.data) + 4; 481 482 /* setup misc. data for compression (target code sizes) */ 483 484 /* size of compressed code to reach without header data */ 485 sum = ptr->real_code_vol - sum; 486 bitcnt = sum << 3; /* need the size in bits */ 487 488 tmp = bitcnt >> 16; 489 dprintk(3, 490 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", 491 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); 492 zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8); 493 zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff); 494 tmp = bitcnt & 0xffff; 495 zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8); 496 zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff); 497 498 bitcnt -= bitcnt >> 7; // bits without stuffing 499 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob 500 501 tmp = bitcnt >> 16; 502 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", 503 ptr->name, bitcnt, tmp); 504 zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8); 505 zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff); 506 tmp = bitcnt & 0xffff; 507 zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8); 508 zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff); 509 510 /* JPEG markers to be included in the compressed stream */ 511 zr36060_write(ptr, ZR060_MER, 512 ZR060_MER_DQT | ZR060_MER_DHT | 513 ((ptr->com.len > 0) ? ZR060_MER_Com : 0) | 514 ((ptr->app.len > 0) ? ZR060_MER_App : 0)); 515 516 /* Setup the Video Frontend */ 517 /* Limit pixel range to 16..235 as per CCIR-601 */ 518 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); 519 520 } else { 521 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); 522 523 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); 524 525 /* 060 communicates with 067 in master mode */ 526 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); 527 528 /* Decompression */ 529 zr36060_write(ptr, ZR060_CMR, 0); 530 531 /* Must be zero */ 532 zr36060_write(ptr, ZR060_MBZ, 0x00); 533 zr36060_write(ptr, ZR060_TCR_HI, 0x00); 534 zr36060_write(ptr, ZR060_TCR_LO, 0x00); 535 536 /* Disable all IRQs - no DataErr means autoreset */ 537 zr36060_write(ptr, ZR060_IMR, 0); 538 539 /* setup misc. data for expansion */ 540 zr36060_write(ptr, ZR060_MER, 0); 541 542 /* setup the fixed jpeg tables - maybe variable, though - 543 * (see table init section above) */ 544 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), 545 zr36060_dht); 546 547 /* Setup the Video Frontend */ 548 //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt); 549 //this doesn't seem right and doesn't work... 550 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); 551 } 552 553 /* Load the tables */ 554 zr36060_write(ptr, ZR060_LOAD, 555 ZR060_LOAD_SyncRst | ZR060_LOAD_Load); 556 zr36060_wait_end(ptr); 557 dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name, 558 ptr->status); 559 560 if (ptr->status & ZR060_CFSR_Busy) { 561 dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name); 562 return; // something is wrong, its timed out!!!! 563 } 564} 565 566/* ========================================================================= 567 CODEC API FUNCTIONS 568 569 this functions are accessed by the master via the API structure 570 ========================================================================= */ 571 572/* set compression/expansion mode and launches codec - 573 this should be the last call from the master before starting processing */ 574static int 575zr36060_set_mode (struct videocodec *codec, 576 int mode) 577{ 578 struct zr36060 *ptr = (struct zr36060 *) codec->data; 579 580 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); 581 582 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) 583 return -EINVAL; 584 585 ptr->mode = mode; 586 zr36060_init(ptr); 587 588 return 0; 589} 590 591/* set picture size (norm is ignored as the codec doesn't know about it) */ 592static int 593zr36060_set_video (struct videocodec *codec, 594 struct tvnorm *norm, 595 struct vfe_settings *cap, 596 struct vfe_polarity *pol) 597{ 598 struct zr36060 *ptr = (struct zr36060 *) codec->data; 599 u32 reg; 600 int size; 601 602 dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name, 603 cap->x, cap->y, cap->width, cap->height, cap->decimation); 604 605 /* if () return -EINVAL; 606 * trust the master driver that it knows what it does - so 607 * we allow invalid startx/y and norm for now ... */ 608 ptr->width = cap->width / (cap->decimation & 0xff); 609 ptr->height = cap->height / (cap->decimation >> 8); 610 611 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); 612 613 /* Note that VSPol/HSPol bits in zr36060 have the opposite 614 * meaning of their zr360x7 counterparts with the same names 615 * N.b. for VSPol this is only true if FIVEdge = 0 (default, 616 * left unchanged here - in accordance with datasheet). 617 */ 618 reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0) 619 | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0) 620 | (pol->field_pol ? ZR060_VPR_FIPol : 0) 621 | (pol->blank_pol ? ZR060_VPR_BLPol : 0) 622 | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0) 623 | (pol->poe_pol ? ZR060_VPR_PoePol : 0) 624 | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0) 625 | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0); 626 zr36060_write(ptr, ZR060_VPR, reg); 627 628 reg = 0; 629 switch (cap->decimation & 0xff) { 630 default: 631 case 1: 632 break; 633 634 case 2: 635 reg |= ZR060_SR_HScale2; 636 break; 637 638 case 4: 639 reg |= ZR060_SR_HScale4; 640 break; 641 } 642 643 switch (cap->decimation >> 8) { 644 default: 645 case 1: 646 break; 647 648 case 2: 649 reg |= ZR060_SR_VScale; 650 break; 651 } 652 zr36060_write(ptr, ZR060_SR, reg); 653 654 zr36060_write(ptr, ZR060_BCR_Y, 0x00); 655 zr36060_write(ptr, ZR060_BCR_U, 0x80); 656 zr36060_write(ptr, ZR060_BCR_V, 0x80); 657 658 /* sync generator */ 659 660 reg = norm->Ht - 1; /* Vtotal */ 661 zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff); 662 zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff); 663 664 reg = norm->Wt - 1; /* Htotal */ 665 zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff); 666 zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff); 667 668 reg = 6 - 1; /* VsyncSize */ 669 zr36060_write(ptr, ZR060_SGR_VSYNC, reg); 670 671 //reg = 30 - 1; /* HsyncSize */ 672///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68); 673 reg = 68; 674 zr36060_write(ptr, ZR060_SGR_HSYNC, reg); 675 676 reg = norm->VStart - 1; /* BVstart */ 677 zr36060_write(ptr, ZR060_SGR_BVSTART, reg); 678 679 reg += norm->Ha / 2; /* BVend */ 680 zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff); 681 zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff); 682 683 reg = norm->HStart - 1; /* BHstart */ 684 zr36060_write(ptr, ZR060_SGR_BHSTART, reg); 685 686 reg += norm->Wa; /* BHend */ 687 zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff); 688 zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff); 689 690 /* active area */ 691 reg = cap->y + norm->VStart; /* Vstart */ 692 zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff); 693 zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff); 694 695 reg += cap->height; /* Vend */ 696 zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff); 697 zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff); 698 699 reg = cap->x + norm->HStart; /* Hstart */ 700 zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff); 701 zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff); 702 703 reg += cap->width; /* Hend */ 704 zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff); 705 zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff); 706 707 /* subimage area */ 708 reg = norm->VStart - 4; /* SVstart */ 709 zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff); 710 zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff); 711 712 reg += norm->Ha / 2 + 8; /* SVend */ 713 zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff); 714 zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff); 715 716 reg = norm->HStart /*+ 64 */ - 4; /* SHstart */ 717 zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff); 718 zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff); 719 720 reg += norm->Wa + 8; /* SHend */ 721 zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff); 722 zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff); 723 724 size = ptr->width * ptr->height; 725 /* Target compressed field size in bits: */ 726 size = size * 16; /* uncompressed size in bits */ 727 /* (Ronald) by default, quality = 100 is a compression 728 * ratio 1:2. Setting low_bitrate (insmod option) sets 729 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the 730 * buz can't handle more at decimation=1... Use low_bitrate if 731 * you have a Buz, unless you know what you're doing */ 732 size = size * cap->quality / (low_bitrate ? 400 : 200); 733 /* Lower limit (arbitrary, 1 KB) */ 734 if (size < 8192) 735 size = 8192; 736 /* Upper limit: 7/8 of the code buffers */ 737 if (size > ptr->total_code_vol * 7) 738 size = ptr->total_code_vol * 7; 739 740 ptr->real_code_vol = size >> 3; /* in bytes */ 741 742 /* the MBCVR is the *maximum* block volume, according to the 743 * JPEG ISO specs, this shouldn't be used, since that allows 744 * for the best encoding quality. So set it to it's max value */ 745 reg = ptr->max_block_vol; 746 zr36060_write(ptr, ZR060_MBCVR, reg); 747 748 return 0; 749} 750 751/* additional control functions */ 752static int 753zr36060_control (struct videocodec *codec, 754 int type, 755 int size, 756 void *data) 757{ 758 struct zr36060 *ptr = (struct zr36060 *) codec->data; 759 int *ival = (int *) data; 760 761 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, 762 size); 763 764 switch (type) { 765 case CODEC_G_STATUS: /* get last status */ 766 if (size != sizeof(int)) 767 return -EFAULT; 768 zr36060_read_status(ptr); 769 *ival = ptr->status; 770 break; 771 772 case CODEC_G_CODEC_MODE: 773 if (size != sizeof(int)) 774 return -EFAULT; 775 *ival = CODEC_MODE_BJPG; 776 break; 777 778 case CODEC_S_CODEC_MODE: 779 if (size != sizeof(int)) 780 return -EFAULT; 781 if (*ival != CODEC_MODE_BJPG) 782 return -EINVAL; 783 /* not needed, do nothing */ 784 return 0; 785 786 case CODEC_G_VFE: 787 case CODEC_S_VFE: 788 /* not needed, do nothing */ 789 return 0; 790 791 case CODEC_S_MMAP: 792 /* not available, give an error */ 793 return -ENXIO; 794 795 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ 796 if (size != sizeof(int)) 797 return -EFAULT; 798 *ival = ptr->total_code_vol; 799 break; 800 801 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ 802 if (size != sizeof(int)) 803 return -EFAULT; 804 ptr->total_code_vol = *ival; 805 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; 806 break; 807 808 case CODEC_G_JPEG_SCALE: /* get scaling factor */ 809 if (size != sizeof(int)) 810 return -EFAULT; 811 *ival = zr36060_read_scalefactor(ptr); 812 break; 813 814 case CODEC_S_JPEG_SCALE: /* set scaling factor */ 815 if (size != sizeof(int)) 816 return -EFAULT; 817 ptr->scalefact = *ival; 818 break; 819 820 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ 821 struct jpeg_app_marker *app = data; 822 823 if (size != sizeof(struct jpeg_app_marker)) 824 return -EFAULT; 825 826 *app = ptr->app; 827 break; 828 } 829 830 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ 831 struct jpeg_app_marker *app = data; 832 833 if (size != sizeof(struct jpeg_app_marker)) 834 return -EFAULT; 835 836 ptr->app = *app; 837 break; 838 } 839 840 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ 841 struct jpeg_com_marker *com = data; 842 843 if (size != sizeof(struct jpeg_com_marker)) 844 return -EFAULT; 845 846 *com = ptr->com; 847 break; 848 } 849 850 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ 851 struct jpeg_com_marker *com = data; 852 853 if (size != sizeof(struct jpeg_com_marker)) 854 return -EFAULT; 855 856 ptr->com = *com; 857 break; 858 } 859 860 default: 861 return -EINVAL; 862 } 863 864 return size; 865} 866 867/* ========================================================================= 868 Exit and unregister function: 869 870 Deinitializes Zoran's JPEG processor 871 ========================================================================= */ 872 873static int 874zr36060_unset (struct videocodec *codec) 875{ 876 struct zr36060 *ptr = codec->data; 877 878 if (ptr) { 879 /* do wee need some codec deinit here, too ???? */ 880 881 dprintk(1, "%s: finished codec #%d\n", ptr->name, 882 ptr->num); 883 kfree(ptr); 884 codec->data = NULL; 885 886 zr36060_codecs--; 887 return 0; 888 } 889 890 return -EFAULT; 891} 892 893/* ========================================================================= 894 Setup and registry function: 895 896 Initializes Zoran's JPEG processor 897 898 Also sets pixel size, average code size, mode (compr./decompr.) 899 (the given size is determined by the processor with the video interface) 900 ========================================================================= */ 901 902static int 903zr36060_setup (struct videocodec *codec) 904{ 905 struct zr36060 *ptr; 906 int res; 907 908 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", 909 zr36060_codecs); 910 911 if (zr36060_codecs == MAX_CODECS) { 912 dprintk(1, 913 KERN_ERR "zr36060: Can't attach more codecs!\n"); 914 return -ENOSPC; 915 } 916 //mem structure init 917 codec->data = ptr = kzalloc(sizeof(struct zr36060), GFP_KERNEL); 918 if (NULL == ptr) { 919 dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n"); 920 return -ENOMEM; 921 } 922 923 snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", 924 zr36060_codecs); 925 ptr->num = zr36060_codecs++; 926 ptr->codec = codec; 927 928 //testing 929 res = zr36060_basic_test(ptr); 930 if (res < 0) { 931 zr36060_unset(codec); 932 return res; 933 } 934 //final setup 935 memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8); 936 memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8); 937 938 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag 939 * (what is the difference?) */ 940 ptr->mode = CODEC_DO_COMPRESSION; 941 ptr->width = 384; 942 ptr->height = 288; 943 ptr->total_code_vol = 16000; /* CHECKME */ 944 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; 945 ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */ 946 ptr->scalefact = 0x100; 947 ptr->dri = 1; /* CHECKME, was 8 is 1 */ 948 949 /* by default, no COM or APP markers - app should set those */ 950 ptr->com.len = 0; 951 ptr->app.appn = 0; 952 ptr->app.len = 0; 953 954 zr36060_init(ptr); 955 956 dprintk(1, KERN_INFO "%s: codec attached and running\n", 957 ptr->name); 958 959 return 0; 960} 961 962static const struct videocodec zr36060_codec = { 963 .owner = THIS_MODULE, 964 .name = "zr36060", 965 .magic = 0L, // magic not used 966 .flags = 967 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | 968 CODEC_FLAG_DECODER | CODEC_FLAG_VFE, 969 .type = CODEC_TYPE_ZR36060, 970 .setup = zr36060_setup, // functionality 971 .unset = zr36060_unset, 972 .set_mode = zr36060_set_mode, 973 .set_video = zr36060_set_video, 974 .control = zr36060_control, 975 // others are not used 976}; 977 978/* ========================================================================= 979 HOOK IN DRIVER AS KERNEL MODULE 980 ========================================================================= */ 981 982static int __init 983zr36060_init_module (void) 984{ 985 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION); 986 zr36060_codecs = 0; 987 return videocodec_register(&zr36060_codec); 988} 989 990static void __exit 991zr36060_cleanup_module (void) 992{ 993 if (zr36060_codecs) { 994 dprintk(1, 995 "zr36060: something's wrong - %d codecs left somehow.\n", 996 zr36060_codecs); 997 } 998 999 /* however, we can't just stay alive */ 1000 videocodec_unregister(&zr36060_codec); 1001} 1002 1003module_init(zr36060_init_module); 1004module_exit(zr36060_cleanup_module); 1005 1006MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>"); 1007MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors " 1008 ZR060_VERSION); 1009MODULE_LICENSE("GPL"); 1010