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