1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#define ZR050_VERSION "v0.7.1"
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/delay.h>
33
34#include <linux/types.h>
35#include <linux/wait.h>
36
37
38#include <asm/io.h>
39
40
41#include "zr36050.h"
42
43
44#include "videocodec.h"
45
46
47
48#define MAX_CODECS 20
49
50
51static int zr36050_codecs;
52
53
54static int debug;
55module_param(debug, int, 0);
56MODULE_PARM_DESC(debug, "Debug level (0-4)");
57
58#define dprintk(num, format, args...) \
59 do { \
60 if (debug >= num) \
61 printk(format, ##args); \
62 } while (0)
63
64
65
66
67
68
69
70
71static u8
72zr36050_read (struct zr36050 *ptr,
73 u16 reg)
74{
75 u8 value = 0;
76
77
78 if (ptr->codec->master_data->readreg)
79 value = (ptr->codec->master_data->readreg(ptr->codec,
80 reg)) & 0xFF;
81 else
82 dprintk(1,
83 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
84 ptr->name);
85
86 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
87 value);
88
89 return value;
90}
91
92static void
93zr36050_write (struct zr36050 *ptr,
94 u16 reg,
95 u8 value)
96{
97 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
98 reg);
99
100
101 if (ptr->codec->master_data->writereg)
102 ptr->codec->master_data->writereg(ptr->codec, reg, value);
103 else
104 dprintk(1,
105 KERN_ERR
106 "%s: invalid I/O setup, nothing written!\n",
107 ptr->name);
108}
109
110
111
112
113
114
115
116
117static u8
118zr36050_read_status1 (struct zr36050 *ptr)
119{
120 ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
121
122 zr36050_read(ptr, 0);
123 return ptr->status1;
124}
125
126
127
128
129
130
131
132
133static u16
134zr36050_read_scalefactor (struct zr36050 *ptr)
135{
136 ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
137 (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
138
139
140 zr36050_read(ptr, 0);
141 return ptr->scalefact;
142}
143
144
145
146
147
148
149
150static void
151zr36050_wait_end (struct zr36050 *ptr)
152{
153 int i = 0;
154
155 while (!(zr36050_read_status1(ptr) & 0x4)) {
156 udelay(1);
157 if (i++ > 200000) {
158 dprintk(1,
159 "%s: timeout at wait_end (last status: 0x%02x)\n",
160 ptr->name, ptr->status1);
161 break;
162 }
163 }
164}
165
166
167
168
169
170
171
172static int
173zr36050_basic_test (struct zr36050 *ptr)
174{
175 zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
176 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
177 if ((zr36050_read(ptr, ZR050_SOF_IDX) |
178 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
179 dprintk(1,
180 KERN_ERR
181 "%s: attach failed, can't connect to jpeg processor!\n",
182 ptr->name);
183 return -ENXIO;
184 }
185 zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
186 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
187 if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
188 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
189 dprintk(1,
190 KERN_ERR
191 "%s: attach failed, can't connect to jpeg processor!\n",
192 ptr->name);
193 return -ENXIO;
194 }
195
196 zr36050_wait_end(ptr);
197 if ((ptr->status1 & 0x4) == 0) {
198 dprintk(1,
199 KERN_ERR
200 "%s: attach failed, jpeg processor failed (end flag)!\n",
201 ptr->name);
202 return -EBUSY;
203 }
204
205 return 0;
206}
207
208
209
210
211
212
213
214static int
215zr36050_pushit (struct zr36050 *ptr,
216 u16 startreg,
217 u16 len,
218 const char *data)
219{
220 int i = 0;
221
222 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
223 startreg, len);
224 while (i < len) {
225 zr36050_write(ptr, startreg++, data[i++]);
226 }
227
228 return i;
229}
230
231
232
233
234
235
236
237
238
239
240
241
242static const char zr36050_dqt[0x86] = {
243 0xff, 0xdb,
244 0x00, 0x84,
245 0x00,
246 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
247 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
248 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
249 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
250 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
251 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
252 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
253 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
254 0x01,
255 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
256 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
257 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
258 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
259 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
260 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
261 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
262 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
263};
264
265static const char zr36050_dht[0x1a4] = {
266 0xff, 0xc4,
267 0x01, 0xa2,
268 0x00,
269 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
270 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
271 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
272 0x01,
273 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
274 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
275 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
276 0x10,
277 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
278 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
279 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
280 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
281 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
282 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
283 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
284 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
285 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
286 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
287 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
288 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
289 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
290 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
291 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
292 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
293 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
294 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
295 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
296 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
297 0xF8, 0xF9, 0xFA,
298 0x11,
299 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
300 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
301 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
302 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
303 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
304 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
305 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
306 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
307 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
308 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
309 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
310 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
311 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
312 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
313 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
314 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
315 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
316 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
317 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
318 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
319 0xF9, 0xFA
320};
321
322
323#define NO_OF_COMPONENTS 0x3
324#define BASELINE_PRECISION 0x8
325static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
326static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
327static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
328
329
330static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
331static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
332
333
334
335
336
337
338
339
340
341
342
343
344
345static int
346zr36050_set_sof (struct zr36050 *ptr)
347{
348 char sof_data[34];
349 int i;
350
351 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
352 ptr->width, ptr->height, NO_OF_COMPONENTS);
353 sof_data[0] = 0xff;
354 sof_data[1] = 0xc0;
355 sof_data[2] = 0x00;
356 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
357 sof_data[4] = BASELINE_PRECISION;
358 sof_data[5] = (ptr->height) >> 8;
359 sof_data[6] = (ptr->height) & 0xff;
360 sof_data[7] = (ptr->width) >> 8;
361 sof_data[8] = (ptr->width) & 0xff;
362 sof_data[9] = NO_OF_COMPONENTS;
363 for (i = 0; i < NO_OF_COMPONENTS; i++) {
364 sof_data[10 + (i * 3)] = i;
365 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]);
366 sof_data[12 + (i * 3)] = zr36050_tq[i];
367 }
368 return zr36050_pushit(ptr, ZR050_SOF_IDX,
369 (3 * NO_OF_COMPONENTS) + 10, sof_data);
370}
371
372
373
374
375
376
377static int
378zr36050_set_sos (struct zr36050 *ptr)
379{
380 char sos_data[16];
381 int i;
382
383 dprintk(3, "%s: write SOS\n", ptr->name);
384 sos_data[0] = 0xff;
385 sos_data[1] = 0xda;
386 sos_data[2] = 0x00;
387 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
388 sos_data[4] = NO_OF_COMPONENTS;
389 for (i = 0; i < NO_OF_COMPONENTS; i++) {
390 sos_data[5 + (i * 2)] = i;
391 sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i];
392 }
393 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;
394 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
395 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
396 return zr36050_pushit(ptr, ZR050_SOS1_IDX,
397 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
398 sos_data);
399}
400
401
402
403
404
405static int
406zr36050_set_dri (struct zr36050 *ptr)
407{
408 char dri_data[6];
409
410 dprintk(3, "%s: write DRI\n", ptr->name);
411 dri_data[0] = 0xff;
412 dri_data[1] = 0xdd;
413 dri_data[2] = 0x00;
414 dri_data[3] = 0x04;
415 dri_data[4] = ptr->dri >> 8;
416 dri_data[5] = ptr->dri & 0xff;
417 return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
418}
419
420
421
422
423
424
425
426
427
428static void
429zr36050_init (struct zr36050 *ptr)
430{
431 int sum = 0;
432 long bitcnt, tmp;
433
434 if (ptr->mode == CODEC_DO_COMPRESSION) {
435 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
436
437
438 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
439
440
441 zr36050_write(ptr, ZR050_MODE,
442 ZR050_MO_COMP | ZR050_MO_TLM);
443 zr36050_write(ptr, ZR050_OPTIONS, 0);
444
445
446 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
447 zr36050_write(ptr, ZR050_INT_REQ_1, 3);
448
449
450
451 zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
452 zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
453
454 zr36050_write(ptr, ZR050_AF_HI, 0xff);
455 zr36050_write(ptr, ZR050_AF_M, 0xff);
456 zr36050_write(ptr, ZR050_AF_LO, 0xff);
457
458
459 sum += zr36050_set_sof(ptr);
460 sum += zr36050_set_sos(ptr);
461 sum += zr36050_set_dri(ptr);
462
463
464
465 dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
466 sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
467 sizeof(zr36050_dqt), zr36050_dqt);
468 sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
469 sizeof(zr36050_dht), zr36050_dht);
470 zr36050_write(ptr, ZR050_APP_IDX, 0xff);
471 zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
472 zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
473 zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
474 sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
475 ptr->app.data) + 4;
476 zr36050_write(ptr, ZR050_COM_IDX, 0xff);
477 zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
478 zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
479 zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
480 sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
481 ptr->com.data) + 4;
482
483
484 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
485
486 zr36050_write(ptr, ZR050_GO, 1);
487 zr36050_wait_end(ptr);
488 dprintk(2, "%s: Status after table preload: 0x%02x\n",
489 ptr->name, ptr->status1);
490
491 if ((ptr->status1 & 0x4) == 0) {
492 dprintk(1, KERN_ERR "%s: init aborted!\n",
493 ptr->name);
494 return;
495 }
496
497
498
499
500 sum = ptr->real_code_vol - sum;
501 bitcnt = sum << 3;
502
503 tmp = bitcnt >> 16;
504 dprintk(3,
505 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
506 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
507 zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
508 zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
509 tmp = bitcnt & 0xffff;
510 zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
511 zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
512
513 bitcnt -= bitcnt >> 7;
514 bitcnt -= ((bitcnt * 5) >> 6);
515
516 tmp = bitcnt >> 16;
517 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
518 ptr->name, bitcnt, tmp);
519 zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
520 zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
521 tmp = bitcnt & 0xffff;
522 zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
523 zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
524
525
526 zr36050_write(ptr, ZR050_MODE,
527 ZR050_MO_COMP | ZR050_MO_PASS2 |
528 (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
529
530
531 zr36050_write(ptr, ZR050_MARKERS_EN,
532 ZR050_ME_DQT | ZR050_ME_DHT |
533 ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
534 ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
535 } else {
536 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
537
538
539 zr36050_write(ptr, ZR050_HARDWARE,
540 ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
541
542
543 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
544
545
546 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
547 zr36050_write(ptr, ZR050_INT_REQ_1, 3);
548
549 dprintk(3, "%s: write DHT\n", ptr->name);
550 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
551 zr36050_dht);
552
553
554 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
555
556 zr36050_write(ptr, ZR050_GO, 1);
557 zr36050_wait_end(ptr);
558 dprintk(2, "%s: Status after table preload: 0x%02x\n",
559 ptr->name, ptr->status1);
560
561 if ((ptr->status1 & 0x4) == 0) {
562 dprintk(1, KERN_ERR "%s: init aborted!\n",
563 ptr->name);
564 return;
565 }
566
567
568 zr36050_write(ptr, ZR050_MODE, 0);
569 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
570 }
571
572
573 zr36050_read(ptr, 0);
574}
575
576
577
578
579
580
581
582
583
584static int
585zr36050_set_mode (struct videocodec *codec,
586 int mode)
587{
588 struct zr36050 *ptr = (struct zr36050 *) codec->data;
589
590 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
591
592 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
593 return -EINVAL;
594
595 ptr->mode = mode;
596 zr36050_init(ptr);
597
598 return 0;
599}
600
601
602static int
603zr36050_set_video (struct videocodec *codec,
604 struct tvnorm *norm,
605 struct vfe_settings *cap,
606 struct vfe_polarity *pol)
607{
608 struct zr36050 *ptr = (struct zr36050 *) codec->data;
609 int size;
610
611 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
612 ptr->name, norm->HStart, norm->VStart,
613 cap->x, cap->y, cap->width, cap->height,
614 cap->decimation, cap->quality);
615
616
617
618 ptr->width = cap->width / (cap->decimation & 0xff);
619 ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
620
621
622 size = ptr->width * ptr->height;
623 size *= 16;
624
625 size = size * cap->quality / 200;
626
627
628 if (size < 8192)
629 size = 8192;
630
631 if (size > ptr->total_code_vol * 7)
632 size = ptr->total_code_vol * 7;
633
634 ptr->real_code_vol = size >> 3;
635
636
637
638 zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
639
640 return 0;
641}
642
643
644static int
645zr36050_control (struct videocodec *codec,
646 int type,
647 int size,
648 void *data)
649{
650 struct zr36050 *ptr = (struct zr36050 *) codec->data;
651 int *ival = (int *) data;
652
653 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
654 size);
655
656 switch (type) {
657 case CODEC_G_STATUS:
658 if (size != sizeof(int))
659 return -EFAULT;
660 zr36050_read_status1(ptr);
661 *ival = ptr->status1;
662 break;
663
664 case CODEC_G_CODEC_MODE:
665 if (size != sizeof(int))
666 return -EFAULT;
667 *ival = CODEC_MODE_BJPG;
668 break;
669
670 case CODEC_S_CODEC_MODE:
671 if (size != sizeof(int))
672 return -EFAULT;
673 if (*ival != CODEC_MODE_BJPG)
674 return -EINVAL;
675
676 return 0;
677
678 case CODEC_G_VFE:
679 case CODEC_S_VFE:
680
681 return 0;
682
683 case CODEC_S_MMAP:
684
685 return -ENXIO;
686
687 case CODEC_G_JPEG_TDS_BYTE:
688 if (size != sizeof(int))
689 return -EFAULT;
690 *ival = ptr->total_code_vol;
691 break;
692
693 case CODEC_S_JPEG_TDS_BYTE:
694 if (size != sizeof(int))
695 return -EFAULT;
696 ptr->total_code_vol = *ival;
697
698
699 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
700 break;
701
702 case CODEC_G_JPEG_SCALE:
703 if (size != sizeof(int))
704 return -EFAULT;
705 *ival = zr36050_read_scalefactor(ptr);
706 break;
707
708 case CODEC_S_JPEG_SCALE:
709 if (size != sizeof(int))
710 return -EFAULT;
711 ptr->scalefact = *ival;
712 break;
713
714 case CODEC_G_JPEG_APP_DATA: {
715 struct jpeg_app_marker *app = data;
716
717 if (size != sizeof(struct jpeg_app_marker))
718 return -EFAULT;
719
720 *app = ptr->app;
721 break;
722 }
723
724 case CODEC_S_JPEG_APP_DATA: {
725 struct jpeg_app_marker *app = data;
726
727 if (size != sizeof(struct jpeg_app_marker))
728 return -EFAULT;
729
730 ptr->app = *app;
731 break;
732 }
733
734 case CODEC_G_JPEG_COM_DATA: {
735 struct jpeg_com_marker *com = data;
736
737 if (size != sizeof(struct jpeg_com_marker))
738 return -EFAULT;
739
740 *com = ptr->com;
741 break;
742 }
743
744 case CODEC_S_JPEG_COM_DATA: {
745 struct jpeg_com_marker *com = data;
746
747 if (size != sizeof(struct jpeg_com_marker))
748 return -EFAULT;
749
750 ptr->com = *com;
751 break;
752 }
753
754 default:
755 return -EINVAL;
756 }
757
758 return size;
759}
760
761
762
763
764
765
766
767static int
768zr36050_unset (struct videocodec *codec)
769{
770 struct zr36050 *ptr = codec->data;
771
772 if (ptr) {
773
774
775 dprintk(1, "%s: finished codec #%d\n", ptr->name,
776 ptr->num);
777 kfree(ptr);
778 codec->data = NULL;
779
780 zr36050_codecs--;
781 return 0;
782 }
783
784 return -EFAULT;
785}
786
787
788
789
790
791
792
793
794
795
796static int
797zr36050_setup (struct videocodec *codec)
798{
799 struct zr36050 *ptr;
800 int res;
801
802 dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
803 zr36050_codecs);
804
805 if (zr36050_codecs == MAX_CODECS) {
806 dprintk(1,
807 KERN_ERR "zr36050: Can't attach more codecs!\n");
808 return -ENOSPC;
809 }
810
811 codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL);
812 if (NULL == ptr) {
813 dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
814 return -ENOMEM;
815 }
816
817 snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
818 zr36050_codecs);
819 ptr->num = zr36050_codecs++;
820 ptr->codec = codec;
821
822
823 res = zr36050_basic_test(ptr);
824 if (res < 0) {
825 zr36050_unset(codec);
826 return res;
827 }
828
829 memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
830 memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
831
832 ptr->bitrate_ctrl = 0;
833
834 ptr->mode = CODEC_DO_COMPRESSION;
835 ptr->width = 384;
836 ptr->height = 288;
837 ptr->total_code_vol = 16000;
838 ptr->max_block_vol = 240;
839 ptr->scalefact = 0x100;
840 ptr->dri = 1;
841
842
843 ptr->app.appn = 0;
844 ptr->app.len = 0;
845 ptr->com.len = 0;
846
847 zr36050_init(ptr);
848
849 dprintk(1, KERN_INFO "%s: codec attached and running\n",
850 ptr->name);
851
852 return 0;
853}
854
855static const struct videocodec zr36050_codec = {
856 .owner = THIS_MODULE,
857 .name = "zr36050",
858 .magic = 0L,
859 .flags =
860 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
861 CODEC_FLAG_DECODER,
862 .type = CODEC_TYPE_ZR36050,
863 .setup = zr36050_setup,
864 .unset = zr36050_unset,
865 .set_mode = zr36050_set_mode,
866 .set_video = zr36050_set_video,
867 .control = zr36050_control,
868
869};
870
871
872
873
874
875static int __init
876zr36050_init_module (void)
877{
878
879 zr36050_codecs = 0;
880 return videocodec_register(&zr36050_codec);
881}
882
883static void __exit
884zr36050_cleanup_module (void)
885{
886 if (zr36050_codecs) {
887 dprintk(1,
888 "zr36050: something's wrong - %d codecs left somehow.\n",
889 zr36050_codecs);
890 }
891 videocodec_unregister(&zr36050_codec);
892}
893
894module_init(zr36050_init_module);
895module_exit(zr36050_cleanup_module);
896
897MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
898MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
899 ZR050_VERSION);
900MODULE_LICENSE("GPL");
901