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