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