2 * Zoran ZR36050 basic configuration functions
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
6 * $Id: zr36050.c,v 1.1.2.11 2003/08/03 14:54:53 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 * 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.
24 * ------------------------------------------------------------------------
27 #define ZR050_VERSION "v0.7.1"
29 #include <linux/version.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/slab.h>
33 #include <linux/delay.h>
35 #include <linux/types.h>
36 #include <linux/wait.h>
38 /* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
41 /* I/O commands, error codes */
45 /* headerfile of this module */
49 #include"videocodec.h"
51 /* it doesn't make sense to have more than 20 or so,
52 just to prevent some unwanted loops */
55 /* amount of chips attached via this driver */
56 static int zr36050_codecs = 0;
58 /* debugging is available via module parameter */
61 MODULE_PARM(debug, "i");
62 MODULE_PARM_DESC(debug, "Debug level (0-4)");
64 #define dprintk(num, format, args...) \
67 printk(format, ##args); \
70 /* =========================================================================
71 Local hardware I/O functions:
73 read/write via codec layer (registers are located in the master device)
74 ========================================================================= */
76 /* read and write functions */
78 zr36050_read (struct zr36050 *ptr,
83 // just in case something is wrong...
84 if (ptr->codec->master_data->readreg)
85 value = (ptr->codec->master_data->readreg(ptr->codec,
89 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
92 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
99 zr36050_write (struct zr36050 *ptr,
103 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
106 // just in case something is wrong...
107 if (ptr->codec->master_data->writereg)
108 ptr->codec->master_data->writereg(ptr->codec, reg, value);
112 "%s: invalid I/O setup, nothing written!\n",
116 /* =========================================================================
117 Local helper function:
120 ========================================================================= */
122 /* status is kept in datastructure */
124 zr36050_read_status1 (struct zr36050 *ptr)
126 ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
128 zr36050_read(ptr, 0);
132 /* =========================================================================
133 Local helper function:
136 ========================================================================= */
138 /* scale factor is kept in datastructure */
140 zr36050_read_scalefactor (struct zr36050 *ptr)
142 ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
143 (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
145 /* leave 0 selected for an eventually GO from master */
146 zr36050_read(ptr, 0);
147 return ptr->scalefact;
150 /* =========================================================================
151 Local helper function:
153 wait if codec is ready to proceed (end of processing) or time is over
154 ========================================================================= */
157 zr36050_wait_end (struct zr36050 *ptr)
161 while (!(zr36050_read_status1(ptr) & 0x4)) {
163 if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
165 "%s: timout at wait_end (last status: 0x%02x)\n",
166 ptr->name, ptr->status1);
172 /* =========================================================================
173 Local helper function:
175 basic test of "connectivity", writes/reads to/from memory the SOF marker
176 ========================================================================= */
179 zr36050_basic_test (struct zr36050 *ptr)
181 zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
182 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
183 if ((zr36050_read(ptr, ZR050_SOF_IDX) |
184 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
187 "%s: attach failed, can't connect to jpeg processor!\n",
191 zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
192 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
193 if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
194 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
197 "%s: attach failed, can't connect to jpeg processor!\n",
202 zr36050_wait_end(ptr);
203 if ((ptr->status1 & 0x4) == 0) {
206 "%s: attach failed, jpeg processor failed (end flag)!\n",
211 return 0; /* looks good! */
214 /* =========================================================================
215 Local helper function:
217 simple loop for pushing the init datasets
218 ========================================================================= */
221 zr36050_pushit (struct zr36050 *ptr,
228 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
231 zr36050_write(ptr, startreg++, data[i++]);
237 /* =========================================================================
240 jpeg baseline setup data (you find it on lots places in internet, or just
241 extract it from any regular .jpg image...)
243 Could be variable, but until it's not needed it they are just fixed to save
244 memory. Otherwise expand zr36050 structure with arrays, push the values to
245 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
246 ========================================================================= */
248 static const char zr36050_dqt[0x86] = {
249 0xff, 0xdb, //Marker: DQT
250 0x00, 0x84, //Length: 2*65+2
251 0x00, //Pq,Tq first table
252 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
253 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
254 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
255 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
256 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
257 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
258 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
259 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
260 0x01, //Pq,Tq second table
261 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
262 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
263 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
264 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
265 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
266 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
267 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
268 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
271 static const char zr36050_dht[0x1a4] = {
272 0xff, 0xc4, //Marker: DHT
273 0x01, 0xa2, //Length: 2*AC, 2*DC
274 0x00, //DC first table
275 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
276 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
277 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
278 0x01, //DC second table
279 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
280 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
281 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
282 0x10, //AC first table
283 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
284 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
285 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
286 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
287 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
288 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
289 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
290 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
291 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
292 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
293 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
294 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
295 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
296 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
297 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
298 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
299 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
300 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
301 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
302 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
304 0x11, //AC second table
305 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
306 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
307 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
308 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
309 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
310 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
311 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
312 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
313 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
314 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
315 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
316 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
317 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
318 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
319 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
320 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
321 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
322 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
323 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
324 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
328 static const char zr36050_app[0x40] = {
329 0xff, 0xe0, //Marker: APP0
330 0x00, 0x3e, //Length: 60+2
331 ' ', 'A', 'V', 'I', '1', 0, 0, 0, // 'AVI' field
332 0, 0, 0, 0, 0, 0, 0, 0,
333 0, 0, 0, 0, 0, 0, 0, 0,
334 0, 0, 0, 0, 0, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0,
341 static const char zr36050_com[0x40] = {
342 0xff, 0xfe, //Marker: COM
343 0x00, 0x3e, //Length: 60+2
344 ' ', 'C', 'O', 'M', 0, 0, 0, 0, // 'COM' field
345 0, 0, 0, 0, 0, 0, 0, 0,
346 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0,
348 0, 0, 0, 0, 0, 0, 0, 0,
349 0, 0, 0, 0, 0, 0, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0,
354 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
355 #define NO_OF_COMPONENTS 0x3 //Y,U,V
356 #define BASELINE_PRECISION 0x8 //MCU size (?)
357 static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
358 static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
359 static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
361 /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
362 static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
363 static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
365 /* =========================================================================
366 Local helper functions:
368 calculation and setup of parameter-dependent JPEG baseline segments
369 (needed for compression only)
370 ========================================================================= */
372 /* ------------------------------------------------------------------------- */
374 /* SOF (start of frame) segment depends on width, height and sampling ratio
375 of each color component */
378 zr36050_set_sof (struct zr36050 *ptr)
380 char sof_data[34]; // max. size of register set
383 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
384 ptr->width, ptr->height, NO_OF_COMPONENTS);
388 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
389 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050
390 sof_data[5] = (ptr->height) >> 8;
391 sof_data[6] = (ptr->height) & 0xff;
392 sof_data[7] = (ptr->width) >> 8;
393 sof_data[8] = (ptr->width) & 0xff;
394 sof_data[9] = NO_OF_COMPONENTS;
395 for (i = 0; i < NO_OF_COMPONENTS; i++) {
396 sof_data[10 + (i * 3)] = i; // index identifier
397 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios
398 sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
400 return zr36050_pushit(ptr, ZR050_SOF_IDX,
401 (3 * NO_OF_COMPONENTS) + 10, sof_data);
404 /* ------------------------------------------------------------------------- */
406 /* SOS (start of scan) segment depends on the used scan components
407 of each color component */
410 zr36050_set_sos (struct zr36050 *ptr)
412 char sos_data[16]; // max. size of register set
415 dprintk(3, "%s: write SOS\n", ptr->name);
419 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
420 sos_data[4] = NO_OF_COMPONENTS;
421 for (i = 0; i < NO_OF_COMPONENTS; i++) {
422 sos_data[5 + (i * 2)] = i; // index
423 sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel.
425 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
426 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
427 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
428 return zr36050_pushit(ptr, ZR050_SOS1_IDX,
429 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
433 /* ------------------------------------------------------------------------- */
435 /* DRI (define restart interval) */
438 zr36050_set_dri (struct zr36050 *ptr)
440 char dri_data[6]; // max. size of register set
442 dprintk(3, "%s: write DRI\n", ptr->name);
447 dri_data[4] = ptr->dri >> 8;
448 dri_data[5] = ptr->dri * 0xff;
449 return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
452 /* =========================================================================
455 Setup compression/decompression of Zoran's JPEG processor
456 ( see also zoran 36050 manual )
458 ... sorry for the spaghetti code ...
459 ========================================================================= */
461 zr36050_init (struct zr36050 *ptr)
466 if (ptr->mode == CODEC_DO_COMPRESSION) {
467 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
469 /* 050 communicates with 057 in master mode */
470 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
472 /* encoding table preload for compression */
473 zr36050_write(ptr, ZR050_MODE,
474 ZR050_MO_COMP | ZR050_MO_TLM);
475 zr36050_write(ptr, ZR050_OPTIONS, 0);
477 /* disable all IRQs */
478 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
479 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
481 /* volume control settings */
482 /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
483 zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
484 zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
486 zr36050_write(ptr, ZR050_AF_HI, 0xff);
487 zr36050_write(ptr, ZR050_AF_M, 0xff);
488 zr36050_write(ptr, ZR050_AF_LO, 0xff);
490 /* setup the variable jpeg tables */
491 sum += zr36050_set_sof(ptr);
492 sum += zr36050_set_sos(ptr);
493 sum += zr36050_set_dri(ptr);
495 /* setup the fixed jpeg tables - maybe variable, though -
496 * (see table init section above) */
497 dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
498 sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
499 sizeof(zr36050_dqt), zr36050_dqt);
500 sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
501 sizeof(zr36050_dht), zr36050_dht);
502 sum += zr36050_pushit(ptr, ZR050_APP_IDX,
503 sizeof(zr36050_app), zr36050_app);
504 sum += zr36050_pushit(ptr, ZR050_COM_IDX,
505 sizeof(zr36050_com), zr36050_com);
507 /* do the internal huffman table preload */
508 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
510 zr36050_write(ptr, ZR050_GO, 1); // launch codec
511 zr36050_wait_end(ptr);
512 dprintk(2, "%s: Status after table preload: 0x%02x\n",
513 ptr->name, ptr->status1);
515 if ((ptr->status1 & 0x4) == 0) {
516 dprintk(1, KERN_ERR "%s: init aborted!\n",
518 return; // something is wrong, its timed out!!!!
521 /* setup misc. data for compression (target code sizes) */
523 /* size of compressed code to reach without header data */
524 sum = ptr->real_code_vol - sum;
525 bitcnt = sum << 3; /* need the size in bits */
529 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
530 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
531 zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
532 zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
533 tmp = bitcnt & 0xffff;
534 zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
535 zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
537 bitcnt -= bitcnt >> 7; // bits without stuffing
538 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
541 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
542 ptr->name, bitcnt, tmp);
543 zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
544 zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
545 tmp = bitcnt & 0xffff;
546 zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
547 zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
549 /* compression setup with or without bitrate control */
550 zr36050_write(ptr, ZR050_MODE,
551 ZR050_MO_COMP | ZR050_MO_PASS2 |
552 (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
554 /* this headers seem to deliver "valid AVI" jpeg frames */
555 zr36050_write(ptr, ZR050_MARKERS_EN,
556 ZR050_ME_APP | ZR050_ME_DQT | ZR050_ME_DHT |
559 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
561 /* 050 communicates with 055 in master mode */
562 zr36050_write(ptr, ZR050_HARDWARE,
563 ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
565 /* encoding table preload */
566 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
568 /* disable all IRQs */
569 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
570 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
572 dprintk(3, "%s: write DHT\n", ptr->name);
573 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
576 /* do the internal huffman table preload */
577 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
579 zr36050_write(ptr, ZR050_GO, 1); // launch codec
580 zr36050_wait_end(ptr);
581 dprintk(2, "%s: Status after table preload: 0x%02x\n",
582 ptr->name, ptr->status1);
584 if ((ptr->status1 & 0x4) == 0) {
585 dprintk(1, KERN_ERR "%s: init aborted!\n",
587 return; // something is wrong, its timed out!!!!
590 /* setup misc. data for expansion */
591 zr36050_write(ptr, ZR050_MODE, 0);
592 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
595 /* adr on selected, to allow GO from master */
596 zr36050_read(ptr, 0);
599 /* =========================================================================
602 this functions are accessed by the master via the API structure
603 ========================================================================= */
605 /* set compression/expansion mode and launches codec -
606 this should be the last call from the master before starting processing */
608 zr36050_set_mode (struct videocodec *codec,
611 struct zr36050 *ptr = (struct zr36050 *) codec->data;
613 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
615 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
624 /* set picture size (norm is ignored as the codec doesn't know about it) */
626 zr36050_set_video (struct videocodec *codec,
628 struct vfe_settings *cap,
629 struct vfe_polarity *pol)
631 struct zr36050 *ptr = (struct zr36050 *) codec->data;
634 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
635 ptr->name, norm->HStart, norm->VStart,
636 cap->x, cap->y, cap->width, cap->height,
637 cap->decimation, cap->quality);
638 /* if () return -EINVAL;
639 * trust the master driver that it knows what it does - so
640 * we allow invalid startx/y and norm for now ... */
641 ptr->width = cap->width / (cap->decimation & 0xff);
642 ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
644 /* (KM) JPEG quality */
645 size = ptr->width * ptr->height;
646 size *= 16; /* size in bits */
647 /* apply quality setting */
648 size = size * cap->quality / 200;
653 /* Maximum: 7/8 of code buffer */
654 if (size > ptr->total_code_vol * 7)
655 size = ptr->total_code_vol * 7;
657 ptr->real_code_vol = size >> 3; /* in bytes */
659 /* Set max_block_vol here (previously in zr36050_init, moved
660 * here for consistency with zr36060 code */
661 zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
666 /* additional control functions */
668 zr36050_control (struct videocodec *codec,
673 struct zr36050 *ptr = (struct zr36050 *) codec->data;
674 int *ival = (int *) data;
676 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
680 case CODEC_G_STATUS: /* get last status */
681 if (size != sizeof(int))
683 zr36050_read_status1(ptr);
684 *ival = ptr->status1;
687 case CODEC_G_CODEC_MODE:
688 if (size != sizeof(int))
690 *ival = CODEC_MODE_BJPG;
693 case CODEC_S_CODEC_MODE:
694 if (size != sizeof(int))
696 if (*ival != CODEC_MODE_BJPG)
698 /* not needed, do nothing */
703 /* not needed, do nothing */
707 /* not available, give an error */
710 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
711 if (size != sizeof(int))
713 *ival = ptr->total_code_vol;
716 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
717 if (size != sizeof(int))
719 ptr->total_code_vol = *ival;
720 /* (Kieran Morrissey)
721 * code copied from zr36060.c to ensure proper bitrate */
722 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
725 case CODEC_G_JPEG_SCALE: /* get scaling factor */
726 if (size != sizeof(int))
728 *ival = zr36050_read_scalefactor(ptr);
731 case CODEC_S_JPEG_SCALE: /* set scaling factor */
732 if (size != sizeof(int))
734 ptr->scalefact = *ival;
743 /* =========================================================================
744 Exit and unregister function:
746 Deinitializes Zoran's JPEG processor
747 ========================================================================= */
750 zr36050_unset (struct videocodec *codec)
752 struct zr36050 *ptr = codec->data;
755 /* do wee need some codec deinit here, too ???? */
757 dprintk(1, "%s: finished codec #%d\n", ptr->name,
769 /* =========================================================================
770 Setup and registry function:
772 Initializes Zoran's JPEG processor
774 Also sets pixel size, average code size, mode (compr./decompr.)
775 (the given size is determined by the processor with the video interface)
776 ========================================================================= */
779 zr36050_setup (struct videocodec *codec)
784 dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
787 if (zr36050_codecs == MAX_CODECS) {
789 KERN_ERR "zr36050: Can't attach more codecs!\n");
793 codec->data = ptr = kmalloc(sizeof(struct zr36050), GFP_KERNEL);
795 dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
798 memset(ptr, 0, sizeof(struct zr36050));
800 snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
802 ptr->num = zr36050_codecs++;
806 res = zr36050_basic_test(ptr);
808 zr36050_unset(codec);
812 memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
813 memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
815 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
816 * (what is the difference?) */
817 ptr->mode = CODEC_DO_COMPRESSION;
820 ptr->total_code_vol = 16000;
821 ptr->max_block_vol = 240;
822 ptr->scalefact = 0x100;
826 dprintk(1, KERN_INFO "%s: codec attached and running\n",
832 static const struct videocodec zr36050_codec = {
833 .owner = THIS_MODULE,
835 .magic = 0L, // magic not used
837 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
839 .type = CODEC_TYPE_ZR36050,
840 .setup = zr36050_setup, // functionality
841 .unset = zr36050_unset,
842 .set_mode = zr36050_set_mode,
843 .set_video = zr36050_set_video,
844 .control = zr36050_control,
845 // others are not used
848 /* =========================================================================
849 HOOK IN DRIVER AS KERNEL MODULE
850 ========================================================================= */
853 zr36050_init_module (void)
855 //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION);
857 return videocodec_register(&zr36050_codec);
861 zr36050_cleanup_module (void)
863 if (zr36050_codecs) {
865 "zr36050: something's wrong - %d codecs left somehow.\n",
868 videocodec_unregister(&zr36050_codec);
871 module_init(zr36050_init_module);
872 module_exit(zr36050_cleanup_module);
874 MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
875 MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
877 MODULE_LICENSE("GPL");