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/module.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/delay.h>
34 #include <linux/types.h>
35 #include <linux/wait.h>
37 /* includes for structures and defines regarding video
38 #include<linux/videodev.h> */
40 /* I/O commands, error codes */
44 /* headerfile of this module */
48 #include "videocodec.h"
50 /* it doesn't make sense to have more than 20 or so,
51 just to prevent some unwanted loops */
54 /* amount of chips attached via this driver */
55 static int zr36050_codecs;
57 /* debugging is available via module parameter */
59 module_param(debug, int, 0);
60 MODULE_PARM_DESC(debug, "Debug level (0-4)");
62 #define dprintk(num, format, args...) \
65 printk(format, ##args); \
68 /* =========================================================================
69 Local hardware I/O functions:
71 read/write via codec layer (registers are located in the master device)
72 ========================================================================= */
74 /* read and write functions */
76 zr36050_read (struct zr36050 *ptr,
81 // just in case something is wrong...
82 if (ptr->codec->master_data->readreg)
83 value = (ptr->codec->master_data->readreg(ptr->codec,
87 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
90 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
97 zr36050_write (struct zr36050 *ptr,
101 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
104 // just in case something is wrong...
105 if (ptr->codec->master_data->writereg)
106 ptr->codec->master_data->writereg(ptr->codec, reg, value);
110 "%s: invalid I/O setup, nothing written!\n",
114 /* =========================================================================
115 Local helper function:
118 ========================================================================= */
120 /* status is kept in datastructure */
122 zr36050_read_status1 (struct zr36050 *ptr)
124 ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
126 zr36050_read(ptr, 0);
130 /* =========================================================================
131 Local helper function:
134 ========================================================================= */
136 /* scale factor is kept in datastructure */
138 zr36050_read_scalefactor (struct zr36050 *ptr)
140 ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
141 (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
143 /* leave 0 selected for an eventually GO from master */
144 zr36050_read(ptr, 0);
145 return ptr->scalefact;
148 /* =========================================================================
149 Local helper function:
151 wait if codec is ready to proceed (end of processing) or time is over
152 ========================================================================= */
155 zr36050_wait_end (struct zr36050 *ptr)
159 while (!(zr36050_read_status1(ptr) & 0x4)) {
161 if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
163 "%s: timeout at wait_end (last status: 0x%02x)\n",
164 ptr->name, ptr->status1);
170 /* =========================================================================
171 Local helper function:
173 basic test of "connectivity", writes/reads to/from memory the SOF marker
174 ========================================================================= */
177 zr36050_basic_test (struct zr36050 *ptr)
179 zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
180 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
181 if ((zr36050_read(ptr, ZR050_SOF_IDX) |
182 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
185 "%s: attach failed, can't connect to jpeg processor!\n",
189 zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
190 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
191 if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
192 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
195 "%s: attach failed, can't connect to jpeg processor!\n",
200 zr36050_wait_end(ptr);
201 if ((ptr->status1 & 0x4) == 0) {
204 "%s: attach failed, jpeg processor failed (end flag)!\n",
209 return 0; /* looks good! */
212 /* =========================================================================
213 Local helper function:
215 simple loop for pushing the init datasets
216 ========================================================================= */
219 zr36050_pushit (struct zr36050 *ptr,
226 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
229 zr36050_write(ptr, startreg++, data[i++]);
235 /* =========================================================================
238 jpeg baseline setup data (you find it on lots places in internet, or just
239 extract it from any regular .jpg image...)
241 Could be variable, but until it's not needed it they are just fixed to save
242 memory. Otherwise expand zr36050 structure with arrays, push the values to
243 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
244 ========================================================================= */
246 static const char zr36050_dqt[0x86] = {
247 0xff, 0xdb, //Marker: DQT
248 0x00, 0x84, //Length: 2*65+2
249 0x00, //Pq,Tq first table
250 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
251 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
252 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
253 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
254 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
255 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
256 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
257 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
258 0x01, //Pq,Tq second table
259 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
260 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
261 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
262 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 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
269 static const char zr36050_dht[0x1a4] = {
270 0xff, 0xc4, //Marker: DHT
271 0x01, 0xa2, //Length: 2*AC, 2*DC
272 0x00, //DC first table
273 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
274 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
275 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
276 0x01, //DC second table
277 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
278 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
279 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
280 0x10, //AC first table
281 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
282 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
283 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
284 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
285 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
286 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
287 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
288 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
289 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
290 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
291 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
292 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
293 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
294 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
295 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
296 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
297 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
298 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
299 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
300 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
302 0x11, //AC second table
303 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
304 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
305 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
306 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
307 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
308 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
309 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
310 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
311 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
312 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
313 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
314 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
315 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
316 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
317 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
318 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
319 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
320 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
321 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
322 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
326 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
327 #define NO_OF_COMPONENTS 0x3 //Y,U,V
328 #define BASELINE_PRECISION 0x8 //MCU size (?)
329 static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
330 static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
331 static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
333 /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
334 static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
335 static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
337 /* =========================================================================
338 Local helper functions:
340 calculation and setup of parameter-dependent JPEG baseline segments
341 (needed for compression only)
342 ========================================================================= */
344 /* ------------------------------------------------------------------------- */
346 /* SOF (start of frame) segment depends on width, height and sampling ratio
347 of each color component */
350 zr36050_set_sof (struct zr36050 *ptr)
352 char sof_data[34]; // max. size of register set
355 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
356 ptr->width, ptr->height, NO_OF_COMPONENTS);
360 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
361 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050
362 sof_data[5] = (ptr->height) >> 8;
363 sof_data[6] = (ptr->height) & 0xff;
364 sof_data[7] = (ptr->width) >> 8;
365 sof_data[8] = (ptr->width) & 0xff;
366 sof_data[9] = NO_OF_COMPONENTS;
367 for (i = 0; i < NO_OF_COMPONENTS; i++) {
368 sof_data[10 + (i * 3)] = i; // index identifier
369 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios
370 sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
372 return zr36050_pushit(ptr, ZR050_SOF_IDX,
373 (3 * NO_OF_COMPONENTS) + 10, sof_data);
376 /* ------------------------------------------------------------------------- */
378 /* SOS (start of scan) segment depends on the used scan components
379 of each color component */
382 zr36050_set_sos (struct zr36050 *ptr)
384 char sos_data[16]; // max. size of register set
387 dprintk(3, "%s: write SOS\n", ptr->name);
391 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
392 sos_data[4] = NO_OF_COMPONENTS;
393 for (i = 0; i < NO_OF_COMPONENTS; i++) {
394 sos_data[5 + (i * 2)] = i; // index
395 sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel.
397 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
398 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
399 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
400 return zr36050_pushit(ptr, ZR050_SOS1_IDX,
401 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
405 /* ------------------------------------------------------------------------- */
407 /* DRI (define restart interval) */
410 zr36050_set_dri (struct zr36050 *ptr)
412 char dri_data[6]; // max. size of register set
414 dprintk(3, "%s: write DRI\n", ptr->name);
419 dri_data[4] = ptr->dri >> 8;
420 dri_data[5] = ptr->dri & 0xff;
421 return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
424 /* =========================================================================
427 Setup compression/decompression of Zoran's JPEG processor
428 ( see also zoran 36050 manual )
430 ... sorry for the spaghetti code ...
431 ========================================================================= */
433 zr36050_init (struct zr36050 *ptr)
438 if (ptr->mode == CODEC_DO_COMPRESSION) {
439 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
441 /* 050 communicates with 057 in master mode */
442 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
444 /* encoding table preload for compression */
445 zr36050_write(ptr, ZR050_MODE,
446 ZR050_MO_COMP | ZR050_MO_TLM);
447 zr36050_write(ptr, ZR050_OPTIONS, 0);
449 /* disable all IRQs */
450 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
451 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
453 /* volume control settings */
454 /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
455 zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
456 zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
458 zr36050_write(ptr, ZR050_AF_HI, 0xff);
459 zr36050_write(ptr, ZR050_AF_M, 0xff);
460 zr36050_write(ptr, ZR050_AF_LO, 0xff);
462 /* setup the variable jpeg tables */
463 sum += zr36050_set_sof(ptr);
464 sum += zr36050_set_sos(ptr);
465 sum += zr36050_set_dri(ptr);
467 /* setup the fixed jpeg tables - maybe variable, though -
468 * (see table init section above) */
469 dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
470 sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
471 sizeof(zr36050_dqt), zr36050_dqt);
472 sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
473 sizeof(zr36050_dht), zr36050_dht);
474 zr36050_write(ptr, ZR050_APP_IDX, 0xff);
475 zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
476 zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
477 zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
478 sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
480 zr36050_write(ptr, ZR050_COM_IDX, 0xff);
481 zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
482 zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
483 zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
484 sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
487 /* do the internal huffman table preload */
488 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
490 zr36050_write(ptr, ZR050_GO, 1); // launch codec
491 zr36050_wait_end(ptr);
492 dprintk(2, "%s: Status after table preload: 0x%02x\n",
493 ptr->name, ptr->status1);
495 if ((ptr->status1 & 0x4) == 0) {
496 dprintk(1, KERN_ERR "%s: init aborted!\n",
498 return; // something is wrong, its timed out!!!!
501 /* setup misc. data for compression (target code sizes) */
503 /* size of compressed code to reach without header data */
504 sum = ptr->real_code_vol - sum;
505 bitcnt = sum << 3; /* need the size in bits */
509 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
510 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
511 zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
512 zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
513 tmp = bitcnt & 0xffff;
514 zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
515 zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
517 bitcnt -= bitcnt >> 7; // bits without stuffing
518 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
521 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
522 ptr->name, bitcnt, tmp);
523 zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
524 zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
525 tmp = bitcnt & 0xffff;
526 zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
527 zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
529 /* compression setup with or without bitrate control */
530 zr36050_write(ptr, ZR050_MODE,
531 ZR050_MO_COMP | ZR050_MO_PASS2 |
532 (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
534 /* this headers seem to deliver "valid AVI" jpeg frames */
535 zr36050_write(ptr, ZR050_MARKERS_EN,
536 ZR050_ME_DQT | ZR050_ME_DHT |
537 ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
538 ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
540 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
542 /* 050 communicates with 055 in master mode */
543 zr36050_write(ptr, ZR050_HARDWARE,
544 ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
546 /* encoding table preload */
547 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
549 /* disable all IRQs */
550 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
551 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
553 dprintk(3, "%s: write DHT\n", ptr->name);
554 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
557 /* do the internal huffman table preload */
558 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
560 zr36050_write(ptr, ZR050_GO, 1); // launch codec
561 zr36050_wait_end(ptr);
562 dprintk(2, "%s: Status after table preload: 0x%02x\n",
563 ptr->name, ptr->status1);
565 if ((ptr->status1 & 0x4) == 0) {
566 dprintk(1, KERN_ERR "%s: init aborted!\n",
568 return; // something is wrong, its timed out!!!!
571 /* setup misc. data for expansion */
572 zr36050_write(ptr, ZR050_MODE, 0);
573 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
576 /* adr on selected, to allow GO from master */
577 zr36050_read(ptr, 0);
580 /* =========================================================================
583 this functions are accessed by the master via the API structure
584 ========================================================================= */
586 /* set compression/expansion mode and launches codec -
587 this should be the last call from the master before starting processing */
589 zr36050_set_mode (struct videocodec *codec,
592 struct zr36050 *ptr = (struct zr36050 *) codec->data;
594 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
596 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
605 /* set picture size (norm is ignored as the codec doesn't know about it) */
607 zr36050_set_video (struct videocodec *codec,
609 struct vfe_settings *cap,
610 struct vfe_polarity *pol)
612 struct zr36050 *ptr = (struct zr36050 *) codec->data;
615 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
616 ptr->name, norm->HStart, norm->VStart,
617 cap->x, cap->y, cap->width, cap->height,
618 cap->decimation, cap->quality);
619 /* if () return -EINVAL;
620 * trust the master driver that it knows what it does - so
621 * we allow invalid startx/y and norm for now ... */
622 ptr->width = cap->width / (cap->decimation & 0xff);
623 ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
625 /* (KM) JPEG quality */
626 size = ptr->width * ptr->height;
627 size *= 16; /* size in bits */
628 /* apply quality setting */
629 size = size * cap->quality / 200;
634 /* Maximum: 7/8 of code buffer */
635 if (size > ptr->total_code_vol * 7)
636 size = ptr->total_code_vol * 7;
638 ptr->real_code_vol = size >> 3; /* in bytes */
640 /* Set max_block_vol here (previously in zr36050_init, moved
641 * here for consistency with zr36060 code */
642 zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
647 /* additional control functions */
649 zr36050_control (struct videocodec *codec,
654 struct zr36050 *ptr = (struct zr36050 *) codec->data;
655 int *ival = (int *) data;
657 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
661 case CODEC_G_STATUS: /* get last status */
662 if (size != sizeof(int))
664 zr36050_read_status1(ptr);
665 *ival = ptr->status1;
668 case CODEC_G_CODEC_MODE:
669 if (size != sizeof(int))
671 *ival = CODEC_MODE_BJPG;
674 case CODEC_S_CODEC_MODE:
675 if (size != sizeof(int))
677 if (*ival != CODEC_MODE_BJPG)
679 /* not needed, do nothing */
684 /* not needed, do nothing */
688 /* not available, give an error */
691 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
692 if (size != sizeof(int))
694 *ival = ptr->total_code_vol;
697 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
698 if (size != sizeof(int))
700 ptr->total_code_vol = *ival;
701 /* (Kieran Morrissey)
702 * code copied from zr36060.c to ensure proper bitrate */
703 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
706 case CODEC_G_JPEG_SCALE: /* get scaling factor */
707 if (size != sizeof(int))
709 *ival = zr36050_read_scalefactor(ptr);
712 case CODEC_S_JPEG_SCALE: /* set scaling factor */
713 if (size != sizeof(int))
715 ptr->scalefact = *ival;
718 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
719 struct jpeg_app_marker *app = data;
721 if (size != sizeof(struct jpeg_app_marker))
728 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
729 struct jpeg_app_marker *app = data;
731 if (size != sizeof(struct jpeg_app_marker))
738 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
739 struct jpeg_com_marker *com = data;
741 if (size != sizeof(struct jpeg_com_marker))
748 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
749 struct jpeg_com_marker *com = data;
751 if (size != sizeof(struct jpeg_com_marker))
765 /* =========================================================================
766 Exit and unregister function:
768 Deinitializes Zoran's JPEG processor
769 ========================================================================= */
772 zr36050_unset (struct videocodec *codec)
774 struct zr36050 *ptr = codec->data;
777 /* do wee need some codec deinit here, too ???? */
779 dprintk(1, "%s: finished codec #%d\n", ptr->name,
791 /* =========================================================================
792 Setup and registry function:
794 Initializes Zoran's JPEG processor
796 Also sets pixel size, average code size, mode (compr./decompr.)
797 (the given size is determined by the processor with the video interface)
798 ========================================================================= */
801 zr36050_setup (struct videocodec *codec)
806 dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
809 if (zr36050_codecs == MAX_CODECS) {
811 KERN_ERR "zr36050: Can't attach more codecs!\n");
815 codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL);
817 dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
821 snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
823 ptr->num = zr36050_codecs++;
827 res = zr36050_basic_test(ptr);
829 zr36050_unset(codec);
833 memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
834 memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
836 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
837 * (what is the difference?) */
838 ptr->mode = CODEC_DO_COMPRESSION;
841 ptr->total_code_vol = 16000;
842 ptr->max_block_vol = 240;
843 ptr->scalefact = 0x100;
846 /* no app/com marker by default */
853 dprintk(1, KERN_INFO "%s: codec attached and running\n",
859 static const struct videocodec zr36050_codec = {
860 .owner = THIS_MODULE,
862 .magic = 0L, // magic not used
864 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
866 .type = CODEC_TYPE_ZR36050,
867 .setup = zr36050_setup, // functionality
868 .unset = zr36050_unset,
869 .set_mode = zr36050_set_mode,
870 .set_video = zr36050_set_video,
871 .control = zr36050_control,
872 // others are not used
875 /* =========================================================================
876 HOOK IN DRIVER AS KERNEL MODULE
877 ========================================================================= */
880 zr36050_init_module (void)
882 //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION);
884 return videocodec_register(&zr36050_codec);
888 zr36050_cleanup_module (void)
890 if (zr36050_codecs) {
892 "zr36050: something's wrong - %d codecs left somehow.\n",
895 videocodec_unregister(&zr36050_codec);
898 module_init(zr36050_init_module);
899 module_exit(zr36050_cleanup_module);
901 MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
902 MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
904 MODULE_LICENSE("GPL");