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