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