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