aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/zr36060.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media/video/zr36060.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/media/video/zr36060.c')
-rw-r--r--drivers/media/video/zr36060.c1016
1 files changed, 1016 insertions, 0 deletions
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
new file mode 100644
index 000000000000..b50dc403e6db
--- /dev/null
+++ b/drivers/media/video/zr36060.c
@@ -0,0 +1,1016 @@
1/*
2 * Zoran ZR36060 basic configuration functions
3 *
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
5 *
6 * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
9 *
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.
14 *
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.
19 *
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.
23 *
24 * ------------------------------------------------------------------------
25 */
26
27#define ZR060_VERSION "v0.7"
28
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>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* headerfile of this module */
46#include"zr36060.h"
47
48/* codec io API */
49#include"videocodec.h"
50
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
54
55/* amount of chips attached via this driver */
56static int zr36060_codecs = 0;
57
58static int low_bitrate = 0;
59module_param(low_bitrate, bool, 0);
60MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
61
62/* debugging is available via module parameter */
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-4)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* =========================================================================
74 Local hardware I/O functions:
75
76 read/write via codec layer (registers are located in the master device)
77 ========================================================================= */
78
79/* read and write functions */
80static u8
81zr36060_read (struct zr36060 *ptr,
82 u16 reg)
83{
84 u8 value = 0;
85
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);
94
95 //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
96
97 return value;
98}
99
100static void
101zr36060_write(struct zr36060 *ptr,
102 u16 reg,
103 u8 value)
104{
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);
107
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);
116}
117
118/* =========================================================================
119 Local helper function:
120
121 status read
122 ========================================================================= */
123
124/* status is kept in datastructure */
125static u8
126zr36060_read_status (struct zr36060 *ptr)
127{
128 ptr->status = zr36060_read(ptr, ZR060_CFSR);
129
130 zr36060_read(ptr, 0);
131 return ptr->status;
132}
133
134/* =========================================================================
135 Local helper function:
136
137 scale factor read
138 ========================================================================= */
139
140/* scale factor is kept in datastructure */
141static u16
142zr36060_read_scalefactor (struct zr36060 *ptr)
143{
144 ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
145 (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
146
147 /* leave 0 selected for an eventually GO from master */
148 zr36060_read(ptr, 0);
149 return ptr->scalefact;
150}
151
152/* =========================================================================
153 Local helper function:
154
155 wait if codec is ready to proceed (end of processing) or time is over
156 ========================================================================= */
157
158static void
159zr36060_wait_end (struct zr36060 *ptr)
160{
161 int i = 0;
162
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;
170 }
171 }
172}
173
174/* =========================================================================
175 Local helper function:
176
177 basic test of "connectivity", writes/reads to/from memory the SOF marker
178 ========================================================================= */
179
180static int
181zr36060_basic_test (struct zr36060 *ptr)
182{
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;
190 }
191
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;
199 }
200
201 return 0; /* looks good! */
202}
203
204/* =========================================================================
205 Local helper function:
206
207 simple loop for pushing the init datasets
208 ========================================================================= */
209
210static int
211zr36060_pushit (struct zr36060 *ptr,
212 u16 startreg,
213 u16 len,
214 const char *data)
215{
216 int i = 0;
217
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++]);
222 }
223
224 return i;
225}
226
227/* =========================================================================
228 Basic datasets:
229
230 jpeg baseline setup data (you find it on lots places in internet, or just
231 extract it from any regular .jpg image...)
232
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 ========================================================================= */
237
238static 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
259};
260
261static 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
316};
317
318/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
319#define NO_OF_COMPONENTS 0x3 //Y,U,V
320#define BASELINE_PRECISION 0x8 //MCU size (?)
321static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
322static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
323static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
324
325/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
326static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
327static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
328
329/* =========================================================================
330 Local helper functions:
331
332 calculation and setup of parameter-dependent JPEG baseline segments
333 (needed for compression only)
334 ========================================================================= */
335
336/* ------------------------------------------------------------------------- */
337
338/* SOF (start of frame) segment depends on width, height and sampling ratio
339 of each color component */
340
341static int
342zr36060_set_sof (struct zr36060 *ptr)
343{
344 char sof_data[34]; // max. size of register set
345 int i;
346
347 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
348 ptr->width, ptr->height, NO_OF_COMPONENTS);
349 sof_data[0] = 0xff;
350 sof_data[1] = 0xc0;
351 sof_data[2] = 0x00;
352 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
353 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060
354 sof_data[5] = (ptr->height) >> 8;
355 sof_data[6] = (ptr->height) & 0xff;
356 sof_data[7] = (ptr->width) >> 8;
357 sof_data[8] = (ptr->width) & 0xff;
358 sof_data[9] = NO_OF_COMPONENTS;
359 for (i = 0; i < NO_OF_COMPONENTS; i++) {
360 sof_data[10 + (i * 3)] = i; // index identifier
361 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
362 (ptr->v_samp_ratio[i]); // sampling ratios
363 sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
364 }
365 return zr36060_pushit(ptr, ZR060_SOF_IDX,
366 (3 * NO_OF_COMPONENTS) + 10, sof_data);
367}
368
369/* ------------------------------------------------------------------------- */
370
371/* SOS (start of scan) segment depends on the used scan components
372 of each color component */
373
374static int
375zr36060_set_sos (struct zr36060 *ptr)
376{
377 char sos_data[16]; // max. size of register set
378 int i;
379
380 dprintk(3, "%s: write SOS\n", ptr->name);
381 sos_data[0] = 0xff;
382 sos_data[1] = 0xda;
383 sos_data[2] = 0x00;
384 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
385 sos_data[4] = NO_OF_COMPONENTS;
386 for (i = 0; i < NO_OF_COMPONENTS; i++) {
387 sos_data[5 + (i * 2)] = i; // index
388 sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
389 zr36060_ta[i]; // AC/DC tbl.sel.
390 }
391 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
392 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
393 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
394 return zr36060_pushit(ptr, ZR060_SOS_IDX,
395 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
396 sos_data);
397}
398
399/* ------------------------------------------------------------------------- */
400
401/* DRI (define restart interval) */
402
403static int
404zr36060_set_dri (struct zr36060 *ptr)
405{
406 char dri_data[6]; // max. size of register set
407
408 dprintk(3, "%s: write DRI\n", ptr->name);
409 dri_data[0] = 0xff;
410 dri_data[1] = 0xdd;
411 dri_data[2] = 0x00;
412 dri_data[3] = 0x04;
413 dri_data[4] = (ptr->dri) >> 8;
414 dri_data[5] = (ptr->dri) & 0xff;
415 return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
416}
417
418/* =========================================================================
419 Setup function:
420
421 Setup compression/decompression of Zoran's JPEG processor
422 ( see also zoran 36060 manual )
423
424 ... sorry for the spaghetti code ...
425 ========================================================================= */
426static void
427zr36060_init (struct zr36060 *ptr)
428{
429 int sum = 0;
430 long bitcnt, tmp;
431
432 if (ptr->mode == CODEC_DO_COMPRESSION) {
433 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
434
435 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
436
437 /* 060 communicates with 067 in master mode */
438 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
439
440 /* Compression with or without variable scale factor */
441 /*FIXME: What about ptr->bitrate_ctrl? */
442 zr36060_write(ptr, ZR060_CMR,
443 ZR060_CMR_Comp | ZR060_CMR_Pass2 |
444 ZR060_CMR_BRB);
445
446 /* Must be zero */
447 zr36060_write(ptr, ZR060_MBZ, 0x00);
448 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
449 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
450
451 /* Disable all IRQs - no DataErr means autoreset */
452 zr36060_write(ptr, ZR060_IMR, 0);
453
454 /* volume control settings */
455 zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
456 zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
457
458 zr36060_write(ptr, ZR060_AF_HI, 0xff);
459 zr36060_write(ptr, ZR060_AF_M, 0xff);
460 zr36060_write(ptr, ZR060_AF_LO, 0xff);
461
462 /* setup the variable jpeg tables */
463 sum += zr36060_set_sof(ptr);
464 sum += zr36060_set_sos(ptr);
465 sum += zr36060_set_dri(ptr);
466
467 /* setup the fixed jpeg tables - maybe variable, though -
468 * (see table init section above) */
469 sum +=
470 zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt),
471 zr36060_dqt);
472 sum +=
473 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
474 zr36060_dht);
475 zr36060_write(ptr, ZR060_APP_IDX, 0xff);
476 zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
477 zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
478 zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
479 sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60,
480 ptr->app.data) + 4;
481 zr36060_write(ptr, ZR060_COM_IDX, 0xff);
482 zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
483 zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
484 zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
485 sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60,
486 ptr->com.data) + 4;
487
488 /* setup misc. data for compression (target code sizes) */
489
490 /* size of compressed code to reach without header data */
491 sum = ptr->real_code_vol - sum;
492 bitcnt = sum << 3; /* need the size in bits */
493
494 tmp = bitcnt >> 16;
495 dprintk(3,
496 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
497 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
498 zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
499 zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
500 tmp = bitcnt & 0xffff;
501 zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
502 zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
503
504 bitcnt -= bitcnt >> 7; // bits without stuffing
505 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
506
507 tmp = bitcnt >> 16;
508 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
509 ptr->name, bitcnt, tmp);
510 zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
511 zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
512 tmp = bitcnt & 0xffff;
513 zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
514 zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
515
516 /* JPEG markers to be included in the compressed stream */
517 zr36060_write(ptr, ZR060_MER,
518 ZR060_MER_DQT | ZR060_MER_DHT |
519 ((ptr->com.len > 0) ? ZR060_MER_Com : 0) |
520 ((ptr->app.len > 0) ? ZR060_MER_App : 0));
521
522 /* Setup the Video Frontend */
523 /* Limit pixel range to 16..235 as per CCIR-601 */
524 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
525
526 } else {
527 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
528
529 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
530
531 /* 060 communicates with 067 in master mode */
532 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
533
534 /* Decompression */
535 zr36060_write(ptr, ZR060_CMR, 0);
536
537 /* Must be zero */
538 zr36060_write(ptr, ZR060_MBZ, 0x00);
539 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
540 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
541
542 /* Disable all IRQs - no DataErr means autoreset */
543 zr36060_write(ptr, ZR060_IMR, 0);
544
545 /* setup misc. data for expansion */
546 zr36060_write(ptr, ZR060_MER, 0);
547
548 /* setup the fixed jpeg tables - maybe variable, though -
549 * (see table init section above) */
550 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
551 zr36060_dht);
552
553 /* Setup the Video Frontend */
554 //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt);
555 //this doesn't seem right and doesn't work...
556 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
557 }
558
559 /* Load the tables */
560 zr36060_write(ptr, ZR060_LOAD,
561 ZR060_LOAD_SyncRst | ZR060_LOAD_Load);
562 zr36060_wait_end(ptr);
563 dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name,
564 ptr->status);
565
566 if (ptr->status & ZR060_CFSR_Busy) {
567 dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name);
568 return; // something is wrong, its timed out!!!!
569 }
570}
571
572/* =========================================================================
573 CODEC API FUNCTIONS
574
575 this functions are accessed by the master via the API structure
576 ========================================================================= */
577
578/* set compression/expansion mode and launches codec -
579 this should be the last call from the master before starting processing */
580static int
581zr36060_set_mode (struct videocodec *codec,
582 int mode)
583{
584 struct zr36060 *ptr = (struct zr36060 *) codec->data;
585
586 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
587
588 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
589 return -EINVAL;
590
591 ptr->mode = mode;
592 zr36060_init(ptr);
593
594 return 0;
595}
596
597/* set picture size (norm is ignored as the codec doesn't know about it) */
598static int
599zr36060_set_video (struct videocodec *codec,
600 struct tvnorm *norm,
601 struct vfe_settings *cap,
602 struct vfe_polarity *pol)
603{
604 struct zr36060 *ptr = (struct zr36060 *) codec->data;
605 u32 reg;
606 int size;
607
608 dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
609 cap->x, cap->y, cap->width, cap->height, cap->decimation);
610
611 /* if () return -EINVAL;
612 * trust the master driver that it knows what it does - so
613 * we allow invalid startx/y and norm for now ... */
614 ptr->width = cap->width / (cap->decimation & 0xff);
615 ptr->height = cap->height / (cap->decimation >> 8);
616
617 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
618
619 /* Note that VSPol/HSPol bits in zr36060 have the opposite
620 * meaning of their zr360x7 counterparts with the same names
621 * N.b. for VSPol this is only true if FIVEdge = 0 (default,
622 * left unchanged here - in accordance with datasheet).
623 */
624 reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0)
625 | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0)
626 | (pol->field_pol ? ZR060_VPR_FIPol : 0)
627 | (pol->blank_pol ? ZR060_VPR_BLPol : 0)
628 | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0)
629 | (pol->poe_pol ? ZR060_VPR_PoePol : 0)
630 | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0)
631 | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0);
632 zr36060_write(ptr, ZR060_VPR, reg);
633
634 reg = 0;
635 switch (cap->decimation & 0xff) {
636 default:
637 case 1:
638 break;
639
640 case 2:
641 reg |= ZR060_SR_HScale2;
642 break;
643
644 case 4:
645 reg |= ZR060_SR_HScale4;
646 break;
647 }
648
649 switch (cap->decimation >> 8) {
650 default:
651 case 1:
652 break;
653
654 case 2:
655 reg |= ZR060_SR_VScale;
656 break;
657 }
658 zr36060_write(ptr, ZR060_SR, reg);
659
660 zr36060_write(ptr, ZR060_BCR_Y, 0x00);
661 zr36060_write(ptr, ZR060_BCR_U, 0x80);
662 zr36060_write(ptr, ZR060_BCR_V, 0x80);
663
664 /* sync generator */
665
666 reg = norm->Ht - 1; /* Vtotal */
667 zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
668 zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
669
670 reg = norm->Wt - 1; /* Htotal */
671 zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
672 zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
673
674 reg = 6 - 1; /* VsyncSize */
675 zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
676
677 //reg = 30 - 1; /* HsyncSize */
678///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
679 reg = 68;
680 zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
681
682 reg = norm->VStart - 1; /* BVstart */
683 zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
684
685 reg += norm->Ha / 2; /* BVend */
686 zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
687 zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
688
689 reg = norm->HStart - 1; /* BHstart */
690 zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
691
692 reg += norm->Wa; /* BHend */
693 zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
694 zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
695
696 /* active area */
697 reg = cap->y + norm->VStart; /* Vstart */
698 zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
699 zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
700
701 reg += cap->height; /* Vend */
702 zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
703 zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
704
705 reg = cap->x + norm->HStart; /* Hstart */
706 zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
707 zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
708
709 reg += cap->width; /* Hend */
710 zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
711 zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
712
713 /* subimage area */
714 reg = norm->VStart - 4; /* SVstart */
715 zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
716 zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
717
718 reg += norm->Ha / 2 + 8; /* SVend */
719 zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
720 zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
721
722 reg = norm->HStart /*+ 64 */ - 4; /* SHstart */
723 zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
724 zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
725
726 reg += norm->Wa + 8; /* SHend */
727 zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
728 zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
729
730 size = ptr->width * ptr->height;
731 /* Target compressed field size in bits: */
732 size = size * 16; /* uncompressed size in bits */
733 /* (Ronald) by default, quality = 100 is a compression
734 * ratio 1:2. Setting low_bitrate (insmod option) sets
735 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
736 * buz can't handle more at decimation=1... Use low_bitrate if
737 * you have a Buz, unless you know what you're doing */
738 size = size * cap->quality / (low_bitrate ? 400 : 200);
739 /* Lower limit (arbitrary, 1 KB) */
740 if (size < 8192)
741 size = 8192;
742 /* Upper limit: 7/8 of the code buffers */
743 if (size > ptr->total_code_vol * 7)
744 size = ptr->total_code_vol * 7;
745
746 ptr->real_code_vol = size >> 3; /* in bytes */
747
748 /* the MBCVR is the *maximum* block volume, according to the
749 * JPEG ISO specs, this shouldn't be used, since that allows
750 * for the best encoding quality. So set it to it's max value */
751 reg = ptr->max_block_vol;
752 zr36060_write(ptr, ZR060_MBCVR, reg);
753
754 return 0;
755}
756
757/* additional control functions */
758static int
759zr36060_control (struct videocodec *codec,
760 int type,
761 int size,
762 void *data)
763{
764 struct zr36060 *ptr = (struct zr36060 *) codec->data;
765 int *ival = (int *) data;
766
767 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
768 size);
769
770 switch (type) {
771 case CODEC_G_STATUS: /* get last status */
772 if (size != sizeof(int))
773 return -EFAULT;
774 zr36060_read_status(ptr);
775 *ival = ptr->status;
776 break;
777
778 case CODEC_G_CODEC_MODE:
779 if (size != sizeof(int))
780 return -EFAULT;
781 *ival = CODEC_MODE_BJPG;
782 break;
783
784 case CODEC_S_CODEC_MODE:
785 if (size != sizeof(int))
786 return -EFAULT;
787 if (*ival != CODEC_MODE_BJPG)
788 return -EINVAL;
789 /* not needed, do nothing */
790 return 0;
791
792 case CODEC_G_VFE:
793 case CODEC_S_VFE:
794 /* not needed, do nothing */
795 return 0;
796
797 case CODEC_S_MMAP:
798 /* not available, give an error */
799 return -ENXIO;
800
801 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
802 if (size != sizeof(int))
803 return -EFAULT;
804 *ival = ptr->total_code_vol;
805 break;
806
807 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
808 if (size != sizeof(int))
809 return -EFAULT;
810 ptr->total_code_vol = *ival;
811 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
812 break;
813
814 case CODEC_G_JPEG_SCALE: /* get scaling factor */
815 if (size != sizeof(int))
816 return -EFAULT;
817 *ival = zr36060_read_scalefactor(ptr);
818 break;
819
820 case CODEC_S_JPEG_SCALE: /* set scaling factor */
821 if (size != sizeof(int))
822 return -EFAULT;
823 ptr->scalefact = *ival;
824 break;
825
826 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
827 struct jpeg_app_marker *app = data;
828
829 if (size != sizeof(struct jpeg_app_marker))
830 return -EFAULT;
831
832 *app = ptr->app;
833 break;
834 }
835
836 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
837 struct jpeg_app_marker *app = data;
838
839 if (size != sizeof(struct jpeg_app_marker))
840 return -EFAULT;
841
842 ptr->app = *app;
843 break;
844 }
845
846 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
847 struct jpeg_com_marker *com = data;
848
849 if (size != sizeof(struct jpeg_com_marker))
850 return -EFAULT;
851
852 *com = ptr->com;
853 break;
854 }
855
856 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
857 struct jpeg_com_marker *com = data;
858
859 if (size != sizeof(struct jpeg_com_marker))
860 return -EFAULT;
861
862 ptr->com = *com;
863 break;
864 }
865
866 default:
867 return -EINVAL;
868 }
869
870 return size;
871}
872
873/* =========================================================================
874 Exit and unregister function:
875
876 Deinitializes Zoran's JPEG processor
877 ========================================================================= */
878
879static int
880zr36060_unset (struct videocodec *codec)
881{
882 struct zr36060 *ptr = codec->data;
883
884 if (ptr) {
885 /* do wee need some codec deinit here, too ???? */
886
887 dprintk(1, "%s: finished codec #%d\n", ptr->name,
888 ptr->num);
889 kfree(ptr);
890 codec->data = NULL;
891
892 zr36060_codecs--;
893 return 0;
894 }
895
896 return -EFAULT;
897}
898
899/* =========================================================================
900 Setup and registry function:
901
902 Initializes Zoran's JPEG processor
903
904 Also sets pixel size, average code size, mode (compr./decompr.)
905 (the given size is determined by the processor with the video interface)
906 ========================================================================= */
907
908static int
909zr36060_setup (struct videocodec *codec)
910{
911 struct zr36060 *ptr;
912 int res;
913
914 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
915 zr36060_codecs);
916
917 if (zr36060_codecs == MAX_CODECS) {
918 dprintk(1,
919 KERN_ERR "zr36060: Can't attach more codecs!\n");
920 return -ENOSPC;
921 }
922 //mem structure init
923 codec->data = ptr = kmalloc(sizeof(struct zr36060), GFP_KERNEL);
924 if (NULL == ptr) {
925 dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n");
926 return -ENOMEM;
927 }
928 memset(ptr, 0, sizeof(struct zr36060));
929
930 snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]",
931 zr36060_codecs);
932 ptr->num = zr36060_codecs++;
933 ptr->codec = codec;
934
935 //testing
936 res = zr36060_basic_test(ptr);
937 if (res < 0) {
938 zr36060_unset(codec);
939 return res;
940 }
941 //final setup
942 memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
943 memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
944
945 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
946 * (what is the difference?) */
947 ptr->mode = CODEC_DO_COMPRESSION;
948 ptr->width = 384;
949 ptr->height = 288;
950 ptr->total_code_vol = 16000; /* CHECKME */
951 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
952 ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */
953 ptr->scalefact = 0x100;
954 ptr->dri = 1; /* CHECKME, was 8 is 1 */
955
956 /* by default, no COM or APP markers - app should set those */
957 ptr->com.len = 0;
958 ptr->app.appn = 0;
959 ptr->app.len = 0;
960
961 zr36060_init(ptr);
962
963 dprintk(1, KERN_INFO "%s: codec attached and running\n",
964 ptr->name);
965
966 return 0;
967}
968
969static const struct videocodec zr36060_codec = {
970 .owner = THIS_MODULE,
971 .name = "zr36060",
972 .magic = 0L, // magic not used
973 .flags =
974 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
975 CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
976 .type = CODEC_TYPE_ZR36060,
977 .setup = zr36060_setup, // functionality
978 .unset = zr36060_unset,
979 .set_mode = zr36060_set_mode,
980 .set_video = zr36060_set_video,
981 .control = zr36060_control,
982 // others are not used
983};
984
985/* =========================================================================
986 HOOK IN DRIVER AS KERNEL MODULE
987 ========================================================================= */
988
989static int __init
990zr36060_init_module (void)
991{
992 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
993 zr36060_codecs = 0;
994 return videocodec_register(&zr36060_codec);
995}
996
997static void __exit
998zr36060_cleanup_module (void)
999{
1000 if (zr36060_codecs) {
1001 dprintk(1,
1002 "zr36060: something's wrong - %d codecs left somehow.\n",
1003 zr36060_codecs);
1004 }
1005
1006 /* however, we can't just stay alive */
1007 videocodec_unregister(&zr36060_codec);
1008}
1009
1010module_init(zr36060_init_module);
1011module_exit(zr36060_cleanup_module);
1012
1013MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
1014MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
1015 ZR060_VERSION);
1016MODULE_LICENSE("GPL");