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