GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / staging / media / zoran / zr36050.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Zoran ZR36050 basic configuration functions
4  *
5  * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
6  */
7
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12
13 #include <linux/types.h>
14 #include <linux/wait.h>
15
16 /* I/O commands, error codes */
17 #include <linux/io.h>
18
19 /* headerfile of this module */
20 #include "zr36050.h"
21
22 /* codec io API */
23 #include "videocodec.h"
24
25 /* it doesn't make sense to have more than 20 or so,
26   just to prevent some unwanted loops */
27 #define MAX_CODECS 20
28
29 /* amount of chips attached via this driver */
30 static int zr36050_codecs;
31
32 /* debugging is available via module parameter */
33 static int zr36050_debug;
34 module_param(zr36050_debug, int, 0);
35 MODULE_PARM_DESC(zr36050_debug, "Debug level (0-4)");
36
37 #define dprintk(num, format, args...) \
38         do { \
39                 if (zr36050_debug >= num) \
40                         printk(format, ##args); \
41         } while (0)
42
43 /* =========================================================================
44    Local hardware I/O functions:
45
46    read/write via codec layer (registers are located in the master device)
47    ========================================================================= */
48
49 /* read and write functions */
50 static u8 zr36050_read(struct zr36050 *ptr, u16 reg)
51 {
52         u8 value = 0;
53
54         /* just in case something is wrong... */
55         if (ptr->codec->master_data->readreg)
56                 value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF;
57         else
58                 dprintk(1,
59                         KERN_ERR "%s: invalid I/O setup, nothing read!\n", ptr->name);
60
61         dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value);
62
63         return value;
64 }
65
66 static void zr36050_write(struct zr36050 *ptr, u16 reg, u8 value)
67 {
68         dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg);
69
70         /* just in case something is wrong... */
71         if (ptr->codec->master_data->writereg)
72                 ptr->codec->master_data->writereg(ptr->codec, reg, value);
73         else
74                 dprintk(1,
75                         KERN_ERR
76                         "%s: invalid I/O setup, nothing written!\n",
77                         ptr->name);
78 }
79
80 /* =========================================================================
81    Local helper function:
82
83    status read
84    ========================================================================= */
85
86 /* status is kept in datastructure */
87 static u8 zr36050_read_status1(struct zr36050 *ptr)
88 {
89         ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
90
91         zr36050_read(ptr, 0);
92         return ptr->status1;
93 }
94
95 /* =========================================================================
96    Local helper function:
97
98    scale factor read
99    ========================================================================= */
100
101 /* scale factor is kept in datastructure */
102 static u16 zr36050_read_scalefactor(struct zr36050 *ptr)
103 {
104         ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
105                          (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
106
107         /* leave 0 selected for an eventually GO from master */
108         zr36050_read(ptr, 0);
109         return ptr->scalefact;
110 }
111
112 /* =========================================================================
113    Local helper function:
114
115    wait if codec is ready to proceed (end of processing) or time is over
116    ========================================================================= */
117
118 static void zr36050_wait_end(struct zr36050 *ptr)
119 {
120         int i = 0;
121
122         while (!(zr36050_read_status1(ptr) & 0x4)) {
123                 udelay(1);
124                 if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
125                         dprintk(1,
126                                 "%s: timeout at wait_end (last status: 0x%02x)\n",
127                                 ptr->name, ptr->status1);
128                         break;
129                 }
130         }
131 }
132
133 /* =========================================================================
134    Local helper function:
135
136    basic test of "connectivity", writes/reads to/from memory the SOF marker
137    ========================================================================= */
138
139 static int zr36050_basic_test(struct zr36050 *ptr)
140 {
141         zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
142         zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
143         if ((zr36050_read(ptr, ZR050_SOF_IDX) |
144              zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
145                 dprintk(1,
146                         KERN_ERR
147                         "%s: attach failed, can't connect to jpeg processor!\n",
148                         ptr->name);
149                 return -ENXIO;
150         }
151         zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
152         zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
153         if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
154              zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
155                 dprintk(1,
156                         KERN_ERR
157                         "%s: attach failed, can't connect to jpeg processor!\n",
158                         ptr->name);
159                 return -ENXIO;
160         }
161
162         zr36050_wait_end(ptr);
163         if ((ptr->status1 & 0x4) == 0) {
164                 dprintk(1,
165                         KERN_ERR
166                         "%s: attach failed, jpeg processor failed (end flag)!\n",
167                         ptr->name);
168                 return -EBUSY;
169         }
170
171         return 0;               /* looks good! */
172 }
173
174 /* =========================================================================
175    Local helper function:
176
177    simple loop for pushing the init datasets
178    ========================================================================= */
179
180 static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char *data)
181 {
182         int i = 0;
183
184         dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
185                 startreg, len);
186         while (i < len)
187                 zr36050_write(ptr, startreg++, data[i++]);
188
189         return i;
190 }
191
192 /* =========================================================================
193    Basic datasets:
194
195    jpeg baseline setup data (you find it on lots places in internet, or just
196    extract it from any regular .jpg image...)
197
198    Could be variable, but until it's not needed it they are just fixed to save
199    memory. Otherwise expand zr36050 structure with arrays, push the values to
200    it and initialize from there, as e.g. the linux zr36057/60 driver does it.
201    ========================================================================= */
202
203 static const char zr36050_dqt[0x86] = {
204         0xff, 0xdb,             //Marker: DQT
205         0x00, 0x84,             //Length: 2*65+2
206         0x00,                   //Pq,Tq first table
207         0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
208         0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
209         0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
210         0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
211         0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
212         0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
213         0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
214         0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
215         0x01,                   //Pq,Tq second table
216         0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
217         0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
218         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
219         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
220         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
221         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
222         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
223         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
224 };
225
226 static const char zr36050_dht[0x1a4] = {
227         0xff, 0xc4,             //Marker: DHT
228         0x01, 0xa2,             //Length: 2*AC, 2*DC
229         0x00,                   //DC first table
230         0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
231         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
232         0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
233         0x01,                   //DC second table
234         0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
235         0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
236         0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
237         0x10,                   //AC first table
238         0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
239         0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
240         0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
241         0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
242         0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
243         0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
244         0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
245         0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
246         0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
247         0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
248         0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
249         0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
250         0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
251         0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
252         0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
253         0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
254         0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
255         0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
256         0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
257         0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
258         0xF8, 0xF9, 0xFA,
259         0x11,                   //AC second table
260         0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
261         0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
262         0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
263         0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
264         0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
265         0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
266         0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
267         0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
268         0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
269         0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
270         0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
271         0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
272         0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
273         0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
274         0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
275         0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
276         0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
277         0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
278         0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
279         0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
280         0xF9, 0xFA
281 };
282
283 /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
284 #define NO_OF_COMPONENTS          0x3   //Y,U,V
285 #define BASELINE_PRECISION        0x8   //MCU size (?)
286 static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };   //table idx's QT
287 static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };   //table idx's DC
288 static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };   //table idx's AC
289
290 /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
291 static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
292 static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
293
294 /* =========================================================================
295    Local helper functions:
296
297    calculation and setup of parameter-dependent JPEG baseline segments
298    (needed for compression only)
299    ========================================================================= */
300
301 /* ------------------------------------------------------------------------- */
302
303 /* SOF (start of frame) segment depends on width, height and sampling ratio
304                          of each color component */
305
306 static int zr36050_set_sof(struct zr36050 *ptr)
307 {
308         char sof_data[34];      // max. size of register set
309         int i;
310
311         dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
312                 ptr->width, ptr->height, NO_OF_COMPONENTS);
313         sof_data[0] = 0xff;
314         sof_data[1] = 0xc0;
315         sof_data[2] = 0x00;
316         sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
317         sof_data[4] = BASELINE_PRECISION;       // only '8' possible with zr36050
318         sof_data[5] = (ptr->height) >> 8;
319         sof_data[6] = (ptr->height) & 0xff;
320         sof_data[7] = (ptr->width) >> 8;
321         sof_data[8] = (ptr->width) & 0xff;
322         sof_data[9] = NO_OF_COMPONENTS;
323         for (i = 0; i < NO_OF_COMPONENTS; i++) {
324                 sof_data[10 + (i * 3)] = i;     // index identifier
325                 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]);  // sampling ratios
326                 sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
327         }
328         return zr36050_pushit(ptr, ZR050_SOF_IDX,
329                               (3 * NO_OF_COMPONENTS) + 10, sof_data);
330 }
331
332 /* ------------------------------------------------------------------------- */
333
334 /* SOS (start of scan) segment depends on the used scan components
335                         of each color component */
336
337 static int zr36050_set_sos(struct zr36050 *ptr)
338 {
339         char sos_data[16];      // max. size of register set
340         int i;
341
342         dprintk(3, "%s: write SOS\n", ptr->name);
343         sos_data[0] = 0xff;
344         sos_data[1] = 0xda;
345         sos_data[2] = 0x00;
346         sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
347         sos_data[4] = NO_OF_COMPONENTS;
348         for (i = 0; i < NO_OF_COMPONENTS; i++) {
349                 sos_data[5 + (i * 2)] = i;      // index
350                 sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i];   // AC/DC tbl.sel.
351         }
352         sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;      // scan start
353         sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
354         sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
355         return zr36050_pushit(ptr, ZR050_SOS1_IDX,
356                               4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
357                               sos_data);
358 }
359
360 /* ------------------------------------------------------------------------- */
361
362 /* DRI (define restart interval) */
363
364 static int zr36050_set_dri(struct zr36050 *ptr)
365 {
366         char dri_data[6];       // max. size of register set
367
368         dprintk(3, "%s: write DRI\n", ptr->name);
369         dri_data[0] = 0xff;
370         dri_data[1] = 0xdd;
371         dri_data[2] = 0x00;
372         dri_data[3] = 0x04;
373         dri_data[4] = ptr->dri >> 8;
374         dri_data[5] = ptr->dri & 0xff;
375         return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
376 }
377
378 /* =========================================================================
379    Setup function:
380
381    Setup compression/decompression of Zoran's JPEG processor
382    ( see also zoran 36050 manual )
383
384    ... sorry for the spaghetti code ...
385    ========================================================================= */
386 static void zr36050_init(struct zr36050 *ptr)
387 {
388         int sum = 0;
389         long bitcnt, tmp;
390
391         if (ptr->mode == CODEC_DO_COMPRESSION) {
392                 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
393
394                 /* 050 communicates with 057 in master mode */
395                 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
396
397                 /* encoding table preload for compression */
398                 zr36050_write(ptr, ZR050_MODE,
399                               ZR050_MO_COMP | ZR050_MO_TLM);
400                 zr36050_write(ptr, ZR050_OPTIONS, 0);
401
402                 /* disable all IRQs */
403                 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
404                 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
405
406                 /* volume control settings */
407                 /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
408                 zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
409                 zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
410
411                 zr36050_write(ptr, ZR050_AF_HI, 0xff);
412                 zr36050_write(ptr, ZR050_AF_M, 0xff);
413                 zr36050_write(ptr, ZR050_AF_LO, 0xff);
414
415                 /* setup the variable jpeg tables */
416                 sum += zr36050_set_sof(ptr);
417                 sum += zr36050_set_sos(ptr);
418                 sum += zr36050_set_dri(ptr);
419
420                 /* setup the fixed jpeg tables - maybe variable, though -
421                  * (see table init section above) */
422                 dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
423                 sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
424                                       sizeof(zr36050_dqt), zr36050_dqt);
425                 sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
426                                       sizeof(zr36050_dht), zr36050_dht);
427                 zr36050_write(ptr, ZR050_APP_IDX, 0xff);
428                 zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
429                 zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
430                 zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
431                 sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
432                                       ptr->app.data) + 4;
433                 zr36050_write(ptr, ZR050_COM_IDX, 0xff);
434                 zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
435                 zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
436                 zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
437                 sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
438                                       ptr->com.data) + 4;
439
440                 /* do the internal huffman table preload */
441                 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
442
443                 zr36050_write(ptr, ZR050_GO, 1);        // launch codec
444                 zr36050_wait_end(ptr);
445                 dprintk(2, "%s: Status after table preload: 0x%02x\n",
446                         ptr->name, ptr->status1);
447
448                 if ((ptr->status1 & 0x4) == 0) {
449                         pr_err("%s: init aborted!\n", ptr->name);
450                         return; // something is wrong, its timed out!!!!
451                 }
452
453                 /* setup misc. data for compression (target code sizes) */
454
455                 /* size of compressed code to reach without header data */
456                 sum = ptr->real_code_vol - sum;
457                 bitcnt = sum << 3;      /* need the size in bits */
458
459                 tmp = bitcnt >> 16;
460                 dprintk(3,
461                         "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
462                         ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
463                 zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
464                 zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
465                 tmp = bitcnt & 0xffff;
466                 zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
467                 zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
468
469                 bitcnt -= bitcnt >> 7;  // bits without stuffing
470                 bitcnt -= ((bitcnt * 5) >> 6);  // bits without eob
471
472                 tmp = bitcnt >> 16;
473                 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
474                         ptr->name, bitcnt, tmp);
475                 zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
476                 zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
477                 tmp = bitcnt & 0xffff;
478                 zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
479                 zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
480
481                 /* compression setup with or without bitrate control */
482                 zr36050_write(ptr, ZR050_MODE,
483                               ZR050_MO_COMP | ZR050_MO_PASS2 |
484                               (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
485
486                 /* this headers seem to deliver "valid AVI" jpeg frames */
487                 zr36050_write(ptr, ZR050_MARKERS_EN,
488                               ZR050_ME_DQT | ZR050_ME_DHT |
489                               ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
490                               ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
491         } else {
492                 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
493
494                 /* 050 communicates with 055 in master mode */
495                 zr36050_write(ptr, ZR050_HARDWARE,
496                               ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
497
498                 /* encoding table preload */
499                 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
500
501                 /* disable all IRQs */
502                 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
503                 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
504
505                 dprintk(3, "%s: write DHT\n", ptr->name);
506                 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
507                                zr36050_dht);
508
509                 /* do the internal huffman table preload */
510                 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
511
512                 zr36050_write(ptr, ZR050_GO, 1);        // launch codec
513                 zr36050_wait_end(ptr);
514                 dprintk(2, "%s: Status after table preload: 0x%02x\n",
515                         ptr->name, ptr->status1);
516
517                 if ((ptr->status1 & 0x4) == 0) {
518                         pr_err("%s: init aborted!\n", ptr->name);
519                         return; // something is wrong, its timed out!!!!
520                 }
521
522                 /* setup misc. data for expansion */
523                 zr36050_write(ptr, ZR050_MODE, 0);
524                 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
525         }
526
527         /* adr on selected, to allow GO from master */
528         zr36050_read(ptr, 0);
529 }
530
531 /* =========================================================================
532    CODEC API FUNCTIONS
533
534    this functions are accessed by the master via the API structure
535    ========================================================================= */
536
537 /* set compression/expansion mode and launches codec -
538    this should be the last call from the master before starting processing */
539 static int zr36050_set_mode(struct videocodec *codec, int mode)
540 {
541         struct zr36050 *ptr = (struct zr36050 *)codec->data;
542
543         dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
544
545         if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
546                 return -EINVAL;
547
548         ptr->mode = mode;
549         zr36050_init(ptr);
550
551         return 0;
552 }
553
554 /* set picture size (norm is ignored as the codec doesn't know about it) */
555 static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm,
556                              struct vfe_settings *cap, struct vfe_polarity *pol)
557 {
558         struct zr36050 *ptr = (struct zr36050 *)codec->data;
559         int size;
560
561         dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
562                 ptr->name, norm->h_start, norm->v_start,
563                 cap->x, cap->y, cap->width, cap->height,
564                 cap->decimation, cap->quality);
565         /* if () return -EINVAL;
566          * trust the master driver that it knows what it does - so
567          * we allow invalid startx/y and norm for now ... */
568         ptr->width = cap->width / (cap->decimation & 0xff);
569         ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
570
571         /* (KM) JPEG quality */
572         size = ptr->width * ptr->height;
573         size *= 16; /* size in bits */
574         /* apply quality setting */
575         size = size * cap->quality / 200;
576
577         /* Minimum: 1kb */
578         if (size < 8192)
579                 size = 8192;
580         /* Maximum: 7/8 of code buffer */
581         if (size > ptr->total_code_vol * 7)
582                 size = ptr->total_code_vol * 7;
583
584         ptr->real_code_vol = size >> 3; /* in bytes */
585
586         /* Set max_block_vol here (previously in zr36050_init, moved
587  * here for consistency with zr36060 code */
588         zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
589
590         return 0;
591 }
592
593 /* additional control functions */
594 static int zr36050_control(struct videocodec *codec, int type, int size, void *data)
595 {
596         struct zr36050 *ptr = (struct zr36050 *)codec->data;
597         int *ival = (int *)data;
598
599         dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
600                 size);
601
602         switch (type) {
603         case CODEC_G_STATUS:    /* get last status */
604                 if (size != sizeof(int))
605                         return -EFAULT;
606                 zr36050_read_status1(ptr);
607                 *ival = ptr->status1;
608                 break;
609
610         case CODEC_G_CODEC_MODE:
611                 if (size != sizeof(int))
612                         return -EFAULT;
613                 *ival = CODEC_MODE_BJPG;
614                 break;
615
616         case CODEC_S_CODEC_MODE:
617                 if (size != sizeof(int))
618                         return -EFAULT;
619                 if (*ival != CODEC_MODE_BJPG)
620                         return -EINVAL;
621                 /* not needed, do nothing */
622                 return 0;
623
624         case CODEC_G_VFE:
625         case CODEC_S_VFE:
626                 /* not needed, do nothing */
627                 return 0;
628
629         case CODEC_S_MMAP:
630                 /* not available, give an error */
631                 return -ENXIO;
632
633         case CODEC_G_JPEG_TDS_BYTE:     /* get target volume in byte */
634                 if (size != sizeof(int))
635                         return -EFAULT;
636                 *ival = ptr->total_code_vol;
637                 break;
638
639         case CODEC_S_JPEG_TDS_BYTE:     /* get target volume in byte */
640                 if (size != sizeof(int))
641                         return -EFAULT;
642                 ptr->total_code_vol = *ival;
643                 /* (Kieran Morrissey)
644                  * code copied from zr36060.c to ensure proper bitrate */
645                 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
646                 break;
647
648         case CODEC_G_JPEG_SCALE:        /* get scaling factor */
649                 if (size != sizeof(int))
650                         return -EFAULT;
651                 *ival = zr36050_read_scalefactor(ptr);
652                 break;
653
654         case CODEC_S_JPEG_SCALE:        /* set scaling factor */
655                 if (size != sizeof(int))
656                         return -EFAULT;
657                 ptr->scalefact = *ival;
658                 break;
659
660         case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
661                 struct jpeg_app_marker *app = data;
662
663                 if (size != sizeof(struct jpeg_app_marker))
664                         return -EFAULT;
665
666                 *app = ptr->app;
667                 break;
668         }
669
670         case CODEC_S_JPEG_APP_DATA: {    /* set appn marker data */
671                 struct jpeg_app_marker *app = data;
672
673                 if (size != sizeof(struct jpeg_app_marker))
674                         return -EFAULT;
675
676                 ptr->app = *app;
677                 break;
678         }
679
680         case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
681                 struct jpeg_com_marker *com = data;
682
683                 if (size != sizeof(struct jpeg_com_marker))
684                         return -EFAULT;
685
686                 *com = ptr->com;
687                 break;
688         }
689
690         case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
691                 struct jpeg_com_marker *com = data;
692
693                 if (size != sizeof(struct jpeg_com_marker))
694                         return -EFAULT;
695
696                 ptr->com = *com;
697                 break;
698         }
699
700         default:
701                 return -EINVAL;
702         }
703
704         return size;
705 }
706
707 /* =========================================================================
708    Exit and unregister function:
709
710    Deinitializes Zoran's JPEG processor
711    ========================================================================= */
712
713 static int zr36050_unset(struct videocodec *codec)
714 {
715         struct zr36050 *ptr = codec->data;
716
717         if (ptr) {
718                 /* do wee need some codec deinit here, too ???? */
719
720                 dprintk(1, "%s: finished codec #%d\n", ptr->name,
721                         ptr->num);
722                 kfree(ptr);
723                 codec->data = NULL;
724
725                 zr36050_codecs--;
726                 return 0;
727         }
728
729         return -EFAULT;
730 }
731
732 /* =========================================================================
733    Setup and registry function:
734
735    Initializes Zoran's JPEG processor
736
737    Also sets pixel size, average code size, mode (compr./decompr.)
738    (the given size is determined by the processor with the video interface)
739    ========================================================================= */
740
741 static int zr36050_setup(struct videocodec *codec)
742 {
743         struct zr36050 *ptr;
744         int res;
745
746         dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
747                 zr36050_codecs);
748
749         if (zr36050_codecs == MAX_CODECS) {
750                 dprintk(1,
751                         KERN_ERR "zr36050: Can't attach more codecs!\n");
752                 return -ENOSPC;
753         }
754         //mem structure init
755         ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
756         codec->data = ptr;
757         if (!ptr)
758                 return -ENOMEM;
759
760         snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
761                  zr36050_codecs);
762         ptr->num = zr36050_codecs++;
763         ptr->codec = codec;
764
765         //testing
766         res = zr36050_basic_test(ptr);
767         if (res < 0) {
768                 zr36050_unset(codec);
769                 return res;
770         }
771         //final setup
772         memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
773         memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
774
775         ptr->bitrate_ctrl = 0;  /* 0 or 1 - fixed file size flag
776                                  * (what is the difference?) */
777         ptr->mode = CODEC_DO_COMPRESSION;
778         ptr->width = 384;
779         ptr->height = 288;
780         ptr->total_code_vol = 16000;
781         ptr->max_block_vol = 240;
782         ptr->scalefact = 0x100;
783         ptr->dri = 1;
784
785         /* no app/com marker by default */
786         ptr->app.appn = 0;
787         ptr->app.len = 0;
788         ptr->com.len = 0;
789
790         zr36050_init(ptr);
791
792         dprintk(1, KERN_INFO "%s: codec attached and running\n",
793                 ptr->name);
794
795         return 0;
796 }
797
798 static const struct videocodec zr36050_codec = {
799         .name = "zr36050",
800         .magic = 0L,            // magic not used
801         .flags =
802             CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
803             CODEC_FLAG_DECODER,
804         .type = CODEC_TYPE_ZR36050,
805         .setup = zr36050_setup, // functionality
806         .unset = zr36050_unset,
807         .set_mode = zr36050_set_mode,
808         .set_video = zr36050_set_video,
809         .control = zr36050_control,
810         // others are not used
811 };
812
813 /* =========================================================================
814    HOOK IN DRIVER AS KERNEL MODULE
815    ========================================================================= */
816
817 int zr36050_init_module(void)
818 {
819         zr36050_codecs = 0;
820         return videocodec_register(&zr36050_codec);
821 }
822
823 void zr36050_cleanup_module(void)
824 {
825         if (zr36050_codecs) {
826                 dprintk(1,
827                         "zr36050: something's wrong - %d codecs left somehow.\n",
828                         zr36050_codecs);
829         }
830         videocodec_unregister(&zr36050_codec);
831 }