1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Zoran ZR36050 basic configuration functions
5 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
8 #define ZR050_VERSION "v0.7.1"
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/slab.h>
13 #include <linux/delay.h>
15 #include <linux/types.h>
16 #include <linux/wait.h>
18 /* I/O commands, error codes */
21 /* headerfile of this module */
25 #include "videocodec.h"
27 /* it doesn't make sense to have more than 20 or so,
28 just to prevent some unwanted loops */
31 /* amount of chips attached via this driver */
32 static int zr36050_codecs;
34 /* debugging is available via module parameter */
36 module_param(debug, int, 0);
37 MODULE_PARM_DESC(debug, "Debug level (0-4)");
39 #define dprintk(num, format, args...) \
42 printk(format, ##args); \
45 /* =========================================================================
46 Local hardware I/O functions:
48 read/write via codec layer (registers are located in the master device)
49 ========================================================================= */
51 /* read and write functions */
52 static u8 zr36050_read(struct zr36050 *ptr, u16 reg)
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;
61 KERN_ERR "%s: invalid I/O setup, nothing read!\n", ptr->name);
63 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value);
68 static void zr36050_write(struct zr36050 *ptr, u16 reg, u8 value)
70 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg);
72 /* just in case something is wrong... */
73 if (ptr->codec->master_data->writereg)
74 ptr->codec->master_data->writereg(ptr->codec, reg, value);
78 "%s: invalid I/O setup, nothing written!\n",
82 /* =========================================================================
83 Local helper function:
86 ========================================================================= */
88 /* status is kept in datastructure */
89 static u8 zr36050_read_status1(struct zr36050 *ptr)
91 ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
97 /* =========================================================================
98 Local helper function:
101 ========================================================================= */
103 /* scale factor is kept in datastructure */
104 static u16 zr36050_read_scalefactor(struct zr36050 *ptr)
106 ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
107 (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
109 /* leave 0 selected for an eventually GO from master */
110 zr36050_read(ptr, 0);
111 return ptr->scalefact;
114 /* =========================================================================
115 Local helper function:
117 wait if codec is ready to proceed (end of processing) or time is over
118 ========================================================================= */
120 static void zr36050_wait_end(struct zr36050 *ptr)
124 while (!(zr36050_read_status1(ptr) & 0x4)) {
126 if (i++ > 200000) { // 200ms, there is for sure something wrong!!!
128 "%s: timeout at wait_end (last status: 0x%02x)\n",
129 ptr->name, ptr->status1);
135 /* =========================================================================
136 Local helper function:
138 basic test of "connectivity", writes/reads to/from memory the SOF marker
139 ========================================================================= */
141 static int zr36050_basic_test(struct zr36050 *ptr)
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) {
149 "%s: attach failed, can't connect to jpeg processor!\n",
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) {
159 "%s: attach failed, can't connect to jpeg processor!\n",
164 zr36050_wait_end(ptr);
165 if ((ptr->status1 & 0x4) == 0) {
168 "%s: attach failed, jpeg processor failed (end flag)!\n",
173 return 0; /* looks good! */
176 /* =========================================================================
177 Local helper function:
179 simple loop for pushing the init datasets
180 ========================================================================= */
182 static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char *data)
186 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
189 zr36050_write(ptr, startreg++, data[i++]);
194 /* =========================================================================
197 jpeg baseline setup data (you find it on lots places in internet, or just
198 extract it from any regular .jpg image...)
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 ========================================================================= */
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
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,
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,
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
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 };
296 /* =========================================================================
297 Local helper functions:
299 calculation and setup of parameter-dependent JPEG baseline segments
300 (needed for compression only)
301 ========================================================================= */
303 /* ------------------------------------------------------------------------- */
305 /* SOF (start of frame) segment depends on width, height and sampling ratio
306 of each color component */
308 static int zr36050_set_sof(struct zr36050 *ptr)
310 char sof_data[34]; // max. size of register set
313 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
314 ptr->width, ptr->height, NO_OF_COMPONENTS);
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
330 return zr36050_pushit(ptr, ZR050_SOF_IDX,
331 (3 * NO_OF_COMPONENTS) + 10, sof_data);
334 /* ------------------------------------------------------------------------- */
336 /* SOS (start of scan) segment depends on the used scan components
337 of each color component */
339 static int zr36050_set_sos(struct zr36050 *ptr)
341 char sos_data[16]; // max. size of register set
344 dprintk(3, "%s: write SOS\n", ptr->name);
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.
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,
362 /* ------------------------------------------------------------------------- */
364 /* DRI (define restart interval) */
366 static int zr36050_set_dri(struct zr36050 *ptr)
368 char dri_data[6]; // max. size of register set
370 dprintk(3, "%s: write DRI\n", ptr->name);
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);
380 /* =========================================================================
383 Setup compression/decompression of Zoran's JPEG processor
384 ( see also zoran 36050 manual )
386 ... sorry for the spaghetti code ...
387 ========================================================================= */
388 static void zr36050_init(struct zr36050 *ptr)
393 if (ptr->mode == CODEC_DO_COMPRESSION) {
394 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
396 /* 050 communicates with 057 in master mode */
397 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
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);
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
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);
413 zr36050_write(ptr, ZR050_AF_HI, 0xff);
414 zr36050_write(ptr, ZR050_AF_M, 0xff);
415 zr36050_write(ptr, ZR050_AF_LO, 0xff);
417 /* setup the variable jpeg tables */
418 sum += zr36050_set_sof(ptr);
419 sum += zr36050_set_sos(ptr);
420 sum += zr36050_set_dri(ptr);
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,
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,
442 /* do the internal huffman table preload */
443 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
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);
450 if ((ptr->status1 & 0x4) == 0) {
451 pr_err("%s: init aborted!\n", ptr->name);
452 return; // something is wrong, its timed out!!!!
455 /* setup misc. data for compression (target code sizes) */
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 */
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);
471 bitcnt -= bitcnt >> 7; // bits without stuffing
472 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
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);
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));
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));
494 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
496 /* 050 communicates with 055 in master mode */
497 zr36050_write(ptr, ZR050_HARDWARE,
498 ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
500 /* encoding table preload */
501 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
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
507 dprintk(3, "%s: write DHT\n", ptr->name);
508 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
511 /* do the internal huffman table preload */
512 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
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);
519 if ((ptr->status1 & 0x4) == 0) {
520 pr_err("%s: init aborted!\n", ptr->name);
521 return; // something is wrong, its timed out!!!!
524 /* setup misc. data for expansion */
525 zr36050_write(ptr, ZR050_MODE, 0);
526 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
529 /* adr on selected, to allow GO from master */
530 zr36050_read(ptr, 0);
533 /* =========================================================================
536 this functions are accessed by the master via the API structure
537 ========================================================================= */
539 /* set compression/expansion mode and launches codec -
540 this should be the last call from the master before starting processing */
541 static int zr36050_set_mode(struct videocodec *codec, int mode)
543 struct zr36050 *ptr = (struct zr36050 *)codec->data;
545 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
547 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
556 /* set picture size (norm is ignored as the codec doesn't know about it) */
557 static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm,
558 struct vfe_settings *cap, struct vfe_polarity *pol)
560 struct zr36050 *ptr = (struct zr36050 *)codec->data;
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);
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;
582 /* Maximum: 7/8 of code buffer */
583 if (size > ptr->total_code_vol * 7)
584 size = ptr->total_code_vol * 7;
586 ptr->real_code_vol = size >> 3; /* in bytes */
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);
595 /* additional control functions */
596 static int zr36050_control(struct videocodec *codec, int type, int size, void *data)
598 struct zr36050 *ptr = (struct zr36050 *)codec->data;
599 int *ival = (int *)data;
601 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
605 case CODEC_G_STATUS: /* get last status */
606 if (size != sizeof(int))
608 zr36050_read_status1(ptr);
609 *ival = ptr->status1;
612 case CODEC_G_CODEC_MODE:
613 if (size != sizeof(int))
615 *ival = CODEC_MODE_BJPG;
618 case CODEC_S_CODEC_MODE:
619 if (size != sizeof(int))
621 if (*ival != CODEC_MODE_BJPG)
623 /* not needed, do nothing */
628 /* not needed, do nothing */
632 /* not available, give an error */
635 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
636 if (size != sizeof(int))
638 *ival = ptr->total_code_vol;
641 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
642 if (size != sizeof(int))
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;
650 case CODEC_G_JPEG_SCALE: /* get scaling factor */
651 if (size != sizeof(int))
653 *ival = zr36050_read_scalefactor(ptr);
656 case CODEC_S_JPEG_SCALE: /* set scaling factor */
657 if (size != sizeof(int))
659 ptr->scalefact = *ival;
662 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
663 struct jpeg_app_marker *app = data;
665 if (size != sizeof(struct jpeg_app_marker))
672 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
673 struct jpeg_app_marker *app = data;
675 if (size != sizeof(struct jpeg_app_marker))
682 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
683 struct jpeg_com_marker *com = data;
685 if (size != sizeof(struct jpeg_com_marker))
692 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
693 struct jpeg_com_marker *com = data;
695 if (size != sizeof(struct jpeg_com_marker))
709 /* =========================================================================
710 Exit and unregister function:
712 Deinitializes Zoran's JPEG processor
713 ========================================================================= */
715 static int zr36050_unset(struct videocodec *codec)
717 struct zr36050 *ptr = codec->data;
720 /* do wee need some codec deinit here, too ???? */
722 dprintk(1, "%s: finished codec #%d\n", ptr->name,
734 /* =========================================================================
735 Setup and registry function:
737 Initializes Zoran's JPEG processor
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 ========================================================================= */
743 static int zr36050_setup(struct videocodec *codec)
748 dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
751 if (zr36050_codecs == MAX_CODECS) {
753 KERN_ERR "zr36050: Can't attach more codecs!\n");
757 codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL);
761 snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
763 ptr->num = zr36050_codecs++;
767 res = zr36050_basic_test(ptr);
769 zr36050_unset(codec);
773 memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
774 memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
776 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
777 * (what is the difference?) */
778 ptr->mode = CODEC_DO_COMPRESSION;
781 ptr->total_code_vol = 16000;
782 ptr->max_block_vol = 240;
783 ptr->scalefact = 0x100;
786 /* no app/com marker by default */
793 dprintk(1, KERN_INFO "%s: codec attached and running\n",
799 static const struct videocodec zr36050_codec = {
800 .owner = THIS_MODULE,
802 .magic = 0L, // magic not used
804 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
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
815 /* =========================================================================
816 HOOK IN DRIVER AS KERNEL MODULE
817 ========================================================================= */
819 static int __init zr36050_init_module(void)
821 //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION);
823 return videocodec_register(&zr36050_codec);
826 static void __exit zr36050_cleanup_module(void)
828 if (zr36050_codecs) {
830 "zr36050: something's wrong - %d codecs left somehow.\n",
833 videocodec_unregister(&zr36050_codec);
836 module_init(zr36050_init_module);
837 module_exit(zr36050_cleanup_module);
839 MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
840 MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
842 MODULE_LICENSE("GPL");