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