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