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