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