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