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