2 * Zoran ZR36060 basic configuration functions
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
6 * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 rbultje Exp $
8 * ------------------------------------------------------------------------
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.
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.
20 * ------------------------------------------------------------------------
23 #define ZR060_VERSION "v0.7"
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/delay.h>
30 #include <linux/types.h>
31 #include <linux/wait.h>
33 /* I/O commands, error codes */
36 /* headerfile of this module */
40 #include "videocodec.h"
42 /* it doesn't make sense to have more than 20 or so,
43 just to prevent some unwanted loops */
46 /* amount of chips attached via this driver */
47 static int zr36060_codecs
;
49 static bool low_bitrate
;
50 module_param(low_bitrate
, bool, 0);
51 MODULE_PARM_DESC(low_bitrate
, "Buz compatibility option, halves bitrate");
53 /* debugging is available via module parameter */
55 module_param(debug
, int, 0);
56 MODULE_PARM_DESC(debug
, "Debug level (0-4)");
58 #define dprintk(num, format, args...) \
61 printk(format, ##args); \
64 /* =========================================================================
65 Local hardware I/O functions:
67 read/write via codec layer (registers are located in the master device)
68 ========================================================================= */
70 /* read and write functions */
72 zr36060_read (struct zr36060
*ptr
,
77 // just in case something is wrong...
78 if (ptr
->codec
->master_data
->readreg
)
79 value
= (ptr
->codec
->master_data
->readreg(ptr
->codec
,
83 KERN_ERR
"%s: invalid I/O setup, nothing read!\n",
86 //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
92 zr36060_write(struct zr36060
*ptr
,
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
);
99 // just in case something is wrong...
100 if (ptr
->codec
->master_data
->writereg
)
101 ptr
->codec
->master_data
->writereg(ptr
->codec
, reg
, value
);
105 "%s: invalid I/O setup, nothing written!\n",
109 /* =========================================================================
110 Local helper function:
113 ========================================================================= */
115 /* status is kept in datastructure */
117 zr36060_read_status (struct zr36060
*ptr
)
119 ptr
->status
= zr36060_read(ptr
, ZR060_CFSR
);
121 zr36060_read(ptr
, 0);
125 /* =========================================================================
126 Local helper function:
129 ========================================================================= */
131 /* scale factor is kept in datastructure */
133 zr36060_read_scalefactor (struct zr36060
*ptr
)
135 ptr
->scalefact
= (zr36060_read(ptr
, ZR060_SF_HI
) << 8) |
136 (zr36060_read(ptr
, ZR060_SF_LO
) & 0xFF);
138 /* leave 0 selected for an eventually GO from master */
139 zr36060_read(ptr
, 0);
140 return ptr
->scalefact
;
143 /* =========================================================================
144 Local helper function:
146 wait if codec is ready to proceed (end of processing) or time is over
147 ========================================================================= */
150 zr36060_wait_end (struct zr36060
*ptr
)
154 while (zr36060_read_status(ptr
) & ZR060_CFSR_Busy
) {
156 if (i
++ > 200000) { // 200ms, there is for sure something wrong!!!
158 "%s: timeout at wait_end (last status: 0x%02x)\n",
159 ptr
->name
, ptr
->status
);
165 /* =========================================================================
166 Local helper function:
168 basic test of "connectivity", writes/reads to/from memory the SOF marker
169 ========================================================================= */
172 zr36060_basic_test (struct zr36060
*ptr
)
174 if ((zr36060_read(ptr
, ZR060_IDR_DEV
) != 0x33) &&
175 (zr36060_read(ptr
, ZR060_IDR_REV
) != 0x01)) {
178 "%s: attach failed, can't connect to jpeg processor!\n",
183 zr36060_wait_end(ptr
);
184 if (ptr
->status
& ZR060_CFSR_Busy
) {
187 "%s: attach failed, jpeg processor failed (end flag)!\n",
192 return 0; /* looks good! */
195 /* =========================================================================
196 Local helper function:
198 simple loop for pushing the init datasets
199 ========================================================================= */
202 zr36060_pushit (struct zr36060
*ptr
,
209 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr
->name
,
212 zr36060_write(ptr
, startreg
++, data
[i
++]);
218 /* =========================================================================
221 jpeg baseline setup data (you find it on lots places in internet, or just
222 extract it from any regular .jpg image...)
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 ========================================================================= */
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
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,
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,
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
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 };
320 /* =========================================================================
321 Local helper functions:
323 calculation and setup of parameter-dependent JPEG baseline segments
324 (needed for compression only)
325 ========================================================================= */
327 /* ------------------------------------------------------------------------- */
329 /* SOF (start of frame) segment depends on width, height and sampling ratio
330 of each color component */
333 zr36060_set_sof (struct zr36060
*ptr
)
335 char sof_data
[34]; // max. size of register set
338 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr
->name
,
339 ptr
->width
, ptr
->height
, NO_OF_COMPONENTS
);
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
356 return zr36060_pushit(ptr
, ZR060_SOF_IDX
,
357 (3 * NO_OF_COMPONENTS
) + 10, sof_data
);
360 /* ------------------------------------------------------------------------- */
362 /* SOS (start of scan) segment depends on the used scan components
363 of each color component */
366 zr36060_set_sos (struct zr36060
*ptr
)
368 char sos_data
[16]; // max. size of register set
371 dprintk(3, "%s: write SOS\n", ptr
->name
);
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.
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,
390 /* ------------------------------------------------------------------------- */
392 /* DRI (define restart interval) */
395 zr36060_set_dri (struct zr36060
*ptr
)
397 char dri_data
[6]; // max. size of register set
399 dprintk(3, "%s: write DRI\n", ptr
->name
);
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
);
409 /* =========================================================================
412 Setup compression/decompression of Zoran's JPEG processor
413 ( see also zoran 36060 manual )
415 ... sorry for the spaghetti code ...
416 ========================================================================= */
418 zr36060_init (struct zr36060
*ptr
)
423 if (ptr
->mode
== CODEC_DO_COMPRESSION
) {
424 dprintk(2, "%s: COMPRESSION SETUP\n", ptr
->name
);
426 zr36060_write(ptr
, ZR060_LOAD
, ZR060_LOAD_SyncRst
);
428 /* 060 communicates with 067 in master mode */
429 zr36060_write(ptr
, ZR060_CIR
, ZR060_CIR_CodeMstr
);
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
|
438 zr36060_write(ptr
, ZR060_MBZ
, 0x00);
439 zr36060_write(ptr
, ZR060_TCR_HI
, 0x00);
440 zr36060_write(ptr
, ZR060_TCR_LO
, 0x00);
442 /* Disable all IRQs - no DataErr means autoreset */
443 zr36060_write(ptr
, ZR060_IMR
, 0);
445 /* volume control settings */
446 zr36060_write(ptr
, ZR060_SF_HI
, ptr
->scalefact
>> 8);
447 zr36060_write(ptr
, ZR060_SF_LO
, ptr
->scalefact
& 0xff);
449 zr36060_write(ptr
, ZR060_AF_HI
, 0xff);
450 zr36060_write(ptr
, ZR060_AF_M
, 0xff);
451 zr36060_write(ptr
, ZR060_AF_LO
, 0xff);
453 /* setup the variable jpeg tables */
454 sum
+= zr36060_set_sof(ptr
);
455 sum
+= zr36060_set_sos(ptr
);
456 sum
+= zr36060_set_dri(ptr
);
458 /* setup the fixed jpeg tables - maybe variable, though -
459 * (see table init section above) */
461 zr36060_pushit(ptr
, ZR060_DQT_IDX
, sizeof(zr36060_dqt
),
464 zr36060_pushit(ptr
, ZR060_DHT_IDX
, sizeof(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,
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,
479 /* setup misc. data for compression (target code sizes) */
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 */
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);
495 bitcnt
-= bitcnt
>> 7; // bits without stuffing
496 bitcnt
-= ((bitcnt
* 5) >> 6); // bits without eob
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);
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));
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
);
518 dprintk(2, "%s: EXPANSION SETUP\n", ptr
->name
);
520 zr36060_write(ptr
, ZR060_LOAD
, ZR060_LOAD_SyncRst
);
522 /* 060 communicates with 067 in master mode */
523 zr36060_write(ptr
, ZR060_CIR
, ZR060_CIR_CodeMstr
);
526 zr36060_write(ptr
, ZR060_CMR
, 0);
529 zr36060_write(ptr
, ZR060_MBZ
, 0x00);
530 zr36060_write(ptr
, ZR060_TCR_HI
, 0x00);
531 zr36060_write(ptr
, ZR060_TCR_LO
, 0x00);
533 /* Disable all IRQs - no DataErr means autoreset */
534 zr36060_write(ptr
, ZR060_IMR
, 0);
536 /* setup misc. data for expansion */
537 zr36060_write(ptr
, ZR060_MER
, 0);
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
),
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
);
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
,
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!!!!
563 /* =========================================================================
566 this functions are accessed by the master via the API structure
567 ========================================================================= */
569 /* set compression/expansion mode and launches codec -
570 this should be the last call from the master before starting processing */
572 zr36060_set_mode (struct videocodec
*codec
,
575 struct zr36060
*ptr
= (struct zr36060
*) codec
->data
;
577 dprintk(2, "%s: set_mode %d call\n", ptr
->name
, mode
);
579 if ((mode
!= CODEC_DO_EXPANSION
) && (mode
!= CODEC_DO_COMPRESSION
))
588 /* set picture size (norm is ignored as the codec doesn't know about it) */
590 zr36060_set_video (struct videocodec
*codec
,
592 struct vfe_settings
*cap
,
593 struct vfe_polarity
*pol
)
595 struct zr36060
*ptr
= (struct zr36060
*) codec
->data
;
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
);
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);
608 zr36060_write(ptr
, ZR060_LOAD
, ZR060_LOAD_SyncRst
);
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).
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
);
626 switch (cap
->decimation
& 0xff) {
632 reg
|= ZR060_SR_HScale2
;
636 reg
|= ZR060_SR_HScale4
;
640 switch (cap
->decimation
>> 8) {
646 reg
|= ZR060_SR_VScale
;
649 zr36060_write(ptr
, ZR060_SR
, reg
);
651 zr36060_write(ptr
, ZR060_BCR_Y
, 0x00);
652 zr36060_write(ptr
, ZR060_BCR_U
, 0x80);
653 zr36060_write(ptr
, ZR060_BCR_V
, 0x80);
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);
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);
665 reg
= 6 - 1; /* VsyncSize */
666 zr36060_write(ptr
, ZR060_SGR_VSYNC
, reg
);
668 //reg = 30 - 1; /* HsyncSize */
669 ///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
671 zr36060_write(ptr
, ZR060_SGR_HSYNC
, reg
);
673 reg
= norm
->VStart
- 1; /* BVstart */
674 zr36060_write(ptr
, ZR060_SGR_BVSTART
, reg
);
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);
680 reg
= norm
->HStart
- 1; /* BHstart */
681 zr36060_write(ptr
, ZR060_SGR_BHSTART
, reg
);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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) */
733 /* Upper limit: 7/8 of the code buffers */
734 if (size
> ptr
->total_code_vol
* 7)
735 size
= ptr
->total_code_vol
* 7;
737 ptr
->real_code_vol
= size
>> 3; /* in bytes */
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
);
748 /* additional control functions */
750 zr36060_control (struct videocodec
*codec
,
755 struct zr36060
*ptr
= (struct zr36060
*) codec
->data
;
756 int *ival
= (int *) data
;
758 dprintk(2, "%s: control %d call with %d byte\n", ptr
->name
, type
,
762 case CODEC_G_STATUS
: /* get last status */
763 if (size
!= sizeof(int))
765 zr36060_read_status(ptr
);
769 case CODEC_G_CODEC_MODE
:
770 if (size
!= sizeof(int))
772 *ival
= CODEC_MODE_BJPG
;
775 case CODEC_S_CODEC_MODE
:
776 if (size
!= sizeof(int))
778 if (*ival
!= CODEC_MODE_BJPG
)
780 /* not needed, do nothing */
785 /* not needed, do nothing */
789 /* not available, give an error */
792 case CODEC_G_JPEG_TDS_BYTE
: /* get target volume in byte */
793 if (size
!= sizeof(int))
795 *ival
= ptr
->total_code_vol
;
798 case CODEC_S_JPEG_TDS_BYTE
: /* get target volume in byte */
799 if (size
!= sizeof(int))
801 ptr
->total_code_vol
= *ival
;
802 ptr
->real_code_vol
= (ptr
->total_code_vol
* 6) >> 3;
805 case CODEC_G_JPEG_SCALE
: /* get scaling factor */
806 if (size
!= sizeof(int))
808 *ival
= zr36060_read_scalefactor(ptr
);
811 case CODEC_S_JPEG_SCALE
: /* set scaling factor */
812 if (size
!= sizeof(int))
814 ptr
->scalefact
= *ival
;
817 case CODEC_G_JPEG_APP_DATA
: { /* get appn marker data */
818 struct jpeg_app_marker
*app
= data
;
820 if (size
!= sizeof(struct jpeg_app_marker
))
827 case CODEC_S_JPEG_APP_DATA
: { /* set appn marker data */
828 struct jpeg_app_marker
*app
= data
;
830 if (size
!= sizeof(struct jpeg_app_marker
))
837 case CODEC_G_JPEG_COM_DATA
: { /* get comment marker data */
838 struct jpeg_com_marker
*com
= data
;
840 if (size
!= sizeof(struct jpeg_com_marker
))
847 case CODEC_S_JPEG_COM_DATA
: { /* set comment marker data */
848 struct jpeg_com_marker
*com
= data
;
850 if (size
!= sizeof(struct jpeg_com_marker
))
864 /* =========================================================================
865 Exit and unregister function:
867 Deinitializes Zoran's JPEG processor
868 ========================================================================= */
871 zr36060_unset (struct videocodec
*codec
)
873 struct zr36060
*ptr
= codec
->data
;
876 /* do wee need some codec deinit here, too ???? */
878 dprintk(1, "%s: finished codec #%d\n", ptr
->name
,
890 /* =========================================================================
891 Setup and registry function:
893 Initializes Zoran's JPEG processor
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 ========================================================================= */
900 zr36060_setup (struct videocodec
*codec
)
905 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
908 if (zr36060_codecs
== MAX_CODECS
) {
910 KERN_ERR
"zr36060: Can't attach more codecs!\n");
914 codec
->data
= ptr
= kzalloc(sizeof(struct zr36060
), GFP_KERNEL
);
916 dprintk(1, KERN_ERR
"zr36060: Can't get enough memory!\n");
920 snprintf(ptr
->name
, sizeof(ptr
->name
), "zr36060[%d]",
922 ptr
->num
= zr36060_codecs
++;
926 res
= zr36060_basic_test(ptr
);
928 zr36060_unset(codec
);
932 memcpy(ptr
->h_samp_ratio
, zr36060_decimation_h
, 8);
933 memcpy(ptr
->v_samp_ratio
, zr36060_decimation_v
, 8);
935 ptr
->bitrate_ctrl
= 0; /* 0 or 1 - fixed file size flag
936 * (what is the difference?) */
937 ptr
->mode
= CODEC_DO_COMPRESSION
;
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 */
946 /* by default, no COM or APP markers - app should set those */
953 dprintk(1, KERN_INFO
"%s: codec attached and running\n",
959 static const struct videocodec zr36060_codec
= {
960 .owner
= THIS_MODULE
,
962 .magic
= 0L, // magic not used
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
975 /* =========================================================================
976 HOOK IN DRIVER AS KERNEL MODULE
977 ========================================================================= */
980 zr36060_init_module (void)
982 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
984 return videocodec_register(&zr36060_codec
);
988 zr36060_cleanup_module (void)
990 if (zr36060_codecs
) {
992 "zr36060: something's wrong - %d codecs left somehow.\n",
996 /* however, we can't just stay alive */
997 videocodec_unregister(&zr36060_codec
);
1000 module_init(zr36060_init_module
);
1001 module_exit(zr36060_cleanup_module
);
1003 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
1004 MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
1006 MODULE_LICENSE("GPL");