1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2005-2006 Micronas USA Inc.
4 */
5
6/*
7 * This file contains code to generate a firmware image for the GO7007SB
8 * encoder. Much of the firmware is read verbatim from a file, but some of
9 * it concerning bitrate control and other things that can be configured at
10 * run-time are generated dynamically. Note that the format headers
11 * generated here do not affect the functioning of the encoder; they are
12 * merely parroted back to the host at the start of each frame.
13 */
14
15#include <linux/module.h>
16#include <linux/time.h>
17#include <linux/mm.h>
18#include <linux/device.h>
19#include <linux/i2c.h>
20#include <linux/firmware.h>
21#include <linux/slab.h>
22#include <asm/byteorder.h>
23
24#include "go7007-priv.h"
25
26#define GO7007_FW_NAME "go7007/go7007tv.bin"
27
28/* Constants used in the source firmware image to describe code segments */
29
30#define FLAG_MODE_MJPEG (1)
31#define FLAG_MODE_MPEG1 (1<<1)
32#define FLAG_MODE_MPEG2 (1<<2)
33#define FLAG_MODE_MPEG4 (1<<3)
34#define FLAG_MODE_H263 (1<<4)
35#define FLAG_MODE_ALL (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
36 FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
37 FLAG_MODE_H263)
38#define FLAG_SPECIAL (1<<8)
39
40#define SPECIAL_FRM_HEAD 0
41#define SPECIAL_BRC_CTRL 1
42#define SPECIAL_CONFIG 2
43#define SPECIAL_SEQHEAD 3
44#define SPECIAL_AV_SYNC 4
45#define SPECIAL_FINAL 5
46#define SPECIAL_AUDIO 6
47#define SPECIAL_MODET 7
48
49/* Little data class for creating MPEG headers bit-by-bit */
50
51struct code_gen {
52 unsigned char *p; /* destination */
53 u32 a; /* collects bits at the top of the variable */
54 int b; /* bit position of most recently-written bit */
55 int len; /* written out so far */
56};
57
58#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
59
60#define CODE_ADD(name, val, length) do { \
61 name.b -= (length); \
62 name.a |= (val) << name.b; \
63 while (name.b <= 24) { \
64 *name.p = name.a >> 24; \
65 ++name.p; \
66 name.a <<= 8; \
67 name.b += 8; \
68 name.len += 8; \
69 } \
70} while (0)
71
72#define CODE_LENGTH(name) (name.len + (32 - name.b))
73
74/* Tables for creating the bitrate control data */
75
76static const s16 converge_speed_ip[101] = {
77 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
78 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
79 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
80 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
81 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
82 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
83 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
84 9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
85 19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
86 41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
87 100
88};
89
90static const s16 converge_speed_ipb[101] = {
91 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
92 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
93 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
94 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
95 6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
96 9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
97 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
98 28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
99 57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
100 125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
101 300
102};
103
104static const s16 LAMBDA_table[4][101] = {
105 { 16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
106 19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
107 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
108 27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
109 32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
110 39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
111 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
112 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
113 67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
114 80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
115 96
116 },
117 {
118 20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
119 23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
120 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
121 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
122 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
123 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
124 58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
125 70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
126 83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
127 100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
128 120
129 },
130 {
131 24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
132 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
133 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
134 41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
135 49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
136 58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
137 70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
138 84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
139 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
140 120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
141 144
142 },
143 {
144 32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
145 38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
146 45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
147 54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
148 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
149 78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
150 93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
151 112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
152 134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
153 160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
154 192
155 }
156};
157
158/* MPEG blank frame generation tables */
159
160enum mpeg_frame_type {
161 PFRAME,
162 BFRAME_PRE,
163 BFRAME_POST,
164 BFRAME_BIDIR,
165 BFRAME_EMPTY
166};
167
168static const u32 addrinctab[33][2] = {
169 { 0x01, 1 }, { 0x03, 3 }, { 0x02, 3 }, { 0x03, 4 },
170 { 0x02, 4 }, { 0x03, 5 }, { 0x02, 5 }, { 0x07, 7 },
171 { 0x06, 7 }, { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 },
172 { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 }, { 0x17, 10 },
173 { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 },
174 { 0x12, 10 }, { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 },
175 { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 },
176 { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 },
177 { 0x18, 11 }
178};
179
180/* Standard JPEG tables */
181
182static const u8 default_intra_quant_table[] = {
183 8, 16, 19, 22, 26, 27, 29, 34,
184 16, 16, 22, 24, 27, 29, 34, 37,
185 19, 22, 26, 27, 29, 34, 34, 38,
186 22, 22, 26, 27, 29, 34, 37, 40,
187 22, 26, 27, 29, 32, 35, 40, 48,
188 26, 27, 29, 32, 35, 40, 48, 58,
189 26, 27, 29, 34, 38, 46, 56, 69,
190 27, 29, 35, 38, 46, 56, 69, 83
191};
192
193static const u8 bits_dc_luminance[] = {
194 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
195};
196
197static const u8 val_dc_luminance[] = {
198 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
199};
200
201static const u8 bits_dc_chrominance[] = {
202 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
203};
204
205static const u8 val_dc_chrominance[] = {
206 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
207};
208
209static const u8 bits_ac_luminance[] = {
210 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
211};
212
213static const u8 val_ac_luminance[] = {
214 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
215 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
216 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
217 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
218 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
219 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
220 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
221 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
222 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
223 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
224 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
225 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
226 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
227 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
228 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
229 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
230 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
231 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
232 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
233 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
234 0xf9, 0xfa
235};
236
237static const u8 bits_ac_chrominance[] = {
238 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
239};
240
241static const u8 val_ac_chrominance[] = {
242 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
243 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
244 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
245 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
246 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
247 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
248 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
249 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
250 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
251 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
252 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
253 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
254 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
255 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
256 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
257 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
258 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
259 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
260 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
261 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
262 0xf9, 0xfa
263};
264
265/* Zig-zag mapping for quant table
266 *
267 * OK, let's do this mapping on the actual table above so it doesn't have
268 * to be done on the fly.
269 */
270static const int zz[64] = {
271 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
272 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
273 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
274 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
275};
276
277static int copy_packages(__le16 *dest, u16 *src, int pkg_cnt, int space)
278{
279 int i, cnt = pkg_cnt * 32;
280
281 if (space < cnt)
282 return -1;
283
284 for (i = 0; i < cnt; ++i)
285 dest[i] = cpu_to_le16p(p: src + i);
286
287 return cnt;
288}
289
290static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
291{
292 int i, p = 0;
293
294 buf[p++] = 0xff;
295 buf[p++] = 0xd8;
296 buf[p++] = 0xff;
297 buf[p++] = 0xdb;
298 buf[p++] = 0;
299 buf[p++] = 2 + 65;
300 buf[p++] = 0;
301 buf[p++] = default_intra_quant_table[0];
302 for (i = 1; i < 64; ++i)
303 /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
304 buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
305 buf[p++] = 0xff;
306 buf[p++] = 0xc0;
307 buf[p++] = 0;
308 buf[p++] = 17;
309 buf[p++] = 8;
310 buf[p++] = go->height >> 8;
311 buf[p++] = go->height & 0xff;
312 buf[p++] = go->width >> 8;
313 buf[p++] = go->width & 0xff;
314 buf[p++] = 3;
315 buf[p++] = 1;
316 buf[p++] = 0x22;
317 buf[p++] = 0;
318 buf[p++] = 2;
319 buf[p++] = 0x11;
320 buf[p++] = 0;
321 buf[p++] = 3;
322 buf[p++] = 0x11;
323 buf[p++] = 0;
324 buf[p++] = 0xff;
325 buf[p++] = 0xc4;
326 buf[p++] = 418 >> 8;
327 buf[p++] = 418 & 0xff;
328 buf[p++] = 0x00;
329 memcpy(buf + p, bits_dc_luminance + 1, 16);
330 p += 16;
331 memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
332 p += sizeof(val_dc_luminance);
333 buf[p++] = 0x01;
334 memcpy(buf + p, bits_dc_chrominance + 1, 16);
335 p += 16;
336 memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
337 p += sizeof(val_dc_chrominance);
338 buf[p++] = 0x10;
339 memcpy(buf + p, bits_ac_luminance + 1, 16);
340 p += 16;
341 memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
342 p += sizeof(val_ac_luminance);
343 buf[p++] = 0x11;
344 memcpy(buf + p, bits_ac_chrominance + 1, 16);
345 p += 16;
346 memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
347 p += sizeof(val_ac_chrominance);
348 buf[p++] = 0xff;
349 buf[p++] = 0xda;
350 buf[p++] = 0;
351 buf[p++] = 12;
352 buf[p++] = 3;
353 buf[p++] = 1;
354 buf[p++] = 0x00;
355 buf[p++] = 2;
356 buf[p++] = 0x11;
357 buf[p++] = 3;
358 buf[p++] = 0x11;
359 buf[p++] = 0;
360 buf[p++] = 63;
361 buf[p++] = 0;
362 return p;
363}
364
365static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space)
366{
367 u8 *buf;
368 u16 mem = 0x3e00;
369 unsigned int addr = 0x19;
370 int size = 0, i, off = 0, chunk;
371
372 buf = kzalloc(size: 4096, GFP_KERNEL);
373 if (buf == NULL)
374 return -ENOMEM;
375
376 for (i = 1; i < 32; ++i) {
377 mjpeg_frame_header(go, buf: buf + size, q: i);
378 size += 80;
379 }
380 chunk = mjpeg_frame_header(go, buf: buf + size, q: 1);
381 memmove(buf + size, buf + size + 80, chunk - 80);
382 size += chunk - 80;
383
384 for (i = 0; i < size; i += chunk * 2) {
385 if (space - off < 32) {
386 off = -1;
387 goto done;
388 }
389
390 code[off + 1] = __cpu_to_le16(0x8000 | mem);
391
392 chunk = 28;
393 if (mem + chunk > 0x4000)
394 chunk = 0x4000 - mem;
395 if (i + 2 * chunk > size)
396 chunk = (size - i) / 2;
397
398 if (chunk < 28) {
399 code[off] = __cpu_to_le16(0x4000 | chunk);
400 code[off + 31] = __cpu_to_le16(addr++);
401 mem = 0x3e00;
402 } else {
403 code[off] = __cpu_to_le16(0x1000 | 28);
404 code[off + 31] = 0;
405 mem += 28;
406 }
407
408 memcpy(&code[off + 2], buf + i, chunk * 2);
409 off += 32;
410 }
411done:
412 kfree(objp: buf);
413 return off;
414}
415
416static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
417 int modulo, int pict_struct, enum mpeg_frame_type frame)
418{
419 int i, j, mb_code, mb_len;
420 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
421 CODE_GEN(c, buf + 6);
422
423 switch (frame) {
424 case PFRAME:
425 mb_code = 0x1;
426 mb_len = 3;
427 break;
428 case BFRAME_PRE:
429 mb_code = 0x2;
430 mb_len = 4;
431 break;
432 case BFRAME_POST:
433 mb_code = 0x2;
434 mb_len = 3;
435 break;
436 case BFRAME_BIDIR:
437 mb_code = 0x2;
438 mb_len = 2;
439 break;
440 default: /* keep the compiler happy */
441 mb_code = mb_len = 0;
442 break;
443 }
444
445 CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
446 CODE_ADD(c, 0xffff, 16);
447 CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
448 if (frame != PFRAME)
449 CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
450 else
451 CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
452 CODE_ADD(c, 0, 3); /* What is this?? */
453 /* Byte-align with zeros */
454 j = 8 - (CODE_LENGTH(c) % 8);
455 if (j != 8)
456 CODE_ADD(c, 0, j);
457
458 if (go->format == V4L2_PIX_FMT_MPEG2) {
459 CODE_ADD(c, 0x1, 24);
460 CODE_ADD(c, 0xb5, 8);
461 CODE_ADD(c, 0x844, 12);
462 CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
463 if (go->interlace_coding) {
464 CODE_ADD(c, pict_struct, 4);
465 if (go->dvd_mode)
466 CODE_ADD(c, 0x000, 11);
467 else
468 CODE_ADD(c, 0x200, 11);
469 } else {
470 CODE_ADD(c, 0x3, 4);
471 CODE_ADD(c, 0x20c, 11);
472 }
473 /* Byte-align with zeros */
474 j = 8 - (CODE_LENGTH(c) % 8);
475 if (j != 8)
476 CODE_ADD(c, 0, j);
477 }
478
479 for (i = 0; i < rows; ++i) {
480 CODE_ADD(c, 1, 24);
481 CODE_ADD(c, i + 1, 8);
482 CODE_ADD(c, 0x2, 6);
483 CODE_ADD(c, 0x1, 1);
484 CODE_ADD(c, mb_code, mb_len);
485 if (go->interlace_coding) {
486 CODE_ADD(c, 0x1, 2);
487 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
488 }
489 if (frame == BFRAME_BIDIR) {
490 CODE_ADD(c, 0x3, 2);
491 if (go->interlace_coding)
492 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
493 }
494 CODE_ADD(c, 0x3, 2);
495 for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
496 CODE_ADD(c, 0x8, 11);
497 CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
498 CODE_ADD(c, mb_code, mb_len);
499 if (go->interlace_coding) {
500 CODE_ADD(c, 0x1, 2);
501 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
502 }
503 if (frame == BFRAME_BIDIR) {
504 CODE_ADD(c, 0x3, 2);
505 if (go->interlace_coding)
506 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
507 }
508 CODE_ADD(c, 0x3, 2);
509
510 /* Byte-align with zeros */
511 j = 8 - (CODE_LENGTH(c) % 8);
512 if (j != 8)
513 CODE_ADD(c, 0, j);
514 }
515
516 i = CODE_LENGTH(c) + 4 * 8;
517 buf[2] = 0x00;
518 buf[3] = 0x00;
519 buf[4] = 0x01;
520 buf[5] = 0x00;
521 return i;
522}
523
524static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
525{
526 int i, aspect_ratio, picture_rate;
527 CODE_GEN(c, buf + 6);
528
529 if (go->format == V4L2_PIX_FMT_MPEG1) {
530 switch (go->aspect_ratio) {
531 case GO7007_RATIO_4_3:
532 aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
533 break;
534 case GO7007_RATIO_16_9:
535 aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
536 break;
537 default:
538 aspect_ratio = 1;
539 break;
540 }
541 } else {
542 switch (go->aspect_ratio) {
543 case GO7007_RATIO_4_3:
544 aspect_ratio = 2;
545 break;
546 case GO7007_RATIO_16_9:
547 aspect_ratio = 3;
548 break;
549 default:
550 aspect_ratio = 1;
551 break;
552 }
553 }
554 switch (go->sensor_framerate) {
555 case 24000:
556 picture_rate = 1;
557 break;
558 case 24024:
559 picture_rate = 2;
560 break;
561 case 25025:
562 picture_rate = go->interlace_coding ? 6 : 3;
563 break;
564 case 30000:
565 picture_rate = go->interlace_coding ? 7 : 4;
566 break;
567 case 30030:
568 picture_rate = go->interlace_coding ? 8 : 5;
569 break;
570 default:
571 picture_rate = 5; /* 30 fps seems like a reasonable default */
572 break;
573 }
574
575 CODE_ADD(c, go->width, 12);
576 CODE_ADD(c, go->height, 12);
577 CODE_ADD(c, aspect_ratio, 4);
578 CODE_ADD(c, picture_rate, 4);
579 CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 20000 : 0x3ffff, 18);
580 CODE_ADD(c, 1, 1);
581 CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 112 : 20, 10);
582 CODE_ADD(c, 0, 3);
583
584 /* Byte-align with zeros */
585 i = 8 - (CODE_LENGTH(c) % 8);
586 if (i != 8)
587 CODE_ADD(c, 0, i);
588
589 if (go->format == V4L2_PIX_FMT_MPEG2) {
590 CODE_ADD(c, 0x1, 24);
591 CODE_ADD(c, 0xb5, 8);
592 CODE_ADD(c, 0x148, 12);
593 if (go->interlace_coding)
594 CODE_ADD(c, 0x20001, 20);
595 else
596 CODE_ADD(c, 0xa0001, 20);
597 CODE_ADD(c, 0, 16);
598
599 /* Byte-align with zeros */
600 i = 8 - (CODE_LENGTH(c) % 8);
601 if (i != 8)
602 CODE_ADD(c, 0, i);
603
604 if (ext) {
605 CODE_ADD(c, 0x1, 24);
606 CODE_ADD(c, 0xb52, 12);
607 CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
608 CODE_ADD(c, 0x105, 9);
609 CODE_ADD(c, 0x505, 16);
610 CODE_ADD(c, go->width, 14);
611 CODE_ADD(c, 1, 1);
612 CODE_ADD(c, go->height, 14);
613
614 /* Byte-align with zeros */
615 i = 8 - (CODE_LENGTH(c) % 8);
616 if (i != 8)
617 CODE_ADD(c, 0, i);
618 }
619 }
620
621 i = CODE_LENGTH(c) + 4 * 8;
622 buf[0] = i & 0xff;
623 buf[1] = i >> 8;
624 buf[2] = 0x00;
625 buf[3] = 0x00;
626 buf[4] = 0x01;
627 buf[5] = 0xb3;
628 return i;
629}
630
631static int gen_mpeg1hdr_to_package(struct go7007 *go,
632 __le16 *code, int space, int *framelen)
633{
634 u8 *buf;
635 u16 mem = 0x3e00;
636 unsigned int addr = 0x19;
637 int i, off = 0, chunk;
638
639 buf = kzalloc(size: 5120, GFP_KERNEL);
640 if (buf == NULL)
641 return -ENOMEM;
642
643 framelen[0] = mpeg1_frame_header(go, buf, modulo: 0, pict_struct: 1, frame: PFRAME);
644 if (go->interlace_coding)
645 framelen[0] += mpeg1_frame_header(go, buf: buf + framelen[0] / 8,
646 modulo: 0, pict_struct: 2, frame: PFRAME);
647 buf[0] = framelen[0] & 0xff;
648 buf[1] = framelen[0] >> 8;
649 i = 368;
650 framelen[1] = mpeg1_frame_header(go, buf: buf + i, modulo: 0, pict_struct: 1, frame: BFRAME_PRE);
651 if (go->interlace_coding)
652 framelen[1] += mpeg1_frame_header(go, buf: buf + i + framelen[1] / 8,
653 modulo: 0, pict_struct: 2, frame: BFRAME_PRE);
654 buf[i] = framelen[1] & 0xff;
655 buf[i + 1] = framelen[1] >> 8;
656 i += 1632;
657 framelen[2] = mpeg1_frame_header(go, buf: buf + i, modulo: 0, pict_struct: 1, frame: BFRAME_POST);
658 if (go->interlace_coding)
659 framelen[2] += mpeg1_frame_header(go, buf: buf + i + framelen[2] / 8,
660 modulo: 0, pict_struct: 2, frame: BFRAME_POST);
661 buf[i] = framelen[2] & 0xff;
662 buf[i + 1] = framelen[2] >> 8;
663 i += 1432;
664 framelen[3] = mpeg1_frame_header(go, buf: buf + i, modulo: 0, pict_struct: 1, frame: BFRAME_BIDIR);
665 if (go->interlace_coding)
666 framelen[3] += mpeg1_frame_header(go, buf: buf + i + framelen[3] / 8,
667 modulo: 0, pict_struct: 2, frame: BFRAME_BIDIR);
668 buf[i] = framelen[3] & 0xff;
669 buf[i + 1] = framelen[3] >> 8;
670 i += 1632 + 16;
671 mpeg1_sequence_header(go, buf: buf + i, ext: 0);
672 i += 40;
673 for (i = 0; i < 5120; i += chunk * 2) {
674 if (space - off < 32) {
675 off = -1;
676 goto done;
677 }
678
679 code[off + 1] = __cpu_to_le16(0x8000 | mem);
680
681 chunk = 28;
682 if (mem + chunk > 0x4000)
683 chunk = 0x4000 - mem;
684 if (i + 2 * chunk > 5120)
685 chunk = (5120 - i) / 2;
686
687 if (chunk < 28) {
688 code[off] = __cpu_to_le16(0x4000 | chunk);
689 code[off + 31] = __cpu_to_le16(addr);
690 if (mem + chunk == 0x4000) {
691 mem = 0x3e00;
692 ++addr;
693 }
694 } else {
695 code[off] = __cpu_to_le16(0x1000 | 28);
696 code[off + 31] = 0;
697 mem += 28;
698 }
699
700 memcpy(&code[off + 2], buf + i, chunk * 2);
701 off += 32;
702 }
703done:
704 kfree(objp: buf);
705 return off;
706}
707
708static int vti_bitlen(struct go7007 *go)
709{
710 unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
711
712 for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
713 ;
714 return i + 1;
715}
716
717static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
718 int modulo, enum mpeg_frame_type frame)
719{
720 int i;
721 CODE_GEN(c, buf + 6);
722 int mb_count = (go->width >> 4) * (go->height >> 4);
723
724 CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
725 if (modulo)
726 CODE_ADD(c, 0x1, 1);
727 CODE_ADD(c, 0x1, 2);
728 CODE_ADD(c, 0, vti_bitlen(go));
729 CODE_ADD(c, 0x3, 2);
730 if (frame == PFRAME)
731 CODE_ADD(c, 0, 1);
732 CODE_ADD(c, 0xc, 11);
733 if (frame != PFRAME)
734 CODE_ADD(c, 0x4, 3);
735 if (frame != BFRAME_EMPTY) {
736 for (i = 0; i < mb_count; ++i) {
737 switch (frame) {
738 case PFRAME:
739 CODE_ADD(c, 0x1, 1);
740 break;
741 case BFRAME_PRE:
742 CODE_ADD(c, 0x47, 8);
743 break;
744 case BFRAME_POST:
745 CODE_ADD(c, 0x27, 7);
746 break;
747 case BFRAME_BIDIR:
748 CODE_ADD(c, 0x5f, 8);
749 break;
750 case BFRAME_EMPTY: /* keep compiler quiet */
751 break;
752 }
753 }
754 }
755
756 /* Byte-align with a zero followed by ones */
757 i = 8 - (CODE_LENGTH(c) % 8);
758 CODE_ADD(c, 0, 1);
759 CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
760
761 i = CODE_LENGTH(c) + 4 * 8;
762 buf[0] = i & 0xff;
763 buf[1] = i >> 8;
764 buf[2] = 0x00;
765 buf[3] = 0x00;
766 buf[4] = 0x01;
767 buf[5] = 0xb6;
768 return i;
769}
770
771static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
772{
773 const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
774 0x00, 0x00, 0x01, 0xb5, 0x09,
775 0x00, 0x00, 0x01, 0x00,
776 0x00, 0x00, 0x01, 0x20, };
777 int i, aspect_ratio;
778 int fps = go->sensor_framerate / go->fps_scale;
779 CODE_GEN(c, buf + 2 + sizeof(head));
780
781 switch (go->aspect_ratio) {
782 case GO7007_RATIO_4_3:
783 aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
784 break;
785 case GO7007_RATIO_16_9:
786 aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
787 break;
788 default:
789 aspect_ratio = 1;
790 break;
791 }
792
793 memcpy(buf + 2, head, sizeof(head));
794 CODE_ADD(c, 0x191, 17);
795 CODE_ADD(c, aspect_ratio, 4);
796 CODE_ADD(c, 0x1, 4);
797 CODE_ADD(c, fps, 16);
798 CODE_ADD(c, 0x3, 2);
799 CODE_ADD(c, 1001, vti_bitlen(go));
800 CODE_ADD(c, 1, 1);
801 CODE_ADD(c, go->width, 13);
802 CODE_ADD(c, 1, 1);
803 CODE_ADD(c, go->height, 13);
804 CODE_ADD(c, 0x2830, 14);
805
806 /* Byte-align */
807 i = 8 - (CODE_LENGTH(c) % 8);
808 CODE_ADD(c, 0, 1);
809 CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
810
811 i = CODE_LENGTH(c) + sizeof(head) * 8;
812 buf[0] = i & 0xff;
813 buf[1] = i >> 8;
814 return i;
815}
816
817static int gen_mpeg4hdr_to_package(struct go7007 *go,
818 __le16 *code, int space, int *framelen)
819{
820 u8 *buf;
821 u16 mem = 0x3e00;
822 unsigned int addr = 0x19;
823 int i, off = 0, chunk;
824
825 buf = kzalloc(size: 5120, GFP_KERNEL);
826 if (buf == NULL)
827 return -ENOMEM;
828
829 framelen[0] = mpeg4_frame_header(go, buf, modulo: 0, frame: PFRAME);
830 i = 368;
831 framelen[1] = mpeg4_frame_header(go, buf: buf + i, modulo: 0, frame: BFRAME_PRE);
832 i += 1632;
833 framelen[2] = mpeg4_frame_header(go, buf: buf + i, modulo: 0, frame: BFRAME_POST);
834 i += 1432;
835 framelen[3] = mpeg4_frame_header(go, buf: buf + i, modulo: 0, frame: BFRAME_BIDIR);
836 i += 1632;
837 mpeg4_frame_header(go, buf: buf + i, modulo: 0, frame: BFRAME_EMPTY);
838 i += 16;
839 mpeg4_sequence_header(go, buf: buf + i, ext: 0);
840 i += 40;
841 for (i = 0; i < 5120; i += chunk * 2) {
842 if (space - off < 32) {
843 off = -1;
844 goto done;
845 }
846
847 code[off + 1] = __cpu_to_le16(0x8000 | mem);
848
849 chunk = 28;
850 if (mem + chunk > 0x4000)
851 chunk = 0x4000 - mem;
852 if (i + 2 * chunk > 5120)
853 chunk = (5120 - i) / 2;
854
855 if (chunk < 28) {
856 code[off] = __cpu_to_le16(0x4000 | chunk);
857 code[off + 31] = __cpu_to_le16(addr);
858 if (mem + chunk == 0x4000) {
859 mem = 0x3e00;
860 ++addr;
861 }
862 } else {
863 code[off] = __cpu_to_le16(0x1000 | 28);
864 code[off + 31] = 0;
865 mem += 28;
866 }
867
868 memcpy(&code[off + 2], buf + i, chunk * 2);
869 off += 32;
870 }
871 mem = 0x3e00;
872 addr = go->ipb ? 0x14f9 : 0x0af9;
873 memset(buf, 0, 5120);
874 framelen[4] = mpeg4_frame_header(go, buf, modulo: 1, frame: PFRAME);
875 i = 368;
876 framelen[5] = mpeg4_frame_header(go, buf: buf + i, modulo: 1, frame: BFRAME_PRE);
877 i += 1632;
878 framelen[6] = mpeg4_frame_header(go, buf: buf + i, modulo: 1, frame: BFRAME_POST);
879 i += 1432;
880 framelen[7] = mpeg4_frame_header(go, buf: buf + i, modulo: 1, frame: BFRAME_BIDIR);
881 i += 1632;
882 mpeg4_frame_header(go, buf: buf + i, modulo: 1, frame: BFRAME_EMPTY);
883 i += 16;
884 for (i = 0; i < 5120; i += chunk * 2) {
885 if (space - off < 32) {
886 off = -1;
887 goto done;
888 }
889
890 code[off + 1] = __cpu_to_le16(0x8000 | mem);
891
892 chunk = 28;
893 if (mem + chunk > 0x4000)
894 chunk = 0x4000 - mem;
895 if (i + 2 * chunk > 5120)
896 chunk = (5120 - i) / 2;
897
898 if (chunk < 28) {
899 code[off] = __cpu_to_le16(0x4000 | chunk);
900 code[off + 31] = __cpu_to_le16(addr);
901 if (mem + chunk == 0x4000) {
902 mem = 0x3e00;
903 ++addr;
904 }
905 } else {
906 code[off] = __cpu_to_le16(0x1000 | 28);
907 code[off + 31] = 0;
908 mem += 28;
909 }
910
911 memcpy(&code[off + 2], buf + i, chunk * 2);
912 off += 32;
913 }
914done:
915 kfree(objp: buf);
916 return off;
917}
918
919static int brctrl_to_package(struct go7007 *go,
920 __le16 *code, int space, int *framelen)
921{
922 int converge_speed = 0;
923 int lambda = (go->format == V4L2_PIX_FMT_MJPEG || go->dvd_mode) ?
924 100 : 0;
925 int peak_rate = 6 * go->bitrate / 5;
926 int vbv_buffer = go->format == V4L2_PIX_FMT_MJPEG ?
927 go->bitrate :
928 (go->dvd_mode ? 900000 : peak_rate);
929 int fps = go->sensor_framerate / go->fps_scale;
930 int q = 0;
931 /* Bizarre math below depends on rounding errors in division */
932 u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
933 u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
934 u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
935 u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
936 u32 cplx[] = {
937 q > 0 ? sgop_expt_addr * q :
938 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
939 q > 0 ? sgop_expt_addr * q :
940 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
941 q > 0 ? sgop_expt_addr * q :
942 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
943 q > 0 ? sgop_expt_addr * q :
944 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
945 };
946 u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
947 u16 pack[] = {
948 0x200e, 0x0000,
949 0xBF20, go->ipb ? converge_speed_ipb[converge_speed]
950 : converge_speed_ip[converge_speed],
951 0xBF21, go->ipb ? 2 : 0,
952 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
953 : 32767,
954 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767,
955 0xBF24, 32767,
956 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
957 0xBF26, sgop_expt_addr & 0x0000FFFF,
958 0xBF27, sgop_expt_addr >> 16,
959 0xBF28, sgop_peak_addr & 0x0000FFFF,
960 0xBF29, sgop_peak_addr >> 16,
961 0xBF2A, vbv_alert_addr & 0x0000FFFF,
962 0xBF2B, vbv_alert_addr >> 16,
963 0xBF2C, 0,
964 0xBF2D, 0,
965 0, 0,
966
967 0x200e, 0x0000,
968 0xBF2E, vbv_alert_addr & 0x0000FFFF,
969 0xBF2F, vbv_alert_addr >> 16,
970 0xBF30, cplx[0] & 0x0000FFFF,
971 0xBF31, cplx[0] >> 16,
972 0xBF32, cplx[1] & 0x0000FFFF,
973 0xBF33, cplx[1] >> 16,
974 0xBF34, cplx[2] & 0x0000FFFF,
975 0xBF35, cplx[2] >> 16,
976 0xBF36, cplx[3] & 0x0000FFFF,
977 0xBF37, cplx[3] >> 16,
978 0xBF38, 0,
979 0xBF39, 0,
980 0xBF3A, total_expt_addr & 0x0000FFFF,
981 0xBF3B, total_expt_addr >> 16,
982 0, 0,
983
984 0x200e, 0x0000,
985 0xBF3C, total_expt_addr & 0x0000FFFF,
986 0xBF3D, total_expt_addr >> 16,
987 0xBF3E, 0,
988 0xBF3F, 0,
989 0xBF48, 0,
990 0xBF49, 0,
991 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
992 0xBF4B, 4,
993 0xBF4C, 0,
994 0xBF4D, 0,
995 0xBF4E, 0,
996 0xBF4F, 0,
997 0xBF50, 0,
998 0xBF51, 0,
999 0, 0,
1000
1001 0x200e, 0x0000,
1002 0xBF40, sgop_expt_addr & 0x0000FFFF,
1003 0xBF41, sgop_expt_addr >> 16,
1004 0xBF42, 0,
1005 0xBF43, 0,
1006 0xBF44, 0,
1007 0xBF45, 0,
1008 0xBF46, (go->width >> 4) * (go->height >> 4),
1009 0xBF47, 0,
1010 0xBF64, 0,
1011 0xBF65, 0,
1012 0xBF18, framelen[4],
1013 0xBF19, framelen[5],
1014 0xBF1A, framelen[6],
1015 0xBF1B, framelen[7],
1016 0, 0,
1017
1018#if 0
1019 /* Remove once we don't care about matching */
1020 0x200e, 0x0000,
1021 0xBF56, 4,
1022 0xBF57, 0,
1023 0xBF58, 5,
1024 0xBF59, 0,
1025 0xBF5A, 6,
1026 0xBF5B, 0,
1027 0xBF5C, 8,
1028 0xBF5D, 0,
1029 0xBF5E, 1,
1030 0xBF5F, 0,
1031 0xBF60, 1,
1032 0xBF61, 0,
1033 0xBF62, 0,
1034 0xBF63, 0,
1035 0, 0,
1036#else
1037 0x2008, 0x0000,
1038 0xBF56, 4,
1039 0xBF57, 0,
1040 0xBF58, 5,
1041 0xBF59, 0,
1042 0xBF5A, 6,
1043 0xBF5B, 0,
1044 0xBF5C, 8,
1045 0xBF5D, 0,
1046 0, 0,
1047 0, 0,
1048 0, 0,
1049 0, 0,
1050 0, 0,
1051 0, 0,
1052 0, 0,
1053#endif
1054
1055 0x200e, 0x0000,
1056 0xBF10, 0,
1057 0xBF11, 0,
1058 0xBF12, 0,
1059 0xBF13, 0,
1060 0xBF14, 0,
1061 0xBF15, 0,
1062 0xBF16, 0,
1063 0xBF17, 0,
1064 0xBF7E, 0,
1065 0xBF7F, 1,
1066 0xBF52, framelen[0],
1067 0xBF53, framelen[1],
1068 0xBF54, framelen[2],
1069 0xBF55, framelen[3],
1070 0, 0,
1071 };
1072
1073 return copy_packages(dest: code, src: pack, pkg_cnt: 6, space);
1074}
1075
1076static int config_package(struct go7007 *go, __le16 *code, int space)
1077{
1078 int fps = go->sensor_framerate / go->fps_scale / 1000;
1079 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1080 int brc_window_size = fps;
1081 int q_min = 2, q_max = 31;
1082 int THACCoeffSet0 = 0;
1083 u16 pack[] = {
1084 0x200e, 0x0000,
1085 0xc002, 0x14b4,
1086 0xc003, 0x28b4,
1087 0xc004, 0x3c5a,
1088 0xdc05, 0x2a77,
1089 0xc6c3, go->format == V4L2_PIX_FMT_MPEG4 ? 0 :
1090 (go->format == V4L2_PIX_FMT_H263 ? 0 : 1),
1091 0xc680, go->format == V4L2_PIX_FMT_MPEG4 ? 0xf1 :
1092 (go->format == V4L2_PIX_FMT_H263 ? 0x61 :
1093 0xd3),
1094 0xc780, 0x0140,
1095 0xe009, 0x0001,
1096 0xc60f, 0x0008,
1097 0xd4ff, 0x0002,
1098 0xe403, 2340,
1099 0xe406, 75,
1100 0xd411, 0x0001,
1101 0xd410, 0xa1d6,
1102 0x0001, 0x2801,
1103
1104 0x200d, 0x0000,
1105 0xe402, 0x018b,
1106 0xe401, 0x8b01,
1107 0xd472, (go->board_info->sensor_flags &
1108 GO7007_SENSOR_TV) &&
1109 (!go->interlace_coding) ?
1110 0x01b0 : 0x0170,
1111 0xd475, (go->board_info->sensor_flags &
1112 GO7007_SENSOR_TV) &&
1113 (!go->interlace_coding) ?
1114 0x0008 : 0x0009,
1115 0xc404, go->interlace_coding ? 0x44 :
1116 (go->format == V4L2_PIX_FMT_MPEG4 ? 0x11 :
1117 (go->format == V4L2_PIX_FMT_MPEG1 ? 0x02 :
1118 (go->format == V4L2_PIX_FMT_MPEG2 ? 0x04 :
1119 (go->format == V4L2_PIX_FMT_H263 ? 0x08 :
1120 0x20)))),
1121 0xbf0a, (go->format == V4L2_PIX_FMT_MPEG4 ? 8 :
1122 (go->format == V4L2_PIX_FMT_MPEG1 ? 1 :
1123 (go->format == V4L2_PIX_FMT_MPEG2 ? 2 :
1124 (go->format == V4L2_PIX_FMT_H263 ? 4 : 16)))) |
1125 ((go->repeat_seqhead ? 1 : 0) << 6) |
1126 ((go->dvd_mode ? 1 : 0) << 9) |
1127 ((go->gop_header_enable ? 1 : 0) << 10),
1128 0xbf0b, 0,
1129 0xdd5a, go->ipb ? 0x14 : 0x0a,
1130 0xbf0c, 0,
1131 0xbf0d, 0,
1132 0xc683, THACCoeffSet0,
1133 0xc40a, (go->width << 4) | rows,
1134 0xe01a, go->board_info->hpi_buffer_cap,
1135 0, 0,
1136 0, 0,
1137
1138 0x2008, 0,
1139 0xe402, 0x88,
1140 0xe401, 0x8f01,
1141 0xbf6a, 0,
1142 0xbf6b, 0,
1143 0xbf6c, 0,
1144 0xbf6d, 0,
1145 0xbf6e, 0,
1146 0xbf6f, 0,
1147 0, 0,
1148 0, 0,
1149 0, 0,
1150 0, 0,
1151 0, 0,
1152 0, 0,
1153 0, 0,
1154
1155 0x200e, 0,
1156 0xbf66, brc_window_size,
1157 0xbf67, 0,
1158 0xbf68, q_min,
1159 0xbf69, q_max,
1160 0xbfe0, 0,
1161 0xbfe1, 0,
1162 0xbfe2, 0,
1163 0xbfe3, go->ipb ? 3 : 1,
1164 0xc031, go->board_info->sensor_flags &
1165 GO7007_SENSOR_VBI ? 1 : 0,
1166 0xc01c, 0x1f,
1167 0xdd8c, 0x15,
1168 0xdd94, 0x15,
1169 0xdd88, go->ipb ? 0x1401 : 0x0a01,
1170 0xdd90, go->ipb ? 0x1401 : 0x0a01,
1171 0, 0,
1172
1173 0x200e, 0,
1174 0xbfe4, 0,
1175 0xbfe5, 0,
1176 0xbfe6, 0,
1177 0xbfe7, fps << 8,
1178 0xbfe8, 0x3a00,
1179 0xbfe9, 0,
1180 0xbfea, 0,
1181 0xbfeb, 0,
1182 0xbfec, (go->interlace_coding ? 1 << 15 : 0) |
1183 (go->modet_enable ? 0xa : 0) |
1184 (go->board_info->sensor_flags &
1185 GO7007_SENSOR_VBI ? 1 : 0),
1186 0xbfed, 0,
1187 0xbfee, 0,
1188 0xbfef, 0,
1189 0xbff0, go->board_info->sensor_flags &
1190 GO7007_SENSOR_TV ? 0xf060 : 0xb060,
1191 0xbff1, 0,
1192 0, 0,
1193 };
1194
1195 return copy_packages(dest: code, src: pack, pkg_cnt: 5, space);
1196}
1197
1198static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
1199 int (*sequence_header_func)(struct go7007 *go,
1200 unsigned char *buf, int ext))
1201{
1202 int vop_time_increment_bitlength = vti_bitlen(go);
1203 int fps = go->sensor_framerate / go->fps_scale *
1204 (go->interlace_coding ? 2 : 1);
1205 unsigned char buf[40] = { };
1206 int len = sequence_header_func(go, buf, 1);
1207 u16 pack[] = {
1208 0x2006, 0,
1209 0xbf08, fps,
1210 0xbf09, 0,
1211 0xbff2, vop_time_increment_bitlength,
1212 0xbff3, (1 << vop_time_increment_bitlength) - 1,
1213 0xbfe6, 0,
1214 0xbfe7, (fps / 1000) << 8,
1215 0, 0,
1216 0, 0,
1217 0, 0,
1218 0, 0,
1219 0, 0,
1220 0, 0,
1221 0, 0,
1222 0, 0,
1223 0, 0,
1224
1225 0x2007, 0,
1226 0xc800, buf[2] << 8 | buf[3],
1227 0xc801, buf[4] << 8 | buf[5],
1228 0xc802, buf[6] << 8 | buf[7],
1229 0xc803, buf[8] << 8 | buf[9],
1230 0xc406, 64,
1231 0xc407, len - 64,
1232 0xc61b, 1,
1233 0, 0,
1234 0, 0,
1235 0, 0,
1236 0, 0,
1237 0, 0,
1238 0, 0,
1239 0, 0,
1240 0, 0,
1241
1242 0x200e, 0,
1243 0xc808, buf[10] << 8 | buf[11],
1244 0xc809, buf[12] << 8 | buf[13],
1245 0xc80a, buf[14] << 8 | buf[15],
1246 0xc80b, buf[16] << 8 | buf[17],
1247 0xc80c, buf[18] << 8 | buf[19],
1248 0xc80d, buf[20] << 8 | buf[21],
1249 0xc80e, buf[22] << 8 | buf[23],
1250 0xc80f, buf[24] << 8 | buf[25],
1251 0xc810, buf[26] << 8 | buf[27],
1252 0xc811, buf[28] << 8 | buf[29],
1253 0xc812, buf[30] << 8 | buf[31],
1254 0xc813, buf[32] << 8 | buf[33],
1255 0xc814, buf[34] << 8 | buf[35],
1256 0xc815, buf[36] << 8 | buf[37],
1257 0, 0,
1258 0, 0,
1259 0, 0,
1260 };
1261
1262 return copy_packages(dest: code, src: pack, pkg_cnt: 3, space);
1263}
1264
1265static int relative_prime(int big, int little)
1266{
1267 int remainder;
1268
1269 while (little != 0) {
1270 remainder = big % little;
1271 big = little;
1272 little = remainder;
1273 }
1274 return big;
1275}
1276
1277static int avsync_to_package(struct go7007 *go, __le16 *code, int space)
1278{
1279 int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
1280 int ratio = arate / go->sensor_framerate;
1281 int adjratio = ratio * 215 / 100;
1282 int rprime = relative_prime(big: go->sensor_framerate,
1283 little: arate % go->sensor_framerate);
1284 int f1 = (arate % go->sensor_framerate) / rprime;
1285 int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
1286 u16 pack[] = {
1287 0x200e, 0,
1288 0xbf98, (u16)((-adjratio) & 0xffff),
1289 0xbf99, (u16)((-adjratio) >> 16),
1290 0xbf92, 0,
1291 0xbf93, 0,
1292 0xbff4, f1 > f2 ? f1 : f2,
1293 0xbff5, f1 < f2 ? f1 : f2,
1294 0xbff6, f1 < f2 ? ratio : ratio + 1,
1295 0xbff7, f1 > f2 ? ratio : ratio + 1,
1296 0xbff8, 0,
1297 0xbff9, 0,
1298 0xbffa, adjratio & 0xffff,
1299 0xbffb, adjratio >> 16,
1300 0xbf94, 0,
1301 0xbf95, 0,
1302 0, 0,
1303 };
1304
1305 return copy_packages(dest: code, src: pack, pkg_cnt: 1, space);
1306}
1307
1308static int final_package(struct go7007 *go, __le16 *code, int space)
1309{
1310 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1311 u16 pack[] = {
1312 0x8000,
1313 0,
1314 0,
1315 0,
1316 0,
1317 0,
1318 0,
1319 2,
1320 ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
1321 (!go->interlace_coding) ?
1322 (1 << 14) | (1 << 9) : 0) |
1323 ((go->encoder_subsample ? 1 : 0) << 8) |
1324 (go->board_info->sensor_flags &
1325 GO7007_SENSOR_CONFIG_MASK),
1326 ((go->encoder_v_halve ? 1 : 0) << 14) |
1327 (go->encoder_v_halve ? rows << 9 : rows << 8) |
1328 (go->encoder_h_halve ? 1 << 6 : 0) |
1329 (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
1330 (1 << 15) | (go->encoder_v_offset << 6) |
1331 (1 << 7) | (go->encoder_h_offset >> 2),
1332 (1 << 6),
1333 0,
1334 0,
1335 ((go->fps_scale - 1) << 8) |
1336 (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
1337 (1 << 7) : 0) |
1338 0x41,
1339 go->ipb ? 0xd4c : 0x36b,
1340 (rows << 8) | (go->width >> 4),
1341 go->format == V4L2_PIX_FMT_MPEG4 ? 0x0404 : 0,
1342 (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
1343 ((go->closed_gop ? 1 : 0) << 12) |
1344 ((go->format == V4L2_PIX_FMT_MPEG4 ? 1 : 0) << 11) |
1345 /* (1 << 9) | */
1346 ((go->ipb ? 3 : 0) << 7) |
1347 ((go->modet_enable ? 1 : 0) << 2) |
1348 ((go->dvd_mode ? 1 : 0) << 1) | 1,
1349 (go->format == V4L2_PIX_FMT_MPEG1 ? 0x89a0 :
1350 (go->format == V4L2_PIX_FMT_MPEG2 ? 0x89a0 :
1351 (go->format == V4L2_PIX_FMT_MJPEG ? 0x89a0 :
1352 (go->format == V4L2_PIX_FMT_MPEG4 ? 0x8920 :
1353 (go->format == V4L2_PIX_FMT_H263 ? 0x8920 : 0))))),
1354 go->ipb ? 0x1f15 : 0x1f0b,
1355 go->ipb ? 0x0015 : 0x000b,
1356 go->ipb ? 0xa800 : 0x5800,
1357 0xffff,
1358 0x0020 + 0x034b * 0,
1359 0x0020 + 0x034b * 1,
1360 0x0020 + 0x034b * 2,
1361 0x0020 + 0x034b * 3,
1362 0x0020 + 0x034b * 4,
1363 0x0020 + 0x034b * 5,
1364 go->ipb ? (go->gop_size / 3) : go->gop_size,
1365 (go->height >> 4) * (go->width >> 4) * 110 / 100,
1366 };
1367
1368 return copy_packages(dest: code, src: pack, pkg_cnt: 1, space);
1369}
1370
1371static int audio_to_package(struct go7007 *go, __le16 *code, int space)
1372{
1373 int clock_config = ((go->board_info->audio_flags &
1374 GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
1375 ((go->board_info->audio_flags &
1376 GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
1377 (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
1378 (go->board_info->audio_main_div - 1);
1379 u16 pack[] = {
1380 0x200d, 0,
1381 0x9002, 0,
1382 0x9002, 0,
1383 0x9031, 0,
1384 0x9032, 0,
1385 0x9033, 0,
1386 0x9034, 0,
1387 0x9035, 0,
1388 0x9036, 0,
1389 0x9037, 0,
1390 0x9040, 0,
1391 0x9000, clock_config,
1392 0x9001, (go->board_info->audio_flags & 0xffff) |
1393 (1 << 9),
1394 0x9000, ((go->board_info->audio_flags &
1395 GO7007_AUDIO_I2S_MASTER ?
1396 1 : 0) << 10) |
1397 clock_config,
1398 0, 0,
1399 0, 0,
1400 0x2005, 0,
1401 0x9041, 0,
1402 0x9042, 256,
1403 0x9043, 0,
1404 0x9044, 16,
1405 0x9045, 16,
1406 0, 0,
1407 0, 0,
1408 0, 0,
1409 0, 0,
1410 0, 0,
1411 0, 0,
1412 0, 0,
1413 0, 0,
1414 0, 0,
1415 0, 0,
1416 };
1417
1418 return copy_packages(dest: code, src: pack, pkg_cnt: 2, space);
1419}
1420
1421static int modet_to_package(struct go7007 *go, __le16 *code, int space)
1422{
1423 bool has_modet0 = go->modet[0].enable;
1424 bool has_modet1 = go->modet[1].enable;
1425 bool has_modet2 = go->modet[2].enable;
1426 bool has_modet3 = go->modet[3].enable;
1427 int ret, mb, i, addr, cnt = 0;
1428 u16 pack[32];
1429 u16 thresholds[] = {
1430 0x200e, 0,
1431 0xbf82, has_modet0 ? go->modet[0].pixel_threshold : 32767,
1432 0xbf83, has_modet1 ? go->modet[1].pixel_threshold : 32767,
1433 0xbf84, has_modet2 ? go->modet[2].pixel_threshold : 32767,
1434 0xbf85, has_modet3 ? go->modet[3].pixel_threshold : 32767,
1435 0xbf86, has_modet0 ? go->modet[0].motion_threshold : 32767,
1436 0xbf87, has_modet1 ? go->modet[1].motion_threshold : 32767,
1437 0xbf88, has_modet2 ? go->modet[2].motion_threshold : 32767,
1438 0xbf89, has_modet3 ? go->modet[3].motion_threshold : 32767,
1439 0xbf8a, has_modet0 ? go->modet[0].mb_threshold : 32767,
1440 0xbf8b, has_modet1 ? go->modet[1].mb_threshold : 32767,
1441 0xbf8c, has_modet2 ? go->modet[2].mb_threshold : 32767,
1442 0xbf8d, has_modet3 ? go->modet[3].mb_threshold : 32767,
1443 0xbf8e, 0,
1444 0xbf8f, 0,
1445 0, 0,
1446 };
1447
1448 ret = copy_packages(dest: code, src: thresholds, pkg_cnt: 1, space);
1449 if (ret < 0)
1450 return -1;
1451 cnt += ret;
1452
1453 addr = 0xbac0;
1454 memset(pack, 0, 64);
1455 i = 0;
1456 for (mb = 0; mb < 1624; ++mb) {
1457 pack[i * 2 + 3] <<= 2;
1458 pack[i * 2 + 3] |= go->modet_map[mb];
1459 if (mb % 8 != 7)
1460 continue;
1461 pack[i * 2 + 2] = addr++;
1462 ++i;
1463 if (i == 10 || mb == 1623) {
1464 pack[0] = 0x2000 | i;
1465 ret = copy_packages(dest: code + cnt, src: pack, pkg_cnt: 1, space: space - cnt);
1466 if (ret < 0)
1467 return -1;
1468 cnt += ret;
1469 i = 0;
1470 memset(pack, 0, 64);
1471 }
1472 pack[i * 2 + 3] = 0;
1473 }
1474
1475 memset(pack, 0, 64);
1476 i = 0;
1477 for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
1478 pack[i * 2 + 2] = addr;
1479 pack[i * 2 + 3] = 0;
1480 ++i;
1481 if (i == 10 || addr == 0xbbf9) {
1482 pack[0] = 0x2000 | i;
1483 ret = copy_packages(dest: code + cnt, src: pack, pkg_cnt: 1, space: space - cnt);
1484 if (ret < 0)
1485 return -1;
1486 cnt += ret;
1487 i = 0;
1488 memset(pack, 0, 64);
1489 }
1490 }
1491 return cnt;
1492}
1493
1494static noinline_for_stack int do_special(struct go7007 *go, u16 type,
1495 __le16 *code, int space, int *framelen)
1496{
1497 switch (type) {
1498 case SPECIAL_FRM_HEAD:
1499 switch (go->format) {
1500 case V4L2_PIX_FMT_MJPEG:
1501 return gen_mjpeghdr_to_package(go, code, space);
1502 case V4L2_PIX_FMT_MPEG1:
1503 case V4L2_PIX_FMT_MPEG2:
1504 return gen_mpeg1hdr_to_package(go, code, space,
1505 framelen);
1506 case V4L2_PIX_FMT_MPEG4:
1507 return gen_mpeg4hdr_to_package(go, code, space,
1508 framelen);
1509 default:
1510 break;
1511 }
1512 break;
1513 case SPECIAL_BRC_CTRL:
1514 return brctrl_to_package(go, code, space, framelen);
1515 case SPECIAL_CONFIG:
1516 return config_package(go, code, space);
1517 case SPECIAL_SEQHEAD:
1518 switch (go->format) {
1519 case V4L2_PIX_FMT_MPEG1:
1520 case V4L2_PIX_FMT_MPEG2:
1521 return seqhead_to_package(go, code, space,
1522 sequence_header_func: mpeg1_sequence_header);
1523 case V4L2_PIX_FMT_MPEG4:
1524 return seqhead_to_package(go, code, space,
1525 sequence_header_func: mpeg4_sequence_header);
1526 default:
1527 return 0;
1528 }
1529 case SPECIAL_AV_SYNC:
1530 return avsync_to_package(go, code, space);
1531 case SPECIAL_FINAL:
1532 return final_package(go, code, space);
1533 case SPECIAL_AUDIO:
1534 return audio_to_package(go, code, space);
1535 case SPECIAL_MODET:
1536 return modet_to_package(go, code, space);
1537 }
1538 dev_err(go->dev,
1539 "firmware file contains unsupported feature %04x\n", type);
1540 return -1;
1541}
1542
1543int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
1544{
1545 const struct firmware *fw_entry;
1546 __le16 *code, *src;
1547 int framelen[8] = { }; /* holds the lengths of empty frame templates */
1548 int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
1549 int mode_flag;
1550 int ret;
1551
1552 switch (go->format) {
1553 case V4L2_PIX_FMT_MJPEG:
1554 mode_flag = FLAG_MODE_MJPEG;
1555 break;
1556 case V4L2_PIX_FMT_MPEG1:
1557 mode_flag = FLAG_MODE_MPEG1;
1558 break;
1559 case V4L2_PIX_FMT_MPEG2:
1560 mode_flag = FLAG_MODE_MPEG2;
1561 break;
1562 case V4L2_PIX_FMT_MPEG4:
1563 mode_flag = FLAG_MODE_MPEG4;
1564 break;
1565 default:
1566 return -1;
1567 }
1568 if (request_firmware(fw: &fw_entry, GO7007_FW_NAME, device: go->dev)) {
1569 dev_err(go->dev,
1570 "unable to load firmware from file \"%s\"\n",
1571 GO7007_FW_NAME);
1572 return -1;
1573 }
1574 code = kcalloc(n: codespace, size: 2, GFP_KERNEL);
1575 if (code == NULL)
1576 goto fw_failed;
1577
1578 src = (__le16 *)fw_entry->data;
1579 srclen = fw_entry->size / 2;
1580 while (srclen >= 2) {
1581 chunk_flags = __le16_to_cpu(src[0]);
1582 chunk_len = __le16_to_cpu(src[1]);
1583 if (chunk_len + 2 > srclen) {
1584 dev_err(go->dev,
1585 "firmware file \"%s\" appears to be corrupted\n",
1586 GO7007_FW_NAME);
1587 goto fw_failed;
1588 }
1589 if (chunk_flags & mode_flag) {
1590 if (chunk_flags & FLAG_SPECIAL) {
1591 ret = do_special(go, __le16_to_cpu(src[2]),
1592 code: &code[i], space: codespace - i, framelen);
1593 if (ret < 0) {
1594 dev_err(go->dev,
1595 "insufficient memory for firmware construction\n");
1596 goto fw_failed;
1597 }
1598 i += ret;
1599 } else {
1600 if (codespace - i < chunk_len) {
1601 dev_err(go->dev,
1602 "insufficient memory for firmware construction\n");
1603 goto fw_failed;
1604 }
1605 memcpy(&code[i], &src[2], chunk_len * 2);
1606 i += chunk_len;
1607 }
1608 }
1609 srclen -= chunk_len + 2;
1610 src += chunk_len + 2;
1611 }
1612 release_firmware(fw: fw_entry);
1613 *fw = (u8 *)code;
1614 *fwlen = i * 2;
1615 return 0;
1616
1617fw_failed:
1618 kfree(objp: code);
1619 release_firmware(fw: fw_entry);
1620 return -1;
1621}
1622
1623MODULE_FIRMWARE(GO7007_FW_NAME);
1624

source code of linux/drivers/media/usb/go7007/go7007-fw.c