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

source code of linux/drivers/media/pci/zoran/zr36050.c