1/*
2 * Zoran ZR36060 basic configuration functions
3 *
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
5 *
6 * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 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 ZR060_VERSION "v0.7"
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 "zr36060.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 */
51static int zr36060_codecs;
52
53static bool low_bitrate;
54module_param(low_bitrate, bool, 0);
55MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
56
57/* debugging is available via module parameter */
58static int debug;
59module_param(debug, int, 0);
60MODULE_PARM_DESC(debug, "Debug level (0-4)");
61
62#define dprintk(num, format, args...) \
63	do { \
64		if (debug >= num) \
65			printk(format, ##args); \
66	} while (0)
67
68/* =========================================================================
69   Local hardware I/O functions:
70
71   read/write via codec layer (registers are located in the master device)
72   ========================================================================= */
73
74/* read and write functions */
75static u8
76zr36060_read (struct zr36060 *ptr,
77	      u16             reg)
78{
79	u8 value = 0;
80
81	// just in case something is wrong...
82	if (ptr->codec->master_data->readreg)
83		value = (ptr->codec->master_data->readreg(ptr->codec,
84							  reg)) & 0xff;
85	else
86		dprintk(1,
87			KERN_ERR "%s: invalid I/O setup, nothing read!\n",
88			ptr->name);
89
90	//dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
91
92	return value;
93}
94
95static void
96zr36060_write(struct zr36060 *ptr,
97	      u16             reg,
98	      u8              value)
99{
100	//dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg);
101	dprintk(4, "0x%02x @0x%04x\n", value, reg);
102
103	// just in case something is wrong...
104	if (ptr->codec->master_data->writereg)
105		ptr->codec->master_data->writereg(ptr->codec, reg, value);
106	else
107		dprintk(1,
108			KERN_ERR
109			"%s: invalid I/O setup, nothing written!\n",
110			ptr->name);
111}
112
113/* =========================================================================
114   Local helper function:
115
116   status read
117   ========================================================================= */
118
119/* status is kept in datastructure */
120static u8
121zr36060_read_status (struct zr36060 *ptr)
122{
123	ptr->status = zr36060_read(ptr, ZR060_CFSR);
124
125	zr36060_read(ptr, 0);
126	return ptr->status;
127}
128
129/* =========================================================================
130   Local helper function:
131
132   scale factor read
133   ========================================================================= */
134
135/* scale factor is kept in datastructure */
136static u16
137zr36060_read_scalefactor (struct zr36060 *ptr)
138{
139	ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
140			 (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
141
142	/* leave 0 selected for an eventually GO from master */
143	zr36060_read(ptr, 0);
144	return ptr->scalefact;
145}
146
147/* =========================================================================
148   Local helper function:
149
150   wait if codec is ready to proceed (end of processing) or time is over
151   ========================================================================= */
152
153static void
154zr36060_wait_end (struct zr36060 *ptr)
155{
156	int i = 0;
157
158	while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) {
159		udelay(1);
160		if (i++ > 200000) {	// 200ms, there is for sure something wrong!!!
161			dprintk(1,
162				"%s: timeout at wait_end (last status: 0x%02x)\n",
163				ptr->name, ptr->status);
164			break;
165		}
166	}
167}
168
169/* =========================================================================
170   Local helper function:
171
172   basic test of "connectivity", writes/reads to/from memory the SOF marker
173   ========================================================================= */
174
175static int
176zr36060_basic_test (struct zr36060 *ptr)
177{
178	if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
179	    (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
180		dprintk(1,
181			KERN_ERR
182			"%s: attach failed, can't connect to jpeg processor!\n",
183			ptr->name);
184		return -ENXIO;
185	}
186
187	zr36060_wait_end(ptr);
188	if (ptr->status & ZR060_CFSR_Busy) {
189		dprintk(1,
190			KERN_ERR
191			"%s: attach failed, jpeg processor failed (end flag)!\n",
192			ptr->name);
193		return -EBUSY;
194	}
195
196	return 0;		/* looks good! */
197}
198
199/* =========================================================================
200   Local helper function:
201
202   simple loop for pushing the init datasets
203   ========================================================================= */
204
205static int
206zr36060_pushit (struct zr36060 *ptr,
207		u16             startreg,
208		u16             len,
209		const char     *data)
210{
211	int i = 0;
212
213	dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
214		startreg, len);
215	while (i < len) {
216		zr36060_write(ptr, startreg++, data[i++]);
217	}
218
219	return i;
220}
221
222/* =========================================================================
223   Basic datasets:
224
225   jpeg baseline setup data (you find it on lots places in internet, or just
226   extract it from any regular .jpg image...)
227
228   Could be variable, but until it's not needed it they are just fixed to save
229   memory. Otherwise expand zr36060 structure with arrays, push the values to
230   it and initialize from there, as e.g. the linux zr36057/60 driver does it.
231   ========================================================================= */
232
233static const char zr36060_dqt[0x86] = {
234	0xff, 0xdb,		//Marker: DQT
235	0x00, 0x84,		//Length: 2*65+2
236	0x00,			//Pq,Tq first table
237	0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
238	0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
239	0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
240	0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
241	0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
242	0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
243	0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
244	0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
245	0x01,			//Pq,Tq second table
246	0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
247	0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
248	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
249	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
250	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
251	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
252	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
253	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
254};
255
256static const char zr36060_dht[0x1a4] = {
257	0xff, 0xc4,		//Marker: DHT
258	0x01, 0xa2,		//Length: 2*AC, 2*DC
259	0x00,			//DC first table
260	0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
261	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
262	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
263	0x01,			//DC second table
264	0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
265	0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
266	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
267	0x10,			//AC first table
268	0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
269	0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
270	0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
271	0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
272	0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
273	0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
274	0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
275	0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
276	0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
277	0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
278	0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
279	0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
280	0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
281	0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
282	0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
283	0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
284	0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
285	0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
286	0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
287	0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
288	0xF8, 0xF9, 0xFA,
289	0x11,			//AC second table
290	0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
291	0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
292	0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
293	0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
294	0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
295	0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
296	0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
297	0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
298	0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
299	0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
300	0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
301	0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
302	0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
303	0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
304	0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
305	0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
306	0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
307	0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
308	0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
309	0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
310	0xF9, 0xFA
311};
312
313/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
314#define NO_OF_COMPONENTS          0x3	//Y,U,V
315#define BASELINE_PRECISION        0x8	//MCU size (?)
316static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };	//table idx's QT
317static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };	//table idx's DC
318static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };	//table idx's AC
319
320/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
321static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
322static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
323
324/* =========================================================================
325   Local helper functions:
326
327   calculation and setup of parameter-dependent JPEG baseline segments
328   (needed for compression only)
329   ========================================================================= */
330
331/* ------------------------------------------------------------------------- */
332
333/* SOF (start of frame) segment depends on width, height and sampling ratio
334			 of each color component */
335
336static int
337zr36060_set_sof (struct zr36060 *ptr)
338{
339	char sof_data[34];	// max. size of register set
340	int i;
341
342	dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
343		ptr->width, ptr->height, NO_OF_COMPONENTS);
344	sof_data[0] = 0xff;
345	sof_data[1] = 0xc0;
346	sof_data[2] = 0x00;
347	sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
348	sof_data[4] = BASELINE_PRECISION;	// only '8' possible with zr36060
349	sof_data[5] = (ptr->height) >> 8;
350	sof_data[6] = (ptr->height) & 0xff;
351	sof_data[7] = (ptr->width) >> 8;
352	sof_data[8] = (ptr->width) & 0xff;
353	sof_data[9] = NO_OF_COMPONENTS;
354	for (i = 0; i < NO_OF_COMPONENTS; i++) {
355		sof_data[10 + (i * 3)] = i;	// index identifier
356		sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
357					 (ptr->v_samp_ratio[i]); // sampling ratios
358		sof_data[12 + (i * 3)] = zr36060_tq[i];	// Q table selection
359	}
360	return zr36060_pushit(ptr, ZR060_SOF_IDX,
361			      (3 * NO_OF_COMPONENTS) + 10, sof_data);
362}
363
364/* ------------------------------------------------------------------------- */
365
366/* SOS (start of scan) segment depends on the used scan components
367			of each color component */
368
369static int
370zr36060_set_sos (struct zr36060 *ptr)
371{
372	char sos_data[16];	// max. size of register set
373	int i;
374
375	dprintk(3, "%s: write SOS\n", ptr->name);
376	sos_data[0] = 0xff;
377	sos_data[1] = 0xda;
378	sos_data[2] = 0x00;
379	sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
380	sos_data[4] = NO_OF_COMPONENTS;
381	for (i = 0; i < NO_OF_COMPONENTS; i++) {
382		sos_data[5 + (i * 2)] = i;	// index
383		sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
384					zr36060_ta[i]; // AC/DC tbl.sel.
385	}
386	sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;	// scan start
387	sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
388	sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
389	return zr36060_pushit(ptr, ZR060_SOS_IDX,
390			      4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
391			      sos_data);
392}
393
394/* ------------------------------------------------------------------------- */
395
396/* DRI (define restart interval) */
397
398static int
399zr36060_set_dri (struct zr36060 *ptr)
400{
401	char dri_data[6];	// max. size of register set
402
403	dprintk(3, "%s: write DRI\n", ptr->name);
404	dri_data[0] = 0xff;
405	dri_data[1] = 0xdd;
406	dri_data[2] = 0x00;
407	dri_data[3] = 0x04;
408	dri_data[4] = (ptr->dri) >> 8;
409	dri_data[5] = (ptr->dri) & 0xff;
410	return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
411}
412
413/* =========================================================================
414   Setup function:
415
416   Setup compression/decompression of Zoran's JPEG processor
417   ( see also zoran 36060 manual )
418
419   ... sorry for the spaghetti code ...
420   ========================================================================= */
421static void
422zr36060_init (struct zr36060 *ptr)
423{
424	int sum = 0;
425	long bitcnt, tmp;
426
427	if (ptr->mode == CODEC_DO_COMPRESSION) {
428		dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
429
430		zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
431
432		/* 060 communicates with 067 in master mode */
433		zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
434
435		/* Compression with or without variable scale factor */
436		/*FIXME: What about ptr->bitrate_ctrl? */
437		zr36060_write(ptr, ZR060_CMR,
438			      ZR060_CMR_Comp | ZR060_CMR_Pass2 |
439			      ZR060_CMR_BRB);
440
441		/* Must be zero */
442		zr36060_write(ptr, ZR060_MBZ, 0x00);
443		zr36060_write(ptr, ZR060_TCR_HI, 0x00);
444		zr36060_write(ptr, ZR060_TCR_LO, 0x00);
445
446		/* Disable all IRQs - no DataErr means autoreset */
447		zr36060_write(ptr, ZR060_IMR, 0);
448
449		/* volume control settings */
450		zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
451		zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
452
453		zr36060_write(ptr, ZR060_AF_HI, 0xff);
454		zr36060_write(ptr, ZR060_AF_M, 0xff);
455		zr36060_write(ptr, ZR060_AF_LO, 0xff);
456
457		/* setup the variable jpeg tables */
458		sum += zr36060_set_sof(ptr);
459		sum += zr36060_set_sos(ptr);
460		sum += zr36060_set_dri(ptr);
461
462		/* setup the fixed jpeg tables - maybe variable, though -
463		 * (see table init section above) */
464		sum +=
465		    zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt),
466				   zr36060_dqt);
467		sum +=
468		    zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
469				   zr36060_dht);
470		zr36060_write(ptr, ZR060_APP_IDX, 0xff);
471		zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
472		zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
473		zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
474		sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60,
475				      ptr->app.data) + 4;
476		zr36060_write(ptr, ZR060_COM_IDX, 0xff);
477		zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
478		zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
479		zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
480		sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60,
481				      ptr->com.data) + 4;
482
483		/* setup misc. data for compression (target code sizes) */
484
485		/* size of compressed code to reach without header data */
486		sum = ptr->real_code_vol - sum;
487		bitcnt = sum << 3;	/* need the size in bits */
488
489		tmp = bitcnt >> 16;
490		dprintk(3,
491			"%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
492			ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
493		zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
494		zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
495		tmp = bitcnt & 0xffff;
496		zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
497		zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
498
499		bitcnt -= bitcnt >> 7;	// bits without stuffing
500		bitcnt -= ((bitcnt * 5) >> 6);	// bits without eob
501
502		tmp = bitcnt >> 16;
503		dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
504			ptr->name, bitcnt, tmp);
505		zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
506		zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
507		tmp = bitcnt & 0xffff;
508		zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
509		zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
510
511		/* JPEG markers to be included in the compressed stream */
512		zr36060_write(ptr, ZR060_MER,
513			      ZR060_MER_DQT | ZR060_MER_DHT |
514			      ((ptr->com.len > 0) ? ZR060_MER_Com : 0) |
515			      ((ptr->app.len > 0) ? ZR060_MER_App : 0));
516
517		/* Setup the Video Frontend */
518		/* Limit pixel range to 16..235 as per CCIR-601 */
519		zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
520
521	} else {
522		dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
523
524		zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
525
526		/* 060 communicates with 067 in master mode */
527		zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
528
529		/* Decompression */
530		zr36060_write(ptr, ZR060_CMR, 0);
531
532		/* Must be zero */
533		zr36060_write(ptr, ZR060_MBZ, 0x00);
534		zr36060_write(ptr, ZR060_TCR_HI, 0x00);
535		zr36060_write(ptr, ZR060_TCR_LO, 0x00);
536
537		/* Disable all IRQs - no DataErr means autoreset */
538		zr36060_write(ptr, ZR060_IMR, 0);
539
540		/* setup misc. data for expansion */
541		zr36060_write(ptr, ZR060_MER, 0);
542
543		/* setup the fixed jpeg tables - maybe variable, though -
544		 * (see table init section above) */
545		zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
546			       zr36060_dht);
547
548		/* Setup the Video Frontend */
549		//zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt);
550		//this doesn't seem right and doesn't work...
551		zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
552	}
553
554	/* Load the tables */
555	zr36060_write(ptr, ZR060_LOAD,
556		      ZR060_LOAD_SyncRst | ZR060_LOAD_Load);
557	zr36060_wait_end(ptr);
558	dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name,
559		ptr->status);
560
561	if (ptr->status & ZR060_CFSR_Busy) {
562		dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name);
563		return;		// something is wrong, its timed out!!!!
564	}
565}
566
567/* =========================================================================
568   CODEC API FUNCTIONS
569
570   this functions are accessed by the master via the API structure
571   ========================================================================= */
572
573/* set compression/expansion mode and launches codec -
574   this should be the last call from the master before starting processing */
575static int
576zr36060_set_mode (struct videocodec *codec,
577		  int                mode)
578{
579	struct zr36060 *ptr = (struct zr36060 *) codec->data;
580
581	dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
582
583	if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
584		return -EINVAL;
585
586	ptr->mode = mode;
587	zr36060_init(ptr);
588
589	return 0;
590}
591
592/* set picture size (norm is ignored as the codec doesn't know about it) */
593static int
594zr36060_set_video (struct videocodec   *codec,
595		   struct tvnorm       *norm,
596		   struct vfe_settings *cap,
597		   struct vfe_polarity *pol)
598{
599	struct zr36060 *ptr = (struct zr36060 *) codec->data;
600	u32 reg;
601	int size;
602
603	dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
604		cap->x, cap->y, cap->width, cap->height, cap->decimation);
605
606	/* if () return -EINVAL;
607	 * trust the master driver that it knows what it does - so
608	 * we allow invalid startx/y and norm for now ... */
609	ptr->width = cap->width / (cap->decimation & 0xff);
610	ptr->height = cap->height / (cap->decimation >> 8);
611
612	zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
613
614	/* Note that VSPol/HSPol bits in zr36060 have the opposite
615	 * meaning of their zr360x7 counterparts with the same names
616	 * N.b. for VSPol this is only true if FIVEdge = 0 (default,
617	 * left unchanged here - in accordance with datasheet).
618	*/
619	reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0)
620	    | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0)
621	    | (pol->field_pol ? ZR060_VPR_FIPol : 0)
622	    | (pol->blank_pol ? ZR060_VPR_BLPol : 0)
623	    | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0)
624	    | (pol->poe_pol ? ZR060_VPR_PoePol : 0)
625	    | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0)
626	    | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0);
627	zr36060_write(ptr, ZR060_VPR, reg);
628
629	reg = 0;
630	switch (cap->decimation & 0xff) {
631	default:
632	case 1:
633		break;
634
635	case 2:
636		reg |= ZR060_SR_HScale2;
637		break;
638
639	case 4:
640		reg |= ZR060_SR_HScale4;
641		break;
642	}
643
644	switch (cap->decimation >> 8) {
645	default:
646	case 1:
647		break;
648
649	case 2:
650		reg |= ZR060_SR_VScale;
651		break;
652	}
653	zr36060_write(ptr, ZR060_SR, reg);
654
655	zr36060_write(ptr, ZR060_BCR_Y, 0x00);
656	zr36060_write(ptr, ZR060_BCR_U, 0x80);
657	zr36060_write(ptr, ZR060_BCR_V, 0x80);
658
659	/* sync generator */
660
661	reg = norm->Ht - 1;	/* Vtotal */
662	zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
663	zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
664
665	reg = norm->Wt - 1;	/* Htotal */
666	zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
667	zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
668
669	reg = 6 - 1;		/* VsyncSize */
670	zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
671
672	//reg   = 30 - 1;               /* HsyncSize */
673///*CP*/        reg = (zr->params.norm == 1 ? 57 : 68);
674	reg = 68;
675	zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
676
677	reg = norm->VStart - 1;	/* BVstart */
678	zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
679
680	reg += norm->Ha / 2;	/* BVend */
681	zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
682	zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
683
684	reg = norm->HStart - 1;	/* BHstart */
685	zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
686
687	reg += norm->Wa;	/* BHend */
688	zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
689	zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
690
691	/* active area */
692	reg = cap->y + norm->VStart;	/* Vstart */
693	zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
694	zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
695
696	reg += cap->height;	/* Vend */
697	zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
698	zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
699
700	reg = cap->x + norm->HStart;	/* Hstart */
701	zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
702	zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
703
704	reg += cap->width;	/* Hend */
705	zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
706	zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
707
708	/* subimage area */
709	reg = norm->VStart - 4;	/* SVstart */
710	zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
711	zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
712
713	reg += norm->Ha / 2 + 8;	/* SVend */
714	zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
715	zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
716
717	reg = norm->HStart /*+ 64 */  - 4;	/* SHstart */
718	zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
719	zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
720
721	reg += norm->Wa + 8;	/* SHend */
722	zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
723	zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
724
725	size = ptr->width * ptr->height;
726	/* Target compressed field size in bits: */
727	size = size * 16;	/* uncompressed size in bits */
728	/* (Ronald) by default, quality = 100 is a compression
729	 * ratio 1:2. Setting low_bitrate (insmod option) sets
730	 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
731	 * buz can't handle more at decimation=1... Use low_bitrate if
732	 * you have a Buz, unless you know what you're doing */
733	size = size * cap->quality / (low_bitrate ? 400 : 200);
734	/* Lower limit (arbitrary, 1 KB) */
735	if (size < 8192)
736		size = 8192;
737	/* Upper limit: 7/8 of the code buffers */
738	if (size > ptr->total_code_vol * 7)
739		size = ptr->total_code_vol * 7;
740
741	ptr->real_code_vol = size >> 3;	/* in bytes */
742
743	/* the MBCVR is the *maximum* block volume, according to the
744	 * JPEG ISO specs, this shouldn't be used, since that allows
745	 * for the best encoding quality. So set it to it's max value */
746	reg = ptr->max_block_vol;
747	zr36060_write(ptr, ZR060_MBCVR, reg);
748
749	return 0;
750}
751
752/* additional control functions */
753static int
754zr36060_control (struct videocodec *codec,
755		 int                type,
756		 int                size,
757		 void              *data)
758{
759	struct zr36060 *ptr = (struct zr36060 *) codec->data;
760	int *ival = (int *) data;
761
762	dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
763		size);
764
765	switch (type) {
766	case CODEC_G_STATUS:	/* get last status */
767		if (size != sizeof(int))
768			return -EFAULT;
769		zr36060_read_status(ptr);
770		*ival = ptr->status;
771		break;
772
773	case CODEC_G_CODEC_MODE:
774		if (size != sizeof(int))
775			return -EFAULT;
776		*ival = CODEC_MODE_BJPG;
777		break;
778
779	case CODEC_S_CODEC_MODE:
780		if (size != sizeof(int))
781			return -EFAULT;
782		if (*ival != CODEC_MODE_BJPG)
783			return -EINVAL;
784		/* not needed, do nothing */
785		return 0;
786
787	case CODEC_G_VFE:
788	case CODEC_S_VFE:
789		/* not needed, do nothing */
790		return 0;
791
792	case CODEC_S_MMAP:
793		/* not available, give an error */
794		return -ENXIO;
795
796	case CODEC_G_JPEG_TDS_BYTE:	/* get target volume in byte */
797		if (size != sizeof(int))
798			return -EFAULT;
799		*ival = ptr->total_code_vol;
800		break;
801
802	case CODEC_S_JPEG_TDS_BYTE:	/* get target volume in byte */
803		if (size != sizeof(int))
804			return -EFAULT;
805		ptr->total_code_vol = *ival;
806		ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
807		break;
808
809	case CODEC_G_JPEG_SCALE:	/* get scaling factor */
810		if (size != sizeof(int))
811			return -EFAULT;
812		*ival = zr36060_read_scalefactor(ptr);
813		break;
814
815	case CODEC_S_JPEG_SCALE:	/* set scaling factor */
816		if (size != sizeof(int))
817			return -EFAULT;
818		ptr->scalefact = *ival;
819		break;
820
821	case CODEC_G_JPEG_APP_DATA: {	/* get appn marker data */
822		struct jpeg_app_marker *app = data;
823
824		if (size != sizeof(struct jpeg_app_marker))
825			return -EFAULT;
826
827		*app = ptr->app;
828		break;
829	}
830
831	case CODEC_S_JPEG_APP_DATA: {	/* set appn marker data */
832		struct jpeg_app_marker *app = data;
833
834		if (size != sizeof(struct jpeg_app_marker))
835			return -EFAULT;
836
837		ptr->app = *app;
838		break;
839	}
840
841	case CODEC_G_JPEG_COM_DATA: {	/* get comment marker data */
842		struct jpeg_com_marker *com = data;
843
844		if (size != sizeof(struct jpeg_com_marker))
845			return -EFAULT;
846
847		*com = ptr->com;
848		break;
849	}
850
851	case CODEC_S_JPEG_COM_DATA: {	/* set comment marker data */
852		struct jpeg_com_marker *com = data;
853
854		if (size != sizeof(struct jpeg_com_marker))
855			return -EFAULT;
856
857		ptr->com = *com;
858		break;
859	}
860
861	default:
862		return -EINVAL;
863	}
864
865	return size;
866}
867
868/* =========================================================================
869   Exit and unregister function:
870
871   Deinitializes Zoran's JPEG processor
872   ========================================================================= */
873
874static int
875zr36060_unset (struct videocodec *codec)
876{
877	struct zr36060 *ptr = codec->data;
878
879	if (ptr) {
880		/* do wee need some codec deinit here, too ???? */
881
882		dprintk(1, "%s: finished codec #%d\n", ptr->name,
883			ptr->num);
884		kfree(ptr);
885		codec->data = NULL;
886
887		zr36060_codecs--;
888		return 0;
889	}
890
891	return -EFAULT;
892}
893
894/* =========================================================================
895   Setup and registry function:
896
897   Initializes Zoran's JPEG processor
898
899   Also sets pixel size, average code size, mode (compr./decompr.)
900   (the given size is determined by the processor with the video interface)
901   ========================================================================= */
902
903static int
904zr36060_setup (struct videocodec *codec)
905{
906	struct zr36060 *ptr;
907	int res;
908
909	dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
910		zr36060_codecs);
911
912	if (zr36060_codecs == MAX_CODECS) {
913		dprintk(1,
914			KERN_ERR "zr36060: Can't attach more codecs!\n");
915		return -ENOSPC;
916	}
917	//mem structure init
918	codec->data = ptr = kzalloc(sizeof(struct zr36060), GFP_KERNEL);
919	if (NULL == ptr) {
920		dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n");
921		return -ENOMEM;
922	}
923
924	snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]",
925		 zr36060_codecs);
926	ptr->num = zr36060_codecs++;
927	ptr->codec = codec;
928
929	//testing
930	res = zr36060_basic_test(ptr);
931	if (res < 0) {
932		zr36060_unset(codec);
933		return res;
934	}
935	//final setup
936	memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
937	memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
938
939	ptr->bitrate_ctrl = 0;	/* 0 or 1 - fixed file size flag
940				 * (what is the difference?) */
941	ptr->mode = CODEC_DO_COMPRESSION;
942	ptr->width = 384;
943	ptr->height = 288;
944	ptr->total_code_vol = 16000;	/* CHECKME */
945	ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
946	ptr->max_block_vol = 240;	/* CHECKME, was 120 is 240 */
947	ptr->scalefact = 0x100;
948	ptr->dri = 1;		/* CHECKME, was 8 is 1 */
949
950	/* by default, no COM or APP markers - app should set those */
951	ptr->com.len = 0;
952	ptr->app.appn = 0;
953	ptr->app.len = 0;
954
955	zr36060_init(ptr);
956
957	dprintk(1, KERN_INFO "%s: codec attached and running\n",
958		ptr->name);
959
960	return 0;
961}
962
963static const struct videocodec zr36060_codec = {
964	.owner = THIS_MODULE,
965	.name = "zr36060",
966	.magic = 0L,		// magic not used
967	.flags =
968	    CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
969	    CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
970	.type = CODEC_TYPE_ZR36060,
971	.setup = zr36060_setup,	// functionality
972	.unset = zr36060_unset,
973	.set_mode = zr36060_set_mode,
974	.set_video = zr36060_set_video,
975	.control = zr36060_control,
976	// others are not used
977};
978
979/* =========================================================================
980   HOOK IN DRIVER AS KERNEL MODULE
981   ========================================================================= */
982
983static int __init
984zr36060_init_module (void)
985{
986	//dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
987	zr36060_codecs = 0;
988	return videocodec_register(&zr36060_codec);
989}
990
991static void __exit
992zr36060_cleanup_module (void)
993{
994	if (zr36060_codecs) {
995		dprintk(1,
996			"zr36060: something's wrong - %d codecs left somehow.\n",
997			zr36060_codecs);
998	}
999
1000	/* however, we can't just stay alive */
1001	videocodec_unregister(&zr36060_codec);
1002}
1003
1004module_init(zr36060_init_module);
1005module_exit(zr36060_cleanup_module);
1006
1007MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
1008MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
1009		   ZR060_VERSION);
1010MODULE_LICENSE("GPL");
1011