initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / media / video / zr36060.c
blob2d582a38dada297caf1e2129a23fed6a683def25
1 /*
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 * 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 ZR060_VERSION "v0.7"
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 */
42 #include<asm/io.h>
43 //#include<errno.h>
45 /* headerfile of this module */
46 #include"zr36060.h"
48 /* codec io API */
49 #include"videocodec.h"
51 /* it doesn't make sense to have more than 20 or so,
52 just to prevent some unwanted loops */
53 #define MAX_CODECS 20
55 /* amount of chips attached via this driver */
56 static int zr36060_codecs = 0;
58 static int low_bitrate = 0;
59 MODULE_PARM(low_bitrate, "i");
60 MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
62 /* debugging is available via module parameter */
63 static int debug = 0;
64 MODULE_PARM(debug, "i");
65 MODULE_PARM_DESC(debug, "Debug level (0-4)");
67 #define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
73 /* =========================================================================
74 Local hardware I/O functions:
76 read/write via codec layer (registers are located in the master device)
77 ========================================================================= */
79 /* read and write functions */
80 static u8
81 zr36060_read (struct zr36060 *ptr,
82 u16 reg)
84 u8 value = 0;
86 // just in case something is wrong...
87 if (ptr->codec->master_data->readreg)
88 value = (ptr->codec->master_data->readreg(ptr->codec,
89 reg)) & 0xff;
90 else
91 dprintk(1,
92 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
93 ptr->name);
95 //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
97 return value;
100 static void
101 zr36060_write(struct zr36060 *ptr,
102 u16 reg,
103 u8 value)
105 //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg);
106 dprintk(4, "0x%02x @0x%04x\n", value, reg);
108 // just in case something is wrong...
109 if (ptr->codec->master_data->writereg)
110 ptr->codec->master_data->writereg(ptr->codec, reg, value);
111 else
112 dprintk(1,
113 KERN_ERR
114 "%s: invalid I/O setup, nothing written!\n",
115 ptr->name);
118 /* =========================================================================
119 Local helper function:
121 status read
122 ========================================================================= */
124 /* status is kept in datastructure */
125 static u8
126 zr36060_read_status (struct zr36060 *ptr)
128 ptr->status = zr36060_read(ptr, ZR060_CFSR);
130 zr36060_read(ptr, 0);
131 return ptr->status;
134 /* =========================================================================
135 Local helper function:
137 scale factor read
138 ========================================================================= */
140 /* scale factor is kept in datastructure */
141 static u16
142 zr36060_read_scalefactor (struct zr36060 *ptr)
144 ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
145 (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
147 /* leave 0 selected for an eventually GO from master */
148 zr36060_read(ptr, 0);
149 return ptr->scalefact;
152 /* =========================================================================
153 Local helper function:
155 wait if codec is ready to proceed (end of processing) or time is over
156 ========================================================================= */
158 static void
159 zr36060_wait_end (struct zr36060 *ptr)
161 int i = 0;
163 while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) {
164 udelay(1);
165 if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
166 dprintk(1,
167 "%s: timout at wait_end (last status: 0x%02x)\n",
168 ptr->name, ptr->status);
169 break;
174 /* =========================================================================
175 Local helper function:
177 basic test of "connectivity", writes/reads to/from memory the SOF marker
178 ========================================================================= */
180 static int
181 zr36060_basic_test (struct zr36060 *ptr)
183 if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
184 (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
185 dprintk(1,
186 KERN_ERR
187 "%s: attach failed, can't connect to jpeg processor!\n",
188 ptr->name);
189 return -ENXIO;
192 zr36060_wait_end(ptr);
193 if (ptr->status & ZR060_CFSR_Busy) {
194 dprintk(1,
195 KERN_ERR
196 "%s: attach failed, jpeg processor failed (end flag)!\n",
197 ptr->name);
198 return -EBUSY;
201 return 0; /* looks good! */
204 /* =========================================================================
205 Local helper function:
207 simple loop for pushing the init datasets
208 ========================================================================= */
210 static int
211 zr36060_pushit (struct zr36060 *ptr,
212 u16 startreg,
213 u16 len,
214 const char *data)
216 int i = 0;
218 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
219 startreg, len);
220 while (i < len) {
221 zr36060_write(ptr, startreg++, data[i++]);
224 return i;
227 /* =========================================================================
228 Basic datasets:
230 jpeg baseline setup data (you find it on lots places in internet, or just
231 extract it from any regular .jpg image...)
233 Could be variable, but until it's not needed it they are just fixed to save
234 memory. Otherwise expand zr36060 structure with arrays, push the values to
235 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
236 ========================================================================= */
238 static const char zr36060_dqt[0x86] = {
239 0xff, 0xdb, //Marker: DQT
240 0x00, 0x84, //Length: 2*65+2
241 0x00, //Pq,Tq first table
242 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
243 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
244 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
245 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
246 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
247 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
248 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
249 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
250 0x01, //Pq,Tq second table
251 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
252 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
253 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
254 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
255 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
256 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
257 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
258 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
261 static const char zr36060_dht[0x1a4] = {
262 0xff, 0xc4, //Marker: DHT
263 0x01, 0xa2, //Length: 2*AC, 2*DC
264 0x00, //DC first table
265 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
266 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
267 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
268 0x01, //DC second table
269 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
270 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
271 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
272 0x10, //AC first table
273 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
274 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
275 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
276 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
277 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
278 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
279 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
280 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
281 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
282 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
283 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
284 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
285 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
286 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
287 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
288 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
289 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
290 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
291 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
292 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
293 0xF8, 0xF9, 0xFA,
294 0x11, //AC second table
295 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
296 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
297 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
298 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
299 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
300 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
301 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
302 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
303 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
304 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
305 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
306 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
307 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
308 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
309 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
310 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
311 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
312 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
313 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
314 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
315 0xF9, 0xFA
318 static const char zr36060_app[0x40] = {
319 0xff, 0xe0, //Marker: APP0
320 0x00, 0x07, //Length: 7
321 ' ', 'A', 'V', 'I', '1', 0, 0, 0, // 'AVI' field
322 0, 0, 0, 0, 0, 0, 0, 0,
323 0, 0, 0, 0, 0, 0, 0, 0,
324 0, 0, 0, 0, 0, 0, 0, 0,
325 0, 0, 0, 0, 0, 0, 0, 0,
326 0, 0, 0, 0, 0, 0, 0, 0,
327 0, 0, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0
331 static const char zr36060_com[0x40] = {
332 0xff, 0xfe, //Marker: COM
333 0x00, 0x06, //Length: 6
334 ' ', 'C', 'O', 'M', 0, 0, 0, 0, // 'COM' field
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,
338 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 0,
341 0, 0, 0, 0
344 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
345 #define NO_OF_COMPONENTS 0x3 //Y,U,V
346 #define BASELINE_PRECISION 0x8 //MCU size (?)
347 static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
348 static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
349 static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
351 /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
352 static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
353 static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
355 /* =========================================================================
356 Local helper functions:
358 calculation and setup of parameter-dependent JPEG baseline segments
359 (needed for compression only)
360 ========================================================================= */
362 /* ------------------------------------------------------------------------- */
364 /* SOF (start of frame) segment depends on width, height and sampling ratio
365 of each color component */
367 static int
368 zr36060_set_sof (struct zr36060 *ptr)
370 char sof_data[34]; // max. size of register set
371 int i;
373 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
374 ptr->width, ptr->height, NO_OF_COMPONENTS);
375 sof_data[0] = 0xff;
376 sof_data[1] = 0xc0;
377 sof_data[2] = 0x00;
378 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
379 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060
380 sof_data[5] = (ptr->height) >> 8;
381 sof_data[6] = (ptr->height) & 0xff;
382 sof_data[7] = (ptr->width) >> 8;
383 sof_data[8] = (ptr->width) & 0xff;
384 sof_data[9] = NO_OF_COMPONENTS;
385 for (i = 0; i < NO_OF_COMPONENTS; i++) {
386 sof_data[10 + (i * 3)] = i; // index identifier
387 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
388 (ptr->v_samp_ratio[i]); // sampling ratios
389 sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
391 return zr36060_pushit(ptr, ZR060_SOF_IDX,
392 (3 * NO_OF_COMPONENTS) + 10, sof_data);
395 /* ------------------------------------------------------------------------- */
397 /* SOS (start of scan) segment depends on the used scan components
398 of each color component */
400 static int
401 zr36060_set_sos (struct zr36060 *ptr)
403 char sos_data[16]; // max. size of register set
404 int i;
406 dprintk(3, "%s: write SOS\n", ptr->name);
407 sos_data[0] = 0xff;
408 sos_data[1] = 0xda;
409 sos_data[2] = 0x00;
410 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
411 sos_data[4] = NO_OF_COMPONENTS;
412 for (i = 0; i < NO_OF_COMPONENTS; i++) {
413 sos_data[5 + (i * 2)] = i; // index
414 sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
415 zr36060_ta[i]; // AC/DC tbl.sel.
417 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
418 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
419 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
420 return zr36060_pushit(ptr, ZR060_SOS_IDX,
421 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
422 sos_data);
425 /* ------------------------------------------------------------------------- */
427 /* DRI (define restart interval) */
429 static int
430 zr36060_set_dri (struct zr36060 *ptr)
432 char dri_data[6]; // max. size of register set
434 dprintk(3, "%s: write DRI\n", ptr->name);
435 dri_data[0] = 0xff;
436 dri_data[1] = 0xdd;
437 dri_data[2] = 0x00;
438 dri_data[3] = 0x04;
439 dri_data[4] = (ptr->dri) >> 8;
440 dri_data[5] = (ptr->dri) & 0xff;
441 return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
444 /* =========================================================================
445 Setup function:
447 Setup compression/decompression of Zoran's JPEG processor
448 ( see also zoran 36060 manual )
450 ... sorry for the spaghetti code ...
451 ========================================================================= */
452 static void
453 zr36060_init (struct zr36060 *ptr)
455 int sum = 0;
456 long bitcnt, tmp;
458 if (ptr->mode == CODEC_DO_COMPRESSION) {
459 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
461 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
463 /* 060 communicates with 067 in master mode */
464 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
466 /* Compression with or without variable scale factor */
467 /*FIXME: What about ptr->bitrate_ctrl? */
468 zr36060_write(ptr, ZR060_CMR,
469 ZR060_CMR_Comp | ZR060_CMR_Pass2 |
470 ZR060_CMR_BRB);
472 /* Must be zero */
473 zr36060_write(ptr, ZR060_MBZ, 0x00);
474 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
475 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
477 /* Disable all IRQs - no DataErr means autoreset */
478 zr36060_write(ptr, ZR060_IMR, 0);
480 /* volume control settings */
481 zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
482 zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
484 zr36060_write(ptr, ZR060_AF_HI, 0xff);
485 zr36060_write(ptr, ZR060_AF_M, 0xff);
486 zr36060_write(ptr, ZR060_AF_LO, 0xff);
488 /* setup the variable jpeg tables */
489 sum += zr36060_set_sof(ptr);
490 sum += zr36060_set_sos(ptr);
491 sum += zr36060_set_dri(ptr);
493 /* setup the fixed jpeg tables - maybe variable, though -
494 * (see table init section above) */
495 sum +=
496 zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt),
497 zr36060_dqt);
498 sum +=
499 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
500 zr36060_dht);
501 sum +=
502 zr36060_pushit(ptr, ZR060_APP_IDX, sizeof(zr36060_app),
503 zr36060_app);
504 sum +=
505 zr36060_pushit(ptr, ZR060_COM_IDX, sizeof(zr36060_com),
506 zr36060_com);
508 /* setup misc. data for compression (target code sizes) */
510 /* size of compressed code to reach without header data */
511 sum = ptr->real_code_vol - sum;
512 bitcnt = sum << 3; /* need the size in bits */
514 tmp = bitcnt >> 16;
515 dprintk(3,
516 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
517 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
518 zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
519 zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
520 tmp = bitcnt & 0xffff;
521 zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
522 zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
524 bitcnt -= bitcnt >> 7; // bits without stuffing
525 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
527 tmp = bitcnt >> 16;
528 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
529 ptr->name, bitcnt, tmp);
530 zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
531 zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
532 tmp = bitcnt & 0xffff;
533 zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
534 zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
536 /* JPEG markers to be included in the compressed stream */
537 zr36060_write(ptr, ZR060_MER,
538 ZR060_MER_App | ZR060_MER_Com | ZR060_MER_DQT
539 | ZR060_MER_DHT);
541 /* Setup the Video Frontend */
542 /* Limit pixel range to 16..235 as per CCIR-601 */
543 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
545 } else {
546 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
548 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
550 /* 060 communicates with 067 in master mode */
551 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
553 /* Decompression */
554 zr36060_write(ptr, ZR060_CMR, 0);
556 /* Must be zero */
557 zr36060_write(ptr, ZR060_MBZ, 0x00);
558 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
559 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
561 /* Disable all IRQs - no DataErr means autoreset */
562 zr36060_write(ptr, ZR060_IMR, 0);
564 /* setup misc. data for expansion */
565 zr36060_write(ptr, ZR060_MER, 0);
567 /* setup the fixed jpeg tables - maybe variable, though -
568 * (see table init section above) */
569 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
570 zr36060_dht);
572 /* Setup the Video Frontend */
573 //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt);
574 //this doesn't seem right and doesn't work...
575 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
578 /* Load the tables */
579 zr36060_write(ptr, ZR060_LOAD,
580 ZR060_LOAD_SyncRst | ZR060_LOAD_Load);
581 zr36060_wait_end(ptr);
582 dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name,
583 ptr->status);
585 if (ptr->status & ZR060_CFSR_Busy) {
586 dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name);
587 return; // something is wrong, its timed out!!!!
591 /* =========================================================================
592 CODEC API FUNCTIONS
594 this functions are accessed by the master via the API structure
595 ========================================================================= */
597 /* set compression/expansion mode and launches codec -
598 this should be the last call from the master before starting processing */
599 static int
600 zr36060_set_mode (struct videocodec *codec,
601 int mode)
603 struct zr36060 *ptr = (struct zr36060 *) codec->data;
605 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
607 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
608 return -EINVAL;
610 ptr->mode = mode;
611 zr36060_init(ptr);
613 return 0;
616 /* set picture size (norm is ignored as the codec doesn't know about it) */
617 static int
618 zr36060_set_video (struct videocodec *codec,
619 struct tvnorm *norm,
620 struct vfe_settings *cap,
621 struct vfe_polarity *pol)
623 struct zr36060 *ptr = (struct zr36060 *) codec->data;
624 u32 reg;
625 int size;
627 dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
628 cap->x, cap->y, cap->width, cap->height, cap->decimation);
630 /* if () return -EINVAL;
631 * trust the master driver that it knows what it does - so
632 * we allow invalid startx/y and norm for now ... */
633 ptr->width = cap->width / (cap->decimation & 0xff);
634 ptr->height = cap->height / (cap->decimation >> 8);
636 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
638 /* Note that VSPol/HSPol bits in zr36060 have the opposite
639 * meaning of their zr360x7 counterparts with the same names
640 * N.b. for VSPol this is only true if FIVEdge = 0 (default,
641 * left unchanged here - in accordance with datasheet).
643 reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0)
644 | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0)
645 | (pol->field_pol ? ZR060_VPR_FIPol : 0)
646 | (pol->blank_pol ? ZR060_VPR_BLPol : 0)
647 | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0)
648 | (pol->poe_pol ? ZR060_VPR_PoePol : 0)
649 | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0)
650 | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0);
651 zr36060_write(ptr, ZR060_VPR, reg);
653 reg = 0;
654 switch (cap->decimation & 0xff) {
655 default:
656 case 1:
657 break;
659 case 2:
660 reg |= ZR060_SR_HScale2;
661 break;
663 case 4:
664 reg |= ZR060_SR_HScale4;
665 break;
668 switch (cap->decimation >> 8) {
669 default:
670 case 1:
671 break;
673 case 2:
674 reg |= ZR060_SR_VScale;
675 break;
677 zr36060_write(ptr, ZR060_SR, reg);
679 zr36060_write(ptr, ZR060_BCR_Y, 0x00);
680 zr36060_write(ptr, ZR060_BCR_U, 0x80);
681 zr36060_write(ptr, ZR060_BCR_V, 0x80);
683 /* sync generator */
685 reg = norm->Ht - 1; /* Vtotal */
686 zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
687 zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
689 reg = norm->Wt - 1; /* Htotal */
690 zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
691 zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
693 reg = 6 - 1; /* VsyncSize */
694 zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
696 //reg = 30 - 1; /* HsyncSize */
697 ///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
698 reg = 68;
699 zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
701 reg = norm->VStart - 1; /* BVstart */
702 zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
704 reg += norm->Ha / 2; /* BVend */
705 zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
706 zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
708 reg = norm->HStart - 1; /* BHstart */
709 zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
711 reg += norm->Wa; /* BHend */
712 zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
713 zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
715 /* active area */
716 reg = cap->y + norm->VStart; /* Vstart */
717 zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
718 zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
720 reg += cap->height; /* Vend */
721 zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
722 zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
724 reg = cap->x + norm->HStart; /* Hstart */
725 zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
726 zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
728 reg += cap->width; /* Hend */
729 zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
730 zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
732 /* subimage area */
733 reg = norm->VStart - 4; /* SVstart */
734 zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
735 zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
737 reg += norm->Ha / 2 + 8; /* SVend */
738 zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
739 zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
741 reg = norm->HStart /*+ 64 */ - 4; /* SHstart */
742 zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
743 zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
745 reg += norm->Wa + 8; /* SHend */
746 zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
747 zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
749 size = ptr->width * ptr->height;
750 /* Target compressed field size in bits: */
751 size = size * 16; /* uncompressed size in bits */
752 /* (Ronald) by default, quality = 100 is a compression
753 * ratio 1:2. Setting low_bitrate (insmod option) sets
754 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
755 * buz can't handle more at decimation=1... Use low_bitrate if
756 * you have a Buz, unless you know what you're doing */
757 size = size * cap->quality / (low_bitrate ? 400 : 200);
758 /* Lower limit (arbitrary, 1 KB) */
759 if (size < 8192)
760 size = 8192;
761 /* Upper limit: 7/8 of the code buffers */
762 if (size > ptr->total_code_vol * 7)
763 size = ptr->total_code_vol * 7;
765 ptr->real_code_vol = size >> 3; /* in bytes */
767 /* the MBCVR is the *maximum* block volume, according to the
768 * JPEG ISO specs, this shouldn't be used, since that allows
769 * for the best encoding quality. So set it to it's max value */
770 reg = ptr->max_block_vol;
771 zr36060_write(ptr, ZR060_MBCVR, reg);
773 return 0;
776 /* additional control functions */
777 static int
778 zr36060_control (struct videocodec *codec,
779 int type,
780 int size,
781 void *data)
783 struct zr36060 *ptr = (struct zr36060 *) codec->data;
784 int *ival = (int *) data;
786 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
787 size);
789 switch (type) {
790 case CODEC_G_STATUS: /* get last status */
791 if (size != sizeof(int))
792 return -EFAULT;
793 zr36060_read_status(ptr);
794 *ival = ptr->status;
795 break;
797 case CODEC_G_CODEC_MODE:
798 if (size != sizeof(int))
799 return -EFAULT;
800 *ival = CODEC_MODE_BJPG;
801 break;
803 case CODEC_S_CODEC_MODE:
804 if (size != sizeof(int))
805 return -EFAULT;
806 if (*ival != CODEC_MODE_BJPG)
807 return -EINVAL;
808 /* not needed, do nothing */
809 return 0;
811 case CODEC_G_VFE:
812 case CODEC_S_VFE:
813 /* not needed, do nothing */
814 return 0;
816 case CODEC_S_MMAP:
817 /* not available, give an error */
818 return -ENXIO;
820 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
821 if (size != sizeof(int))
822 return -EFAULT;
823 *ival = ptr->total_code_vol;
824 break;
826 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
827 if (size != sizeof(int))
828 return -EFAULT;
829 ptr->total_code_vol = *ival;
830 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
831 break;
833 case CODEC_G_JPEG_SCALE: /* get scaling factor */
834 if (size != sizeof(int))
835 return -EFAULT;
836 *ival = zr36060_read_scalefactor(ptr);
837 break;
839 case CODEC_S_JPEG_SCALE: /* set scaling factor */
840 if (size != sizeof(int))
841 return -EFAULT;
842 ptr->scalefact = *ival;
843 break;
844 default:
845 return -EINVAL;
848 return size;
851 /* =========================================================================
852 Exit and unregister function:
854 Deinitializes Zoran's JPEG processor
855 ========================================================================= */
857 static int
858 zr36060_unset (struct videocodec *codec)
860 struct zr36060 *ptr = codec->data;
862 if (ptr) {
863 /* do wee need some codec deinit here, too ???? */
865 dprintk(1, "%s: finished codec #%d\n", ptr->name,
866 ptr->num);
867 kfree(ptr);
868 codec->data = NULL;
870 zr36060_codecs--;
871 return 0;
874 return -EFAULT;
877 /* =========================================================================
878 Setup and registry function:
880 Initializes Zoran's JPEG processor
882 Also sets pixel size, average code size, mode (compr./decompr.)
883 (the given size is determined by the processor with the video interface)
884 ========================================================================= */
886 static int
887 zr36060_setup (struct videocodec *codec)
889 struct zr36060 *ptr;
890 int res;
892 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
893 zr36060_codecs);
895 if (zr36060_codecs == MAX_CODECS) {
896 dprintk(1,
897 KERN_ERR "zr36060: Can't attach more codecs!\n");
898 return -ENOSPC;
900 //mem structure init
901 codec->data = ptr = kmalloc(sizeof(struct zr36060), GFP_KERNEL);
902 if (NULL == ptr) {
903 dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n");
904 return -ENOMEM;
906 memset(ptr, 0, sizeof(struct zr36060));
908 snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]",
909 zr36060_codecs);
910 ptr->num = zr36060_codecs++;
911 ptr->codec = codec;
913 //testing
914 res = zr36060_basic_test(ptr);
915 if (res < 0) {
916 zr36060_unset(codec);
917 return res;
919 //final setup
920 memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
921 memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
923 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
924 * (what is the difference?) */
925 ptr->mode = CODEC_DO_COMPRESSION;
926 ptr->width = 384;
927 ptr->height = 288;
928 ptr->total_code_vol = 16000; /* CHECKME */
929 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
930 ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */
931 ptr->scalefact = 0x100;
932 ptr->dri = 1; /* CHECKME, was 8 is 1 */
933 zr36060_init(ptr);
935 dprintk(1, KERN_INFO "%s: codec attached and running\n",
936 ptr->name);
938 return 0;
941 static const struct videocodec zr36060_codec = {
942 .owner = THIS_MODULE,
943 .name = "zr36060",
944 .magic = 0L, // magic not used
945 .flags =
946 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
947 CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
948 .type = CODEC_TYPE_ZR36060,
949 .setup = zr36060_setup, // functionality
950 .unset = zr36060_unset,
951 .set_mode = zr36060_set_mode,
952 .set_video = zr36060_set_video,
953 .control = zr36060_control,
954 // others are not used
957 /* =========================================================================
958 HOOK IN DRIVER AS KERNEL MODULE
959 ========================================================================= */
961 static int __init
962 zr36060_init_module (void)
964 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
965 zr36060_codecs = 0;
966 return videocodec_register(&zr36060_codec);
969 static void __exit
970 zr36060_cleanup_module (void)
972 if (zr36060_codecs) {
973 dprintk(1,
974 "zr36060: something's wrong - %d codecs left somehow.\n",
975 zr36060_codecs);
978 /* however, we can't just stay alive */
979 videocodec_unregister(&zr36060_codec);
982 module_init(zr36060_init_module);
983 module_exit(zr36060_cleanup_module);
985 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
986 MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
987 ZR060_VERSION);
988 MODULE_LICENSE("GPL");