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 */
32static 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 */
41static 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
57static 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 */
72static 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 */
81static 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
97static 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
118static 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
154static 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
178static 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
201static 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 (?)
261static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };	//table idx's QT
262static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };	//table idx's DC
263static 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) */
266static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
267static 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 */
282static 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
317static 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
345static 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 */
368static 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 */
526static 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) */
543static 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 */
586static 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
700static 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
729static 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
787static 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
804int zr36050_init_module(void)
805{
806	zr36050_codecs = 0;
807	return videocodec_register(&zr36050_codec);
808}
809
810void 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