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