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