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