1*1802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2866b8695SGreg Kroah-Hartman /* 3866b8695SGreg Kroah-Hartman * Copyright (C) 2005-2006 Micronas USA Inc. 4866b8695SGreg Kroah-Hartman */ 5866b8695SGreg Kroah-Hartman 6866b8695SGreg Kroah-Hartman /* 7866b8695SGreg Kroah-Hartman * This file contains code to generate a firmware image for the GO7007SB 8866b8695SGreg Kroah-Hartman * encoder. Much of the firmware is read verbatim from a file, but some of 9866b8695SGreg Kroah-Hartman * it concerning bitrate control and other things that can be configured at 10866b8695SGreg Kroah-Hartman * run-time are generated dynamically. Note that the format headers 11866b8695SGreg Kroah-Hartman * generated here do not affect the functioning of the encoder; they are 12866b8695SGreg Kroah-Hartman * merely parroted back to the host at the start of each frame. 13866b8695SGreg Kroah-Hartman */ 14866b8695SGreg Kroah-Hartman 15866b8695SGreg Kroah-Hartman #include <linux/module.h> 16866b8695SGreg Kroah-Hartman #include <linux/time.h> 17866b8695SGreg Kroah-Hartman #include <linux/mm.h> 18866b8695SGreg Kroah-Hartman #include <linux/device.h> 19866b8695SGreg Kroah-Hartman #include <linux/i2c.h> 20866b8695SGreg Kroah-Hartman #include <linux/firmware.h> 215a0e3ad6STejun Heo #include <linux/slab.h> 22866b8695SGreg Kroah-Hartman #include <asm/byteorder.h> 23866b8695SGreg Kroah-Hartman 24866b8695SGreg Kroah-Hartman #include "go7007-priv.h" 25866b8695SGreg Kroah-Hartman 260a6ecbb4SHans Verkuil #define GO7007_FW_NAME "go7007/go7007tv.bin" 270a6ecbb4SHans Verkuil 28866b8695SGreg Kroah-Hartman /* Constants used in the source firmware image to describe code segments */ 29866b8695SGreg Kroah-Hartman 30866b8695SGreg Kroah-Hartman #define FLAG_MODE_MJPEG (1) 31866b8695SGreg Kroah-Hartman #define FLAG_MODE_MPEG1 (1<<1) 32866b8695SGreg Kroah-Hartman #define FLAG_MODE_MPEG2 (1<<2) 33866b8695SGreg Kroah-Hartman #define FLAG_MODE_MPEG4 (1<<3) 34866b8695SGreg Kroah-Hartman #define FLAG_MODE_H263 (1<<4) 35866b8695SGreg Kroah-Hartman #define FLAG_MODE_ALL (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \ 36866b8695SGreg Kroah-Hartman FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \ 37866b8695SGreg Kroah-Hartman FLAG_MODE_H263) 38866b8695SGreg Kroah-Hartman #define FLAG_SPECIAL (1<<8) 39866b8695SGreg Kroah-Hartman 40866b8695SGreg Kroah-Hartman #define SPECIAL_FRM_HEAD 0 41866b8695SGreg Kroah-Hartman #define SPECIAL_BRC_CTRL 1 42866b8695SGreg Kroah-Hartman #define SPECIAL_CONFIG 2 43866b8695SGreg Kroah-Hartman #define SPECIAL_SEQHEAD 3 44866b8695SGreg Kroah-Hartman #define SPECIAL_AV_SYNC 4 45866b8695SGreg Kroah-Hartman #define SPECIAL_FINAL 5 46866b8695SGreg Kroah-Hartman #define SPECIAL_AUDIO 6 47866b8695SGreg Kroah-Hartman #define SPECIAL_MODET 7 48866b8695SGreg Kroah-Hartman 49866b8695SGreg Kroah-Hartman /* Little data class for creating MPEG headers bit-by-bit */ 50866b8695SGreg Kroah-Hartman 51866b8695SGreg Kroah-Hartman struct code_gen { 52866b8695SGreg Kroah-Hartman unsigned char *p; /* destination */ 53866b8695SGreg Kroah-Hartman u32 a; /* collects bits at the top of the variable */ 54866b8695SGreg Kroah-Hartman int b; /* bit position of most recently-written bit */ 55866b8695SGreg Kroah-Hartman int len; /* written out so far */ 56866b8695SGreg Kroah-Hartman }; 57866b8695SGreg Kroah-Hartman 58866b8695SGreg Kroah-Hartman #define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 } 59866b8695SGreg Kroah-Hartman 60866b8695SGreg Kroah-Hartman #define CODE_ADD(name, val, length) do { \ 61866b8695SGreg Kroah-Hartman name.b -= (length); \ 62866b8695SGreg Kroah-Hartman name.a |= (val) << name.b; \ 63866b8695SGreg Kroah-Hartman while (name.b <= 24) { \ 64866b8695SGreg Kroah-Hartman *name.p = name.a >> 24; \ 65866b8695SGreg Kroah-Hartman ++name.p; \ 66866b8695SGreg Kroah-Hartman name.a <<= 8; \ 67866b8695SGreg Kroah-Hartman name.b += 8; \ 68866b8695SGreg Kroah-Hartman name.len += 8; \ 69866b8695SGreg Kroah-Hartman } \ 70866b8695SGreg Kroah-Hartman } while (0) 71866b8695SGreg Kroah-Hartman 72866b8695SGreg Kroah-Hartman #define CODE_LENGTH(name) (name.len + (32 - name.b)) 73866b8695SGreg Kroah-Hartman 74866b8695SGreg Kroah-Hartman /* Tables for creating the bitrate control data */ 75866b8695SGreg Kroah-Hartman 76866b8695SGreg Kroah-Hartman static const s16 converge_speed_ip[101] = { 77866b8695SGreg Kroah-Hartman 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 78866b8695SGreg Kroah-Hartman 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 79866b8695SGreg Kroah-Hartman 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 80866b8695SGreg Kroah-Hartman 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 81866b8695SGreg Kroah-Hartman 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 82866b8695SGreg Kroah-Hartman 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 83866b8695SGreg Kroah-Hartman 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 84866b8695SGreg Kroah-Hartman 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 85866b8695SGreg Kroah-Hartman 19, 20, 22, 23, 25, 27, 30, 32, 35, 38, 86866b8695SGreg Kroah-Hartman 41, 45, 49, 53, 58, 63, 69, 76, 83, 91, 87866b8695SGreg Kroah-Hartman 100 88866b8695SGreg Kroah-Hartman }; 89866b8695SGreg Kroah-Hartman 90866b8695SGreg Kroah-Hartman static const s16 converge_speed_ipb[101] = { 91866b8695SGreg Kroah-Hartman 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 92866b8695SGreg Kroah-Hartman 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 93866b8695SGreg Kroah-Hartman 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 94866b8695SGreg Kroah-Hartman 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 95866b8695SGreg Kroah-Hartman 6, 6, 6, 7, 7, 7, 7, 8, 8, 9, 96866b8695SGreg Kroah-Hartman 9, 9, 10, 10, 11, 12, 12, 13, 14, 14, 97866b8695SGreg Kroah-Hartman 15, 16, 17, 18, 19, 20, 22, 23, 25, 26, 98866b8695SGreg Kroah-Hartman 28, 30, 32, 34, 37, 40, 42, 46, 49, 53, 99866b8695SGreg Kroah-Hartman 57, 61, 66, 71, 77, 83, 90, 97, 106, 115, 100866b8695SGreg Kroah-Hartman 125, 135, 147, 161, 175, 191, 209, 228, 249, 273, 101866b8695SGreg Kroah-Hartman 300 102866b8695SGreg Kroah-Hartman }; 103866b8695SGreg Kroah-Hartman 104866b8695SGreg Kroah-Hartman static const s16 LAMBDA_table[4][101] = { 105866b8695SGreg Kroah-Hartman { 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 106866b8695SGreg Kroah-Hartman 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 107866b8695SGreg Kroah-Hartman 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, 108866b8695SGreg Kroah-Hartman 27, 27, 28, 28, 29, 29, 30, 31, 31, 32, 109866b8695SGreg Kroah-Hartman 32, 33, 33, 34, 35, 35, 36, 37, 37, 38, 110866b8695SGreg Kroah-Hartman 39, 39, 40, 41, 42, 42, 43, 44, 45, 46, 111866b8695SGreg Kroah-Hartman 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 112866b8695SGreg Kroah-Hartman 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 113866b8695SGreg Kroah-Hartman 67, 68, 69, 70, 72, 73, 74, 76, 77, 78, 114866b8695SGreg Kroah-Hartman 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 115866b8695SGreg Kroah-Hartman 96 116866b8695SGreg Kroah-Hartman }, 117866b8695SGreg Kroah-Hartman { 118866b8695SGreg Kroah-Hartman 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 119866b8695SGreg Kroah-Hartman 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 120866b8695SGreg Kroah-Hartman 28, 29, 29, 30, 30, 31, 31, 32, 33, 33, 121866b8695SGreg Kroah-Hartman 34, 34, 35, 36, 36, 37, 38, 38, 39, 40, 122866b8695SGreg Kroah-Hartman 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 123866b8695SGreg Kroah-Hartman 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 124866b8695SGreg Kroah-Hartman 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 125866b8695SGreg Kroah-Hartman 70, 71, 72, 73, 75, 76, 78, 79, 80, 82, 126866b8695SGreg Kroah-Hartman 83, 85, 86, 88, 90, 91, 93, 95, 96, 98, 127866b8695SGreg Kroah-Hartman 100, 102, 103, 105, 107, 109, 111, 113, 115, 117, 128866b8695SGreg Kroah-Hartman 120 129866b8695SGreg Kroah-Hartman }, 130866b8695SGreg Kroah-Hartman { 131866b8695SGreg Kroah-Hartman 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 132866b8695SGreg Kroah-Hartman 28, 29, 29, 30, 30, 31, 31, 32, 33, 33, 133866b8695SGreg Kroah-Hartman 34, 34, 35, 36, 36, 37, 38, 38, 39, 40, 134866b8695SGreg Kroah-Hartman 41, 41, 42, 43, 44, 44, 45, 46, 47, 48, 135866b8695SGreg Kroah-Hartman 49, 50, 50, 51, 52, 53, 54, 55, 56, 57, 136866b8695SGreg Kroah-Hartman 58, 59, 60, 62, 63, 64, 65, 66, 67, 69, 137866b8695SGreg Kroah-Hartman 70, 71, 72, 74, 75, 76, 78, 79, 81, 82, 138866b8695SGreg Kroah-Hartman 84, 85, 87, 88, 90, 92, 93, 95, 97, 98, 139866b8695SGreg Kroah-Hartman 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 140866b8695SGreg Kroah-Hartman 120, 122, 124, 127, 129, 131, 134, 136, 138, 141, 141866b8695SGreg Kroah-Hartman 144 142866b8695SGreg Kroah-Hartman }, 143866b8695SGreg Kroah-Hartman { 144866b8695SGreg Kroah-Hartman 32, 32, 33, 33, 34, 34, 35, 36, 36, 37, 145866b8695SGreg Kroah-Hartman 38, 38, 39, 40, 41, 41, 42, 43, 44, 44, 146866b8695SGreg Kroah-Hartman 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 147866b8695SGreg Kroah-Hartman 54, 55, 56, 57, 58, 59, 60, 62, 63, 64, 148866b8695SGreg Kroah-Hartman 65, 66, 67, 69, 70, 71, 72, 74, 75, 76, 149866b8695SGreg Kroah-Hartman 78, 79, 81, 82, 84, 85, 87, 88, 90, 92, 150866b8695SGreg Kroah-Hartman 93, 95, 97, 98, 100, 102, 104, 106, 108, 110, 151866b8695SGreg Kroah-Hartman 112, 114, 116, 118, 120, 122, 124, 127, 129, 131, 152866b8695SGreg Kroah-Hartman 134, 136, 139, 141, 144, 146, 149, 152, 154, 157, 153866b8695SGreg Kroah-Hartman 160, 163, 166, 169, 172, 175, 178, 181, 185, 188, 154866b8695SGreg Kroah-Hartman 192 155866b8695SGreg Kroah-Hartman } 156866b8695SGreg Kroah-Hartman }; 157866b8695SGreg Kroah-Hartman 158866b8695SGreg Kroah-Hartman /* MPEG blank frame generation tables */ 159866b8695SGreg Kroah-Hartman 160866b8695SGreg Kroah-Hartman enum mpeg_frame_type { 161866b8695SGreg Kroah-Hartman PFRAME, 162866b8695SGreg Kroah-Hartman BFRAME_PRE, 163866b8695SGreg Kroah-Hartman BFRAME_POST, 164866b8695SGreg Kroah-Hartman BFRAME_BIDIR, 165866b8695SGreg Kroah-Hartman BFRAME_EMPTY 166866b8695SGreg Kroah-Hartman }; 167866b8695SGreg Kroah-Hartman 168866b8695SGreg Kroah-Hartman static const u32 addrinctab[33][2] = { 169866b8695SGreg Kroah-Hartman { 0x01, 1 }, { 0x03, 3 }, { 0x02, 3 }, { 0x03, 4 }, 170866b8695SGreg Kroah-Hartman { 0x02, 4 }, { 0x03, 5 }, { 0x02, 5 }, { 0x07, 7 }, 171866b8695SGreg Kroah-Hartman { 0x06, 7 }, { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 }, 172866b8695SGreg Kroah-Hartman { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 }, { 0x17, 10 }, 173866b8695SGreg Kroah-Hartman { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 }, 174866b8695SGreg Kroah-Hartman { 0x12, 10 }, { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 }, 175866b8695SGreg Kroah-Hartman { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 }, 176866b8695SGreg Kroah-Hartman { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 }, 177866b8695SGreg Kroah-Hartman { 0x18, 11 } 178866b8695SGreg Kroah-Hartman }; 179866b8695SGreg Kroah-Hartman 180866b8695SGreg Kroah-Hartman /* Standard JPEG tables */ 181866b8695SGreg Kroah-Hartman 182866b8695SGreg Kroah-Hartman static const u8 default_intra_quant_table[] = { 183866b8695SGreg Kroah-Hartman 8, 16, 19, 22, 26, 27, 29, 34, 184866b8695SGreg Kroah-Hartman 16, 16, 22, 24, 27, 29, 34, 37, 185866b8695SGreg Kroah-Hartman 19, 22, 26, 27, 29, 34, 34, 38, 186866b8695SGreg Kroah-Hartman 22, 22, 26, 27, 29, 34, 37, 40, 187866b8695SGreg Kroah-Hartman 22, 26, 27, 29, 32, 35, 40, 48, 188866b8695SGreg Kroah-Hartman 26, 27, 29, 32, 35, 40, 48, 58, 189866b8695SGreg Kroah-Hartman 26, 27, 29, 34, 38, 46, 56, 69, 190866b8695SGreg Kroah-Hartman 27, 29, 35, 38, 46, 56, 69, 83 191866b8695SGreg Kroah-Hartman }; 192866b8695SGreg Kroah-Hartman 193866b8695SGreg Kroah-Hartman static const u8 bits_dc_luminance[] = { 194866b8695SGreg Kroah-Hartman 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 195866b8695SGreg Kroah-Hartman }; 196866b8695SGreg Kroah-Hartman 197866b8695SGreg Kroah-Hartman static const u8 val_dc_luminance[] = { 198866b8695SGreg Kroah-Hartman 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 199866b8695SGreg Kroah-Hartman }; 200866b8695SGreg Kroah-Hartman 201866b8695SGreg Kroah-Hartman static const u8 bits_dc_chrominance[] = { 202866b8695SGreg Kroah-Hartman 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 203866b8695SGreg Kroah-Hartman }; 204866b8695SGreg Kroah-Hartman 205866b8695SGreg Kroah-Hartman static const u8 val_dc_chrominance[] = { 206866b8695SGreg Kroah-Hartman 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 207866b8695SGreg Kroah-Hartman }; 208866b8695SGreg Kroah-Hartman 209866b8695SGreg Kroah-Hartman static const u8 bits_ac_luminance[] = { 210866b8695SGreg Kroah-Hartman 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d 211866b8695SGreg Kroah-Hartman }; 212866b8695SGreg Kroah-Hartman 213866b8695SGreg Kroah-Hartman static const u8 val_ac_luminance[] = { 214866b8695SGreg Kroah-Hartman 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 215866b8695SGreg Kroah-Hartman 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 216866b8695SGreg Kroah-Hartman 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 217866b8695SGreg Kroah-Hartman 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 218866b8695SGreg Kroah-Hartman 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 219866b8695SGreg Kroah-Hartman 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 220866b8695SGreg Kroah-Hartman 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 221866b8695SGreg Kroah-Hartman 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 222866b8695SGreg Kroah-Hartman 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 223866b8695SGreg Kroah-Hartman 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 224866b8695SGreg Kroah-Hartman 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 225866b8695SGreg Kroah-Hartman 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 226866b8695SGreg Kroah-Hartman 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 227866b8695SGreg Kroah-Hartman 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 228866b8695SGreg Kroah-Hartman 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 229866b8695SGreg Kroah-Hartman 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 230866b8695SGreg Kroah-Hartman 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 231866b8695SGreg Kroah-Hartman 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 232866b8695SGreg Kroah-Hartman 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 233866b8695SGreg Kroah-Hartman 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 234866b8695SGreg Kroah-Hartman 0xf9, 0xfa 235866b8695SGreg Kroah-Hartman }; 236866b8695SGreg Kroah-Hartman 237866b8695SGreg Kroah-Hartman static const u8 bits_ac_chrominance[] = { 238866b8695SGreg Kroah-Hartman 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 239866b8695SGreg Kroah-Hartman }; 240866b8695SGreg Kroah-Hartman 241866b8695SGreg Kroah-Hartman static const u8 val_ac_chrominance[] = { 242866b8695SGreg Kroah-Hartman 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 243866b8695SGreg Kroah-Hartman 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 244866b8695SGreg Kroah-Hartman 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 245866b8695SGreg Kroah-Hartman 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 246866b8695SGreg Kroah-Hartman 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 247866b8695SGreg Kroah-Hartman 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 248866b8695SGreg Kroah-Hartman 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 249866b8695SGreg Kroah-Hartman 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 250866b8695SGreg Kroah-Hartman 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 251866b8695SGreg Kroah-Hartman 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 252866b8695SGreg Kroah-Hartman 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 253866b8695SGreg Kroah-Hartman 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 254866b8695SGreg Kroah-Hartman 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 255866b8695SGreg Kroah-Hartman 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 256866b8695SGreg Kroah-Hartman 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 257866b8695SGreg Kroah-Hartman 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 258866b8695SGreg Kroah-Hartman 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 259866b8695SGreg Kroah-Hartman 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 260866b8695SGreg Kroah-Hartman 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 261866b8695SGreg Kroah-Hartman 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 262866b8695SGreg Kroah-Hartman 0xf9, 0xfa 263866b8695SGreg Kroah-Hartman }; 264866b8695SGreg Kroah-Hartman 265866b8695SGreg Kroah-Hartman /* Zig-zag mapping for quant table 266866b8695SGreg Kroah-Hartman * 267866b8695SGreg Kroah-Hartman * OK, let's do this mapping on the actual table above so it doesn't have 268866b8695SGreg Kroah-Hartman * to be done on the fly. 269866b8695SGreg Kroah-Hartman */ 270866b8695SGreg Kroah-Hartman static const int zz[64] = { 271866b8695SGreg Kroah-Hartman 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 272866b8695SGreg Kroah-Hartman 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 273866b8695SGreg Kroah-Hartman 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 274866b8695SGreg Kroah-Hartman 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 275866b8695SGreg Kroah-Hartman }; 276866b8695SGreg Kroah-Hartman 2779febd042SHarvey Harrison static int copy_packages(__le16 *dest, u16 *src, int pkg_cnt, int space) 278866b8695SGreg Kroah-Hartman { 279866b8695SGreg Kroah-Hartman int i, cnt = pkg_cnt * 32; 280866b8695SGreg Kroah-Hartman 281866b8695SGreg Kroah-Hartman if (space < cnt) 282866b8695SGreg Kroah-Hartman return -1; 283866b8695SGreg Kroah-Hartman 284866b8695SGreg Kroah-Hartman for (i = 0; i < cnt; ++i) 2859febd042SHarvey Harrison dest[i] = cpu_to_le16p(src + i); 286866b8695SGreg Kroah-Hartman 287866b8695SGreg Kroah-Hartman return cnt; 288866b8695SGreg Kroah-Hartman } 289866b8695SGreg Kroah-Hartman 290866b8695SGreg Kroah-Hartman static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q) 291866b8695SGreg Kroah-Hartman { 292866b8695SGreg Kroah-Hartman int i, p = 0; 293866b8695SGreg Kroah-Hartman 294866b8695SGreg Kroah-Hartman buf[p++] = 0xff; 295866b8695SGreg Kroah-Hartman buf[p++] = 0xd8; 296866b8695SGreg Kroah-Hartman buf[p++] = 0xff; 297866b8695SGreg Kroah-Hartman buf[p++] = 0xdb; 298866b8695SGreg Kroah-Hartman buf[p++] = 0; 299866b8695SGreg Kroah-Hartman buf[p++] = 2 + 65; 300866b8695SGreg Kroah-Hartman buf[p++] = 0; 301866b8695SGreg Kroah-Hartman buf[p++] = default_intra_quant_table[0]; 302866b8695SGreg Kroah-Hartman for (i = 1; i < 64; ++i) 303866b8695SGreg Kroah-Hartman /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */ 304866b8695SGreg Kroah-Hartman buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3; 305866b8695SGreg Kroah-Hartman buf[p++] = 0xff; 306866b8695SGreg Kroah-Hartman buf[p++] = 0xc0; 307866b8695SGreg Kroah-Hartman buf[p++] = 0; 308866b8695SGreg Kroah-Hartman buf[p++] = 17; 309866b8695SGreg Kroah-Hartman buf[p++] = 8; 310866b8695SGreg Kroah-Hartman buf[p++] = go->height >> 8; 311866b8695SGreg Kroah-Hartman buf[p++] = go->height & 0xff; 312866b8695SGreg Kroah-Hartman buf[p++] = go->width >> 8; 313866b8695SGreg Kroah-Hartman buf[p++] = go->width & 0xff; 314866b8695SGreg Kroah-Hartman buf[p++] = 3; 315866b8695SGreg Kroah-Hartman buf[p++] = 1; 316866b8695SGreg Kroah-Hartman buf[p++] = 0x22; 317866b8695SGreg Kroah-Hartman buf[p++] = 0; 318866b8695SGreg Kroah-Hartman buf[p++] = 2; 319866b8695SGreg Kroah-Hartman buf[p++] = 0x11; 320866b8695SGreg Kroah-Hartman buf[p++] = 0; 321866b8695SGreg Kroah-Hartman buf[p++] = 3; 322866b8695SGreg Kroah-Hartman buf[p++] = 0x11; 323866b8695SGreg Kroah-Hartman buf[p++] = 0; 324866b8695SGreg Kroah-Hartman buf[p++] = 0xff; 325866b8695SGreg Kroah-Hartman buf[p++] = 0xc4; 326866b8695SGreg Kroah-Hartman buf[p++] = 418 >> 8; 327866b8695SGreg Kroah-Hartman buf[p++] = 418 & 0xff; 328866b8695SGreg Kroah-Hartman buf[p++] = 0x00; 329866b8695SGreg Kroah-Hartman memcpy(buf + p, bits_dc_luminance + 1, 16); 330866b8695SGreg Kroah-Hartman p += 16; 331866b8695SGreg Kroah-Hartman memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance)); 332866b8695SGreg Kroah-Hartman p += sizeof(val_dc_luminance); 333866b8695SGreg Kroah-Hartman buf[p++] = 0x01; 334866b8695SGreg Kroah-Hartman memcpy(buf + p, bits_dc_chrominance + 1, 16); 335866b8695SGreg Kroah-Hartman p += 16; 336866b8695SGreg Kroah-Hartman memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance)); 337866b8695SGreg Kroah-Hartman p += sizeof(val_dc_chrominance); 338866b8695SGreg Kroah-Hartman buf[p++] = 0x10; 339866b8695SGreg Kroah-Hartman memcpy(buf + p, bits_ac_luminance + 1, 16); 340866b8695SGreg Kroah-Hartman p += 16; 341866b8695SGreg Kroah-Hartman memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance)); 342866b8695SGreg Kroah-Hartman p += sizeof(val_ac_luminance); 343866b8695SGreg Kroah-Hartman buf[p++] = 0x11; 344866b8695SGreg Kroah-Hartman memcpy(buf + p, bits_ac_chrominance + 1, 16); 345866b8695SGreg Kroah-Hartman p += 16; 346866b8695SGreg Kroah-Hartman memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance)); 347866b8695SGreg Kroah-Hartman p += sizeof(val_ac_chrominance); 348866b8695SGreg Kroah-Hartman buf[p++] = 0xff; 349866b8695SGreg Kroah-Hartman buf[p++] = 0xda; 350866b8695SGreg Kroah-Hartman buf[p++] = 0; 351866b8695SGreg Kroah-Hartman buf[p++] = 12; 352866b8695SGreg Kroah-Hartman buf[p++] = 3; 353866b8695SGreg Kroah-Hartman buf[p++] = 1; 354866b8695SGreg Kroah-Hartman buf[p++] = 0x00; 355866b8695SGreg Kroah-Hartman buf[p++] = 2; 356866b8695SGreg Kroah-Hartman buf[p++] = 0x11; 357866b8695SGreg Kroah-Hartman buf[p++] = 3; 358866b8695SGreg Kroah-Hartman buf[p++] = 0x11; 359866b8695SGreg Kroah-Hartman buf[p++] = 0; 360866b8695SGreg Kroah-Hartman buf[p++] = 63; 361866b8695SGreg Kroah-Hartman buf[p++] = 0; 362866b8695SGreg Kroah-Hartman return p; 363866b8695SGreg Kroah-Hartman } 364866b8695SGreg Kroah-Hartman 3659febd042SHarvey Harrison static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space) 366866b8695SGreg Kroah-Hartman { 367866b8695SGreg Kroah-Hartman u8 *buf; 368866b8695SGreg Kroah-Hartman u16 mem = 0x3e00; 369866b8695SGreg Kroah-Hartman unsigned int addr = 0x19; 370866b8695SGreg Kroah-Hartman int size = 0, i, off = 0, chunk; 371866b8695SGreg Kroah-Hartman 3727a6cb0d5SJulia Lawall buf = kzalloc(4096, GFP_KERNEL); 373535ec049SJoe Perches if (buf == NULL) 3745bcc0dd7SJavier Martinez Canillas return -ENOMEM; 375866b8695SGreg Kroah-Hartman 376866b8695SGreg Kroah-Hartman for (i = 1; i < 32; ++i) { 377866b8695SGreg Kroah-Hartman mjpeg_frame_header(go, buf + size, i); 378866b8695SGreg Kroah-Hartman size += 80; 379866b8695SGreg Kroah-Hartman } 380866b8695SGreg Kroah-Hartman chunk = mjpeg_frame_header(go, buf + size, 1); 381866b8695SGreg Kroah-Hartman memmove(buf + size, buf + size + 80, chunk - 80); 382866b8695SGreg Kroah-Hartman size += chunk - 80; 383866b8695SGreg Kroah-Hartman 384866b8695SGreg Kroah-Hartman for (i = 0; i < size; i += chunk * 2) { 385866b8695SGreg Kroah-Hartman if (space - off < 32) { 386866b8695SGreg Kroah-Hartman off = -1; 387866b8695SGreg Kroah-Hartman goto done; 388866b8695SGreg Kroah-Hartman } 389866b8695SGreg Kroah-Hartman 390866b8695SGreg Kroah-Hartman code[off + 1] = __cpu_to_le16(0x8000 | mem); 391866b8695SGreg Kroah-Hartman 392866b8695SGreg Kroah-Hartman chunk = 28; 393866b8695SGreg Kroah-Hartman if (mem + chunk > 0x4000) 394866b8695SGreg Kroah-Hartman chunk = 0x4000 - mem; 395866b8695SGreg Kroah-Hartman if (i + 2 * chunk > size) 396866b8695SGreg Kroah-Hartman chunk = (size - i) / 2; 397866b8695SGreg Kroah-Hartman 398866b8695SGreg Kroah-Hartman if (chunk < 28) { 399866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x4000 | chunk); 400866b8695SGreg Kroah-Hartman code[off + 31] = __cpu_to_le16(addr++); 401866b8695SGreg Kroah-Hartman mem = 0x3e00; 402866b8695SGreg Kroah-Hartman } else { 403866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x1000 | 28); 404866b8695SGreg Kroah-Hartman code[off + 31] = 0; 405866b8695SGreg Kroah-Hartman mem += 28; 406866b8695SGreg Kroah-Hartman } 407866b8695SGreg Kroah-Hartman 408866b8695SGreg Kroah-Hartman memcpy(&code[off + 2], buf + i, chunk * 2); 409866b8695SGreg Kroah-Hartman off += 32; 410866b8695SGreg Kroah-Hartman } 411866b8695SGreg Kroah-Hartman done: 412866b8695SGreg Kroah-Hartman kfree(buf); 413866b8695SGreg Kroah-Hartman return off; 414866b8695SGreg Kroah-Hartman } 415866b8695SGreg Kroah-Hartman 416866b8695SGreg Kroah-Hartman static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf, 417866b8695SGreg Kroah-Hartman int modulo, int pict_struct, enum mpeg_frame_type frame) 418866b8695SGreg Kroah-Hartman { 419866b8695SGreg Kroah-Hartman int i, j, mb_code, mb_len; 420866b8695SGreg Kroah-Hartman int rows = go->interlace_coding ? go->height / 32 : go->height / 16; 421866b8695SGreg Kroah-Hartman CODE_GEN(c, buf + 6); 422866b8695SGreg Kroah-Hartman 423866b8695SGreg Kroah-Hartman switch (frame) { 424866b8695SGreg Kroah-Hartman case PFRAME: 425866b8695SGreg Kroah-Hartman mb_code = 0x1; 426866b8695SGreg Kroah-Hartman mb_len = 3; 427866b8695SGreg Kroah-Hartman break; 428866b8695SGreg Kroah-Hartman case BFRAME_PRE: 429866b8695SGreg Kroah-Hartman mb_code = 0x2; 430866b8695SGreg Kroah-Hartman mb_len = 4; 431866b8695SGreg Kroah-Hartman break; 432866b8695SGreg Kroah-Hartman case BFRAME_POST: 433866b8695SGreg Kroah-Hartman mb_code = 0x2; 434866b8695SGreg Kroah-Hartman mb_len = 3; 435866b8695SGreg Kroah-Hartman break; 436866b8695SGreg Kroah-Hartman case BFRAME_BIDIR: 437866b8695SGreg Kroah-Hartman mb_code = 0x2; 438866b8695SGreg Kroah-Hartman mb_len = 2; 439866b8695SGreg Kroah-Hartman break; 440866b8695SGreg Kroah-Hartman default: /* keep the compiler happy */ 441866b8695SGreg Kroah-Hartman mb_code = mb_len = 0; 442866b8695SGreg Kroah-Hartman break; 443866b8695SGreg Kroah-Hartman } 444866b8695SGreg Kroah-Hartman 445866b8695SGreg Kroah-Hartman CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13); 446866b8695SGreg Kroah-Hartman CODE_ADD(c, 0xffff, 16); 44735d2d76dSHans Verkuil CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4); 448866b8695SGreg Kroah-Hartman if (frame != PFRAME) 44935d2d76dSHans Verkuil CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4); 450866b8695SGreg Kroah-Hartman else 451866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */ 452866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 3); /* What is this?? */ 453866b8695SGreg Kroah-Hartman /* Byte-align with zeros */ 454866b8695SGreg Kroah-Hartman j = 8 - (CODE_LENGTH(c) % 8); 455866b8695SGreg Kroah-Hartman if (j != 8) 456866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, j); 457866b8695SGreg Kroah-Hartman 45835d2d76dSHans Verkuil if (go->format == V4L2_PIX_FMT_MPEG2) { 459866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 24); 460866b8695SGreg Kroah-Hartman CODE_ADD(c, 0xb5, 8); 461866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x844, 12); 462866b8695SGreg Kroah-Hartman CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8); 463866b8695SGreg Kroah-Hartman if (go->interlace_coding) { 464866b8695SGreg Kroah-Hartman CODE_ADD(c, pict_struct, 4); 465866b8695SGreg Kroah-Hartman if (go->dvd_mode) 466866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x000, 11); 467866b8695SGreg Kroah-Hartman else 468866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x200, 11); 469866b8695SGreg Kroah-Hartman } else { 470866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 4); 471866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x20c, 11); 472866b8695SGreg Kroah-Hartman } 473866b8695SGreg Kroah-Hartman /* Byte-align with zeros */ 474866b8695SGreg Kroah-Hartman j = 8 - (CODE_LENGTH(c) % 8); 475866b8695SGreg Kroah-Hartman if (j != 8) 476866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, j); 477866b8695SGreg Kroah-Hartman } 478866b8695SGreg Kroah-Hartman 479866b8695SGreg Kroah-Hartman for (i = 0; i < rows; ++i) { 480866b8695SGreg Kroah-Hartman CODE_ADD(c, 1, 24); 481866b8695SGreg Kroah-Hartman CODE_ADD(c, i + 1, 8); 482866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x2, 6); 483866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 1); 484866b8695SGreg Kroah-Hartman CODE_ADD(c, mb_code, mb_len); 485866b8695SGreg Kroah-Hartman if (go->interlace_coding) { 486866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 2); 487866b8695SGreg Kroah-Hartman CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1); 488866b8695SGreg Kroah-Hartman } 489866b8695SGreg Kroah-Hartman if (frame == BFRAME_BIDIR) { 490866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 2); 491866b8695SGreg Kroah-Hartman if (go->interlace_coding) 492866b8695SGreg Kroah-Hartman CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1); 493866b8695SGreg Kroah-Hartman } 494866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 2); 495866b8695SGreg Kroah-Hartman for (j = (go->width >> 4) - 2; j >= 33; j -= 33) 496866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x8, 11); 497866b8695SGreg Kroah-Hartman CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]); 498866b8695SGreg Kroah-Hartman CODE_ADD(c, mb_code, mb_len); 499866b8695SGreg Kroah-Hartman if (go->interlace_coding) { 500866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 2); 501866b8695SGreg Kroah-Hartman CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1); 502866b8695SGreg Kroah-Hartman } 503866b8695SGreg Kroah-Hartman if (frame == BFRAME_BIDIR) { 504866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 2); 505866b8695SGreg Kroah-Hartman if (go->interlace_coding) 506866b8695SGreg Kroah-Hartman CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1); 507866b8695SGreg Kroah-Hartman } 508866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 2); 509866b8695SGreg Kroah-Hartman 510866b8695SGreg Kroah-Hartman /* Byte-align with zeros */ 511866b8695SGreg Kroah-Hartman j = 8 - (CODE_LENGTH(c) % 8); 512866b8695SGreg Kroah-Hartman if (j != 8) 513866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, j); 514866b8695SGreg Kroah-Hartman } 515866b8695SGreg Kroah-Hartman 516866b8695SGreg Kroah-Hartman i = CODE_LENGTH(c) + 4 * 8; 517866b8695SGreg Kroah-Hartman buf[2] = 0x00; 518866b8695SGreg Kroah-Hartman buf[3] = 0x00; 519866b8695SGreg Kroah-Hartman buf[4] = 0x01; 520866b8695SGreg Kroah-Hartman buf[5] = 0x00; 521866b8695SGreg Kroah-Hartman return i; 522866b8695SGreg Kroah-Hartman } 523866b8695SGreg Kroah-Hartman 524866b8695SGreg Kroah-Hartman static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext) 525866b8695SGreg Kroah-Hartman { 526866b8695SGreg Kroah-Hartman int i, aspect_ratio, picture_rate; 527866b8695SGreg Kroah-Hartman CODE_GEN(c, buf + 6); 528866b8695SGreg Kroah-Hartman 52935d2d76dSHans Verkuil if (go->format == V4L2_PIX_FMT_MPEG1) { 530866b8695SGreg Kroah-Hartman switch (go->aspect_ratio) { 531866b8695SGreg Kroah-Hartman case GO7007_RATIO_4_3: 532866b8695SGreg Kroah-Hartman aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2; 533866b8695SGreg Kroah-Hartman break; 534866b8695SGreg Kroah-Hartman case GO7007_RATIO_16_9: 535866b8695SGreg Kroah-Hartman aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4; 536866b8695SGreg Kroah-Hartman break; 537866b8695SGreg Kroah-Hartman default: 538866b8695SGreg Kroah-Hartman aspect_ratio = 1; 539866b8695SGreg Kroah-Hartman break; 540866b8695SGreg Kroah-Hartman } 541866b8695SGreg Kroah-Hartman } else { 542866b8695SGreg Kroah-Hartman switch (go->aspect_ratio) { 543866b8695SGreg Kroah-Hartman case GO7007_RATIO_4_3: 544866b8695SGreg Kroah-Hartman aspect_ratio = 2; 545866b8695SGreg Kroah-Hartman break; 546866b8695SGreg Kroah-Hartman case GO7007_RATIO_16_9: 547866b8695SGreg Kroah-Hartman aspect_ratio = 3; 548866b8695SGreg Kroah-Hartman break; 549866b8695SGreg Kroah-Hartman default: 550866b8695SGreg Kroah-Hartman aspect_ratio = 1; 551866b8695SGreg Kroah-Hartman break; 552866b8695SGreg Kroah-Hartman } 553866b8695SGreg Kroah-Hartman } 554866b8695SGreg Kroah-Hartman switch (go->sensor_framerate) { 555866b8695SGreg Kroah-Hartman case 24000: 556866b8695SGreg Kroah-Hartman picture_rate = 1; 557866b8695SGreg Kroah-Hartman break; 558866b8695SGreg Kroah-Hartman case 24024: 559866b8695SGreg Kroah-Hartman picture_rate = 2; 560866b8695SGreg Kroah-Hartman break; 561866b8695SGreg Kroah-Hartman case 25025: 562866b8695SGreg Kroah-Hartman picture_rate = go->interlace_coding ? 6 : 3; 563866b8695SGreg Kroah-Hartman break; 564866b8695SGreg Kroah-Hartman case 30000: 565866b8695SGreg Kroah-Hartman picture_rate = go->interlace_coding ? 7 : 4; 566866b8695SGreg Kroah-Hartman break; 567866b8695SGreg Kroah-Hartman case 30030: 568866b8695SGreg Kroah-Hartman picture_rate = go->interlace_coding ? 8 : 5; 569866b8695SGreg Kroah-Hartman break; 570866b8695SGreg Kroah-Hartman default: 571866b8695SGreg Kroah-Hartman picture_rate = 5; /* 30 fps seems like a reasonable default */ 572866b8695SGreg Kroah-Hartman break; 573866b8695SGreg Kroah-Hartman } 574866b8695SGreg Kroah-Hartman 575866b8695SGreg Kroah-Hartman CODE_ADD(c, go->width, 12); 576866b8695SGreg Kroah-Hartman CODE_ADD(c, go->height, 12); 577866b8695SGreg Kroah-Hartman CODE_ADD(c, aspect_ratio, 4); 578866b8695SGreg Kroah-Hartman CODE_ADD(c, picture_rate, 4); 57935d2d76dSHans Verkuil CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 20000 : 0x3ffff, 18); 580866b8695SGreg Kroah-Hartman CODE_ADD(c, 1, 1); 58135d2d76dSHans Verkuil CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 112 : 20, 10); 582866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 3); 583866b8695SGreg Kroah-Hartman 584866b8695SGreg Kroah-Hartman /* Byte-align with zeros */ 585866b8695SGreg Kroah-Hartman i = 8 - (CODE_LENGTH(c) % 8); 586866b8695SGreg Kroah-Hartman if (i != 8) 587866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, i); 588866b8695SGreg Kroah-Hartman 58935d2d76dSHans Verkuil if (go->format == V4L2_PIX_FMT_MPEG2) { 590866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 24); 591866b8695SGreg Kroah-Hartman CODE_ADD(c, 0xb5, 8); 592866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x148, 12); 593866b8695SGreg Kroah-Hartman if (go->interlace_coding) 594866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x20001, 20); 595866b8695SGreg Kroah-Hartman else 596866b8695SGreg Kroah-Hartman CODE_ADD(c, 0xa0001, 20); 597866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 16); 598866b8695SGreg Kroah-Hartman 599866b8695SGreg Kroah-Hartman /* Byte-align with zeros */ 600866b8695SGreg Kroah-Hartman i = 8 - (CODE_LENGTH(c) % 8); 601866b8695SGreg Kroah-Hartman if (i != 8) 602866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, i); 603866b8695SGreg Kroah-Hartman 604866b8695SGreg Kroah-Hartman if (ext) { 605866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 24); 606866b8695SGreg Kroah-Hartman CODE_ADD(c, 0xb52, 12); 607866b8695SGreg Kroah-Hartman CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3); 608866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x105, 9); 609866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x505, 16); 610866b8695SGreg Kroah-Hartman CODE_ADD(c, go->width, 14); 611866b8695SGreg Kroah-Hartman CODE_ADD(c, 1, 1); 612866b8695SGreg Kroah-Hartman CODE_ADD(c, go->height, 14); 613866b8695SGreg Kroah-Hartman 614866b8695SGreg Kroah-Hartman /* Byte-align with zeros */ 615866b8695SGreg Kroah-Hartman i = 8 - (CODE_LENGTH(c) % 8); 616866b8695SGreg Kroah-Hartman if (i != 8) 617866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, i); 618866b8695SGreg Kroah-Hartman } 619866b8695SGreg Kroah-Hartman } 620866b8695SGreg Kroah-Hartman 621866b8695SGreg Kroah-Hartman i = CODE_LENGTH(c) + 4 * 8; 622866b8695SGreg Kroah-Hartman buf[0] = i & 0xff; 623866b8695SGreg Kroah-Hartman buf[1] = i >> 8; 624866b8695SGreg Kroah-Hartman buf[2] = 0x00; 625866b8695SGreg Kroah-Hartman buf[3] = 0x00; 626866b8695SGreg Kroah-Hartman buf[4] = 0x01; 627866b8695SGreg Kroah-Hartman buf[5] = 0xb3; 628866b8695SGreg Kroah-Hartman return i; 629866b8695SGreg Kroah-Hartman } 630866b8695SGreg Kroah-Hartman 631866b8695SGreg Kroah-Hartman static int gen_mpeg1hdr_to_package(struct go7007 *go, 6329febd042SHarvey Harrison __le16 *code, int space, int *framelen) 633866b8695SGreg Kroah-Hartman { 634866b8695SGreg Kroah-Hartman u8 *buf; 635866b8695SGreg Kroah-Hartman u16 mem = 0x3e00; 636866b8695SGreg Kroah-Hartman unsigned int addr = 0x19; 637866b8695SGreg Kroah-Hartman int i, off = 0, chunk; 638866b8695SGreg Kroah-Hartman 6397a6cb0d5SJulia Lawall buf = kzalloc(5120, GFP_KERNEL); 640535ec049SJoe Perches if (buf == NULL) 6415bcc0dd7SJavier Martinez Canillas return -ENOMEM; 642535ec049SJoe Perches 643866b8695SGreg Kroah-Hartman framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME); 644866b8695SGreg Kroah-Hartman if (go->interlace_coding) 645866b8695SGreg Kroah-Hartman framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8, 646866b8695SGreg Kroah-Hartman 0, 2, PFRAME); 647866b8695SGreg Kroah-Hartman buf[0] = framelen[0] & 0xff; 648866b8695SGreg Kroah-Hartman buf[1] = framelen[0] >> 8; 649866b8695SGreg Kroah-Hartman i = 368; 650866b8695SGreg Kroah-Hartman framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE); 651866b8695SGreg Kroah-Hartman if (go->interlace_coding) 652866b8695SGreg Kroah-Hartman framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8, 653866b8695SGreg Kroah-Hartman 0, 2, BFRAME_PRE); 654866b8695SGreg Kroah-Hartman buf[i] = framelen[1] & 0xff; 655866b8695SGreg Kroah-Hartman buf[i + 1] = framelen[1] >> 8; 656866b8695SGreg Kroah-Hartman i += 1632; 657866b8695SGreg Kroah-Hartman framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST); 658866b8695SGreg Kroah-Hartman if (go->interlace_coding) 659866b8695SGreg Kroah-Hartman framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8, 660866b8695SGreg Kroah-Hartman 0, 2, BFRAME_POST); 661866b8695SGreg Kroah-Hartman buf[i] = framelen[2] & 0xff; 662866b8695SGreg Kroah-Hartman buf[i + 1] = framelen[2] >> 8; 663866b8695SGreg Kroah-Hartman i += 1432; 664866b8695SGreg Kroah-Hartman framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR); 665866b8695SGreg Kroah-Hartman if (go->interlace_coding) 666866b8695SGreg Kroah-Hartman framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8, 667866b8695SGreg Kroah-Hartman 0, 2, BFRAME_BIDIR); 668866b8695SGreg Kroah-Hartman buf[i] = framelen[3] & 0xff; 669866b8695SGreg Kroah-Hartman buf[i + 1] = framelen[3] >> 8; 670866b8695SGreg Kroah-Hartman i += 1632 + 16; 671866b8695SGreg Kroah-Hartman mpeg1_sequence_header(go, buf + i, 0); 672866b8695SGreg Kroah-Hartman i += 40; 673866b8695SGreg Kroah-Hartman for (i = 0; i < 5120; i += chunk * 2) { 674866b8695SGreg Kroah-Hartman if (space - off < 32) { 675866b8695SGreg Kroah-Hartman off = -1; 676866b8695SGreg Kroah-Hartman goto done; 677866b8695SGreg Kroah-Hartman } 678866b8695SGreg Kroah-Hartman 679866b8695SGreg Kroah-Hartman code[off + 1] = __cpu_to_le16(0x8000 | mem); 680866b8695SGreg Kroah-Hartman 681866b8695SGreg Kroah-Hartman chunk = 28; 682866b8695SGreg Kroah-Hartman if (mem + chunk > 0x4000) 683866b8695SGreg Kroah-Hartman chunk = 0x4000 - mem; 684866b8695SGreg Kroah-Hartman if (i + 2 * chunk > 5120) 685866b8695SGreg Kroah-Hartman chunk = (5120 - i) / 2; 686866b8695SGreg Kroah-Hartman 687866b8695SGreg Kroah-Hartman if (chunk < 28) { 688866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x4000 | chunk); 689866b8695SGreg Kroah-Hartman code[off + 31] = __cpu_to_le16(addr); 690866b8695SGreg Kroah-Hartman if (mem + chunk == 0x4000) { 691866b8695SGreg Kroah-Hartman mem = 0x3e00; 692866b8695SGreg Kroah-Hartman ++addr; 693866b8695SGreg Kroah-Hartman } 694866b8695SGreg Kroah-Hartman } else { 695866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x1000 | 28); 696866b8695SGreg Kroah-Hartman code[off + 31] = 0; 697866b8695SGreg Kroah-Hartman mem += 28; 698866b8695SGreg Kroah-Hartman } 699866b8695SGreg Kroah-Hartman 700866b8695SGreg Kroah-Hartman memcpy(&code[off + 2], buf + i, chunk * 2); 701866b8695SGreg Kroah-Hartman off += 32; 702866b8695SGreg Kroah-Hartman } 703866b8695SGreg Kroah-Hartman done: 704866b8695SGreg Kroah-Hartman kfree(buf); 705866b8695SGreg Kroah-Hartman return off; 706866b8695SGreg Kroah-Hartman } 707866b8695SGreg Kroah-Hartman 708866b8695SGreg Kroah-Hartman static int vti_bitlen(struct go7007 *go) 709866b8695SGreg Kroah-Hartman { 710866b8695SGreg Kroah-Hartman unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale; 711866b8695SGreg Kroah-Hartman 7125c72afd8SHimangi Saraogi for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i) 7135c72afd8SHimangi Saraogi ; 714866b8695SGreg Kroah-Hartman return i + 1; 715866b8695SGreg Kroah-Hartman } 716866b8695SGreg Kroah-Hartman 717866b8695SGreg Kroah-Hartman static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf, 718866b8695SGreg Kroah-Hartman int modulo, enum mpeg_frame_type frame) 719866b8695SGreg Kroah-Hartman { 720866b8695SGreg Kroah-Hartman int i; 721866b8695SGreg Kroah-Hartman CODE_GEN(c, buf + 6); 722866b8695SGreg Kroah-Hartman int mb_count = (go->width >> 4) * (go->height >> 4); 723866b8695SGreg Kroah-Hartman 724866b8695SGreg Kroah-Hartman CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2); 725866b8695SGreg Kroah-Hartman if (modulo) 726866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 1); 727866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 2); 728866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, vti_bitlen(go)); 729866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 2); 730866b8695SGreg Kroah-Hartman if (frame == PFRAME) 731866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 1); 732866b8695SGreg Kroah-Hartman CODE_ADD(c, 0xc, 11); 733866b8695SGreg Kroah-Hartman if (frame != PFRAME) 734866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x4, 3); 735866b8695SGreg Kroah-Hartman if (frame != BFRAME_EMPTY) { 736866b8695SGreg Kroah-Hartman for (i = 0; i < mb_count; ++i) { 737866b8695SGreg Kroah-Hartman switch (frame) { 738866b8695SGreg Kroah-Hartman case PFRAME: 739866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 1); 740866b8695SGreg Kroah-Hartman break; 741866b8695SGreg Kroah-Hartman case BFRAME_PRE: 742866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x47, 8); 743866b8695SGreg Kroah-Hartman break; 744866b8695SGreg Kroah-Hartman case BFRAME_POST: 745866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x27, 7); 746866b8695SGreg Kroah-Hartman break; 747866b8695SGreg Kroah-Hartman case BFRAME_BIDIR: 748866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x5f, 8); 749866b8695SGreg Kroah-Hartman break; 750866b8695SGreg Kroah-Hartman case BFRAME_EMPTY: /* keep compiler quiet */ 751866b8695SGreg Kroah-Hartman break; 752866b8695SGreg Kroah-Hartman } 753866b8695SGreg Kroah-Hartman } 754866b8695SGreg Kroah-Hartman } 755866b8695SGreg Kroah-Hartman 756866b8695SGreg Kroah-Hartman /* Byte-align with a zero followed by ones */ 757866b8695SGreg Kroah-Hartman i = 8 - (CODE_LENGTH(c) % 8); 758866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 1); 759866b8695SGreg Kroah-Hartman CODE_ADD(c, (1 << (i - 1)) - 1, i - 1); 760866b8695SGreg Kroah-Hartman 761866b8695SGreg Kroah-Hartman i = CODE_LENGTH(c) + 4 * 8; 762866b8695SGreg Kroah-Hartman buf[0] = i & 0xff; 763866b8695SGreg Kroah-Hartman buf[1] = i >> 8; 764866b8695SGreg Kroah-Hartman buf[2] = 0x00; 765866b8695SGreg Kroah-Hartman buf[3] = 0x00; 766866b8695SGreg Kroah-Hartman buf[4] = 0x01; 767866b8695SGreg Kroah-Hartman buf[5] = 0xb6; 768866b8695SGreg Kroah-Hartman return i; 769866b8695SGreg Kroah-Hartman } 770866b8695SGreg Kroah-Hartman 771866b8695SGreg Kroah-Hartman static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext) 772866b8695SGreg Kroah-Hartman { 773866b8695SGreg Kroah-Hartman const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali, 774866b8695SGreg Kroah-Hartman 0x00, 0x00, 0x01, 0xb5, 0x09, 775866b8695SGreg Kroah-Hartman 0x00, 0x00, 0x01, 0x00, 776866b8695SGreg Kroah-Hartman 0x00, 0x00, 0x01, 0x20, }; 777866b8695SGreg Kroah-Hartman int i, aspect_ratio; 778866b8695SGreg Kroah-Hartman int fps = go->sensor_framerate / go->fps_scale; 779866b8695SGreg Kroah-Hartman CODE_GEN(c, buf + 2 + sizeof(head)); 780866b8695SGreg Kroah-Hartman 781866b8695SGreg Kroah-Hartman switch (go->aspect_ratio) { 782866b8695SGreg Kroah-Hartman case GO7007_RATIO_4_3: 783866b8695SGreg Kroah-Hartman aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2; 784866b8695SGreg Kroah-Hartman break; 785866b8695SGreg Kroah-Hartman case GO7007_RATIO_16_9: 786866b8695SGreg Kroah-Hartman aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4; 787866b8695SGreg Kroah-Hartman break; 788866b8695SGreg Kroah-Hartman default: 789866b8695SGreg Kroah-Hartman aspect_ratio = 1; 790866b8695SGreg Kroah-Hartman break; 791866b8695SGreg Kroah-Hartman } 792866b8695SGreg Kroah-Hartman 793866b8695SGreg Kroah-Hartman memcpy(buf + 2, head, sizeof(head)); 794866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x191, 17); 795866b8695SGreg Kroah-Hartman CODE_ADD(c, aspect_ratio, 4); 796866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x1, 4); 797866b8695SGreg Kroah-Hartman CODE_ADD(c, fps, 16); 798866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x3, 2); 799866b8695SGreg Kroah-Hartman CODE_ADD(c, 1001, vti_bitlen(go)); 800866b8695SGreg Kroah-Hartman CODE_ADD(c, 1, 1); 801866b8695SGreg Kroah-Hartman CODE_ADD(c, go->width, 13); 802866b8695SGreg Kroah-Hartman CODE_ADD(c, 1, 1); 803866b8695SGreg Kroah-Hartman CODE_ADD(c, go->height, 13); 804866b8695SGreg Kroah-Hartman CODE_ADD(c, 0x2830, 14); 805866b8695SGreg Kroah-Hartman 806866b8695SGreg Kroah-Hartman /* Byte-align */ 807866b8695SGreg Kroah-Hartman i = 8 - (CODE_LENGTH(c) % 8); 808866b8695SGreg Kroah-Hartman CODE_ADD(c, 0, 1); 809866b8695SGreg Kroah-Hartman CODE_ADD(c, (1 << (i - 1)) - 1, i - 1); 810866b8695SGreg Kroah-Hartman 811866b8695SGreg Kroah-Hartman i = CODE_LENGTH(c) + sizeof(head) * 8; 812866b8695SGreg Kroah-Hartman buf[0] = i & 0xff; 813866b8695SGreg Kroah-Hartman buf[1] = i >> 8; 814866b8695SGreg Kroah-Hartman return i; 815866b8695SGreg Kroah-Hartman } 816866b8695SGreg Kroah-Hartman 817866b8695SGreg Kroah-Hartman static int gen_mpeg4hdr_to_package(struct go7007 *go, 8189febd042SHarvey Harrison __le16 *code, int space, int *framelen) 819866b8695SGreg Kroah-Hartman { 820866b8695SGreg Kroah-Hartman u8 *buf; 821866b8695SGreg Kroah-Hartman u16 mem = 0x3e00; 822866b8695SGreg Kroah-Hartman unsigned int addr = 0x19; 823866b8695SGreg Kroah-Hartman int i, off = 0, chunk; 824866b8695SGreg Kroah-Hartman 8257a6cb0d5SJulia Lawall buf = kzalloc(5120, GFP_KERNEL); 826535ec049SJoe Perches if (buf == NULL) 8275bcc0dd7SJavier Martinez Canillas return -ENOMEM; 828535ec049SJoe Perches 829866b8695SGreg Kroah-Hartman framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME); 830866b8695SGreg Kroah-Hartman i = 368; 831866b8695SGreg Kroah-Hartman framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE); 832866b8695SGreg Kroah-Hartman i += 1632; 833866b8695SGreg Kroah-Hartman framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST); 834866b8695SGreg Kroah-Hartman i += 1432; 835866b8695SGreg Kroah-Hartman framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR); 836866b8695SGreg Kroah-Hartman i += 1632; 837866b8695SGreg Kroah-Hartman mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY); 838866b8695SGreg Kroah-Hartman i += 16; 839866b8695SGreg Kroah-Hartman mpeg4_sequence_header(go, buf + i, 0); 840866b8695SGreg Kroah-Hartman i += 40; 841866b8695SGreg Kroah-Hartman for (i = 0; i < 5120; i += chunk * 2) { 842866b8695SGreg Kroah-Hartman if (space - off < 32) { 843866b8695SGreg Kroah-Hartman off = -1; 844866b8695SGreg Kroah-Hartman goto done; 845866b8695SGreg Kroah-Hartman } 846866b8695SGreg Kroah-Hartman 847866b8695SGreg Kroah-Hartman code[off + 1] = __cpu_to_le16(0x8000 | mem); 848866b8695SGreg Kroah-Hartman 849866b8695SGreg Kroah-Hartman chunk = 28; 850866b8695SGreg Kroah-Hartman if (mem + chunk > 0x4000) 851866b8695SGreg Kroah-Hartman chunk = 0x4000 - mem; 852866b8695SGreg Kroah-Hartman if (i + 2 * chunk > 5120) 853866b8695SGreg Kroah-Hartman chunk = (5120 - i) / 2; 854866b8695SGreg Kroah-Hartman 855866b8695SGreg Kroah-Hartman if (chunk < 28) { 856866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x4000 | chunk); 857866b8695SGreg Kroah-Hartman code[off + 31] = __cpu_to_le16(addr); 858866b8695SGreg Kroah-Hartman if (mem + chunk == 0x4000) { 859866b8695SGreg Kroah-Hartman mem = 0x3e00; 860866b8695SGreg Kroah-Hartman ++addr; 861866b8695SGreg Kroah-Hartman } 862866b8695SGreg Kroah-Hartman } else { 863866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x1000 | 28); 864866b8695SGreg Kroah-Hartman code[off + 31] = 0; 865866b8695SGreg Kroah-Hartman mem += 28; 866866b8695SGreg Kroah-Hartman } 867866b8695SGreg Kroah-Hartman 868866b8695SGreg Kroah-Hartman memcpy(&code[off + 2], buf + i, chunk * 2); 869866b8695SGreg Kroah-Hartman off += 32; 870866b8695SGreg Kroah-Hartman } 871866b8695SGreg Kroah-Hartman mem = 0x3e00; 872866b8695SGreg Kroah-Hartman addr = go->ipb ? 0x14f9 : 0x0af9; 873866b8695SGreg Kroah-Hartman memset(buf, 0, 5120); 874866b8695SGreg Kroah-Hartman framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME); 875866b8695SGreg Kroah-Hartman i = 368; 876866b8695SGreg Kroah-Hartman framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE); 877866b8695SGreg Kroah-Hartman i += 1632; 878866b8695SGreg Kroah-Hartman framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST); 879866b8695SGreg Kroah-Hartman i += 1432; 880866b8695SGreg Kroah-Hartman framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR); 881866b8695SGreg Kroah-Hartman i += 1632; 882866b8695SGreg Kroah-Hartman mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY); 883866b8695SGreg Kroah-Hartman i += 16; 884866b8695SGreg Kroah-Hartman for (i = 0; i < 5120; i += chunk * 2) { 885866b8695SGreg Kroah-Hartman if (space - off < 32) { 886866b8695SGreg Kroah-Hartman off = -1; 887866b8695SGreg Kroah-Hartman goto done; 888866b8695SGreg Kroah-Hartman } 889866b8695SGreg Kroah-Hartman 890866b8695SGreg Kroah-Hartman code[off + 1] = __cpu_to_le16(0x8000 | mem); 891866b8695SGreg Kroah-Hartman 892866b8695SGreg Kroah-Hartman chunk = 28; 893866b8695SGreg Kroah-Hartman if (mem + chunk > 0x4000) 894866b8695SGreg Kroah-Hartman chunk = 0x4000 - mem; 895866b8695SGreg Kroah-Hartman if (i + 2 * chunk > 5120) 896866b8695SGreg Kroah-Hartman chunk = (5120 - i) / 2; 897866b8695SGreg Kroah-Hartman 898866b8695SGreg Kroah-Hartman if (chunk < 28) { 899866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x4000 | chunk); 900866b8695SGreg Kroah-Hartman code[off + 31] = __cpu_to_le16(addr); 901866b8695SGreg Kroah-Hartman if (mem + chunk == 0x4000) { 902866b8695SGreg Kroah-Hartman mem = 0x3e00; 903866b8695SGreg Kroah-Hartman ++addr; 904866b8695SGreg Kroah-Hartman } 905866b8695SGreg Kroah-Hartman } else { 906866b8695SGreg Kroah-Hartman code[off] = __cpu_to_le16(0x1000 | 28); 907866b8695SGreg Kroah-Hartman code[off + 31] = 0; 908866b8695SGreg Kroah-Hartman mem += 28; 909866b8695SGreg Kroah-Hartman } 910866b8695SGreg Kroah-Hartman 911866b8695SGreg Kroah-Hartman memcpy(&code[off + 2], buf + i, chunk * 2); 912866b8695SGreg Kroah-Hartman off += 32; 913866b8695SGreg Kroah-Hartman } 914866b8695SGreg Kroah-Hartman done: 915866b8695SGreg Kroah-Hartman kfree(buf); 916866b8695SGreg Kroah-Hartman return off; 917866b8695SGreg Kroah-Hartman } 918866b8695SGreg Kroah-Hartman 919866b8695SGreg Kroah-Hartman static int brctrl_to_package(struct go7007 *go, 9209febd042SHarvey Harrison __le16 *code, int space, int *framelen) 921866b8695SGreg Kroah-Hartman { 922866b8695SGreg Kroah-Hartman int converge_speed = 0; 92335d2d76dSHans Verkuil int lambda = (go->format == V4L2_PIX_FMT_MJPEG || go->dvd_mode) ? 924866b8695SGreg Kroah-Hartman 100 : 0; 925866b8695SGreg Kroah-Hartman int peak_rate = 6 * go->bitrate / 5; 92635d2d76dSHans Verkuil int vbv_buffer = go->format == V4L2_PIX_FMT_MJPEG ? 927866b8695SGreg Kroah-Hartman go->bitrate : 928866b8695SGreg Kroah-Hartman (go->dvd_mode ? 900000 : peak_rate); 929866b8695SGreg Kroah-Hartman int fps = go->sensor_framerate / go->fps_scale; 930866b8695SGreg Kroah-Hartman int q = 0; 931866b8695SGreg Kroah-Hartman /* Bizarre math below depends on rounding errors in division */ 932866b8695SGreg Kroah-Hartman u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps; 933866b8695SGreg Kroah-Hartman u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps; 934866b8695SGreg Kroah-Hartman u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000); 935866b8695SGreg Kroah-Hartman u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32); 936866b8695SGreg Kroah-Hartman u32 cplx[] = { 937866b8695SGreg Kroah-Hartman q > 0 ? sgop_expt_addr * q : 938866b8695SGreg Kroah-Hartman 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32, 939866b8695SGreg Kroah-Hartman q > 0 ? sgop_expt_addr * q : 940866b8695SGreg Kroah-Hartman 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32, 941866b8695SGreg Kroah-Hartman q > 0 ? sgop_expt_addr * q : 942866b8695SGreg Kroah-Hartman 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32, 943866b8695SGreg Kroah-Hartman q > 0 ? sgop_expt_addr * q : 944866b8695SGreg Kroah-Hartman 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32, 945866b8695SGreg Kroah-Hartman }; 946866b8695SGreg Kroah-Hartman u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr; 947866b8695SGreg Kroah-Hartman u16 pack[] = { 948866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 949866b8695SGreg Kroah-Hartman 0xBF20, go->ipb ? converge_speed_ipb[converge_speed] 950866b8695SGreg Kroah-Hartman : converge_speed_ip[converge_speed], 951866b8695SGreg Kroah-Hartman 0xBF21, go->ipb ? 2 : 0, 952866b8695SGreg Kroah-Hartman 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50] 953866b8695SGreg Kroah-Hartman : 32767, 954866b8695SGreg Kroah-Hartman 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767, 955866b8695SGreg Kroah-Hartman 0xBF24, 32767, 956866b8695SGreg Kroah-Hartman 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda], 957866b8695SGreg Kroah-Hartman 0xBF26, sgop_expt_addr & 0x0000FFFF, 958866b8695SGreg Kroah-Hartman 0xBF27, sgop_expt_addr >> 16, 959866b8695SGreg Kroah-Hartman 0xBF28, sgop_peak_addr & 0x0000FFFF, 960866b8695SGreg Kroah-Hartman 0xBF29, sgop_peak_addr >> 16, 961866b8695SGreg Kroah-Hartman 0xBF2A, vbv_alert_addr & 0x0000FFFF, 962866b8695SGreg Kroah-Hartman 0xBF2B, vbv_alert_addr >> 16, 963866b8695SGreg Kroah-Hartman 0xBF2C, 0, 964866b8695SGreg Kroah-Hartman 0xBF2D, 0, 965866b8695SGreg Kroah-Hartman 0, 0, 966866b8695SGreg Kroah-Hartman 967866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 968866b8695SGreg Kroah-Hartman 0xBF2E, vbv_alert_addr & 0x0000FFFF, 969866b8695SGreg Kroah-Hartman 0xBF2F, vbv_alert_addr >> 16, 970866b8695SGreg Kroah-Hartman 0xBF30, cplx[0] & 0x0000FFFF, 971866b8695SGreg Kroah-Hartman 0xBF31, cplx[0] >> 16, 972866b8695SGreg Kroah-Hartman 0xBF32, cplx[1] & 0x0000FFFF, 973866b8695SGreg Kroah-Hartman 0xBF33, cplx[1] >> 16, 974866b8695SGreg Kroah-Hartman 0xBF34, cplx[2] & 0x0000FFFF, 975866b8695SGreg Kroah-Hartman 0xBF35, cplx[2] >> 16, 976866b8695SGreg Kroah-Hartman 0xBF36, cplx[3] & 0x0000FFFF, 977866b8695SGreg Kroah-Hartman 0xBF37, cplx[3] >> 16, 978866b8695SGreg Kroah-Hartman 0xBF38, 0, 979866b8695SGreg Kroah-Hartman 0xBF39, 0, 980866b8695SGreg Kroah-Hartman 0xBF3A, total_expt_addr & 0x0000FFFF, 981866b8695SGreg Kroah-Hartman 0xBF3B, total_expt_addr >> 16, 982866b8695SGreg Kroah-Hartman 0, 0, 983866b8695SGreg Kroah-Hartman 984866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 985866b8695SGreg Kroah-Hartman 0xBF3C, total_expt_addr & 0x0000FFFF, 986866b8695SGreg Kroah-Hartman 0xBF3D, total_expt_addr >> 16, 987866b8695SGreg Kroah-Hartman 0xBF3E, 0, 988866b8695SGreg Kroah-Hartman 0xBF3F, 0, 989866b8695SGreg Kroah-Hartman 0xBF48, 0, 990866b8695SGreg Kroah-Hartman 0xBF49, 0, 991866b8695SGreg Kroah-Hartman 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q), 992866b8695SGreg Kroah-Hartman 0xBF4B, 4, 993866b8695SGreg Kroah-Hartman 0xBF4C, 0, 994866b8695SGreg Kroah-Hartman 0xBF4D, 0, 995866b8695SGreg Kroah-Hartman 0xBF4E, 0, 996866b8695SGreg Kroah-Hartman 0xBF4F, 0, 997866b8695SGreg Kroah-Hartman 0xBF50, 0, 998866b8695SGreg Kroah-Hartman 0xBF51, 0, 999866b8695SGreg Kroah-Hartman 0, 0, 1000866b8695SGreg Kroah-Hartman 1001866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 1002866b8695SGreg Kroah-Hartman 0xBF40, sgop_expt_addr & 0x0000FFFF, 1003866b8695SGreg Kroah-Hartman 0xBF41, sgop_expt_addr >> 16, 1004866b8695SGreg Kroah-Hartman 0xBF42, 0, 1005866b8695SGreg Kroah-Hartman 0xBF43, 0, 1006866b8695SGreg Kroah-Hartman 0xBF44, 0, 1007866b8695SGreg Kroah-Hartman 0xBF45, 0, 1008866b8695SGreg Kroah-Hartman 0xBF46, (go->width >> 4) * (go->height >> 4), 1009866b8695SGreg Kroah-Hartman 0xBF47, 0, 1010866b8695SGreg Kroah-Hartman 0xBF64, 0, 1011866b8695SGreg Kroah-Hartman 0xBF65, 0, 1012866b8695SGreg Kroah-Hartman 0xBF18, framelen[4], 1013866b8695SGreg Kroah-Hartman 0xBF19, framelen[5], 1014866b8695SGreg Kroah-Hartman 0xBF1A, framelen[6], 1015866b8695SGreg Kroah-Hartman 0xBF1B, framelen[7], 1016866b8695SGreg Kroah-Hartman 0, 0, 1017866b8695SGreg Kroah-Hartman 1018028d4c98SMauro Carvalho Chehab #if 0 1019028d4c98SMauro Carvalho Chehab /* Remove once we don't care about matching */ 1020866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 1021866b8695SGreg Kroah-Hartman 0xBF56, 4, 1022866b8695SGreg Kroah-Hartman 0xBF57, 0, 1023866b8695SGreg Kroah-Hartman 0xBF58, 5, 1024866b8695SGreg Kroah-Hartman 0xBF59, 0, 1025866b8695SGreg Kroah-Hartman 0xBF5A, 6, 1026866b8695SGreg Kroah-Hartman 0xBF5B, 0, 1027866b8695SGreg Kroah-Hartman 0xBF5C, 8, 1028866b8695SGreg Kroah-Hartman 0xBF5D, 0, 1029866b8695SGreg Kroah-Hartman 0xBF5E, 1, 1030866b8695SGreg Kroah-Hartman 0xBF5F, 0, 1031866b8695SGreg Kroah-Hartman 0xBF60, 1, 1032866b8695SGreg Kroah-Hartman 0xBF61, 0, 1033866b8695SGreg Kroah-Hartman 0xBF62, 0, 1034866b8695SGreg Kroah-Hartman 0xBF63, 0, 1035866b8695SGreg Kroah-Hartman 0, 0, 1036866b8695SGreg Kroah-Hartman #else 1037866b8695SGreg Kroah-Hartman 0x2008, 0x0000, 1038866b8695SGreg Kroah-Hartman 0xBF56, 4, 1039866b8695SGreg Kroah-Hartman 0xBF57, 0, 1040866b8695SGreg Kroah-Hartman 0xBF58, 5, 1041866b8695SGreg Kroah-Hartman 0xBF59, 0, 1042866b8695SGreg Kroah-Hartman 0xBF5A, 6, 1043866b8695SGreg Kroah-Hartman 0xBF5B, 0, 1044866b8695SGreg Kroah-Hartman 0xBF5C, 8, 1045866b8695SGreg Kroah-Hartman 0xBF5D, 0, 1046866b8695SGreg Kroah-Hartman 0, 0, 1047866b8695SGreg Kroah-Hartman 0, 0, 1048866b8695SGreg Kroah-Hartman 0, 0, 1049866b8695SGreg Kroah-Hartman 0, 0, 1050866b8695SGreg Kroah-Hartman 0, 0, 1051866b8695SGreg Kroah-Hartman 0, 0, 1052866b8695SGreg Kroah-Hartman 0, 0, 1053866b8695SGreg Kroah-Hartman #endif 1054866b8695SGreg Kroah-Hartman 1055866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 1056866b8695SGreg Kroah-Hartman 0xBF10, 0, 1057866b8695SGreg Kroah-Hartman 0xBF11, 0, 1058866b8695SGreg Kroah-Hartman 0xBF12, 0, 1059866b8695SGreg Kroah-Hartman 0xBF13, 0, 1060866b8695SGreg Kroah-Hartman 0xBF14, 0, 1061866b8695SGreg Kroah-Hartman 0xBF15, 0, 1062866b8695SGreg Kroah-Hartman 0xBF16, 0, 1063866b8695SGreg Kroah-Hartman 0xBF17, 0, 1064866b8695SGreg Kroah-Hartman 0xBF7E, 0, 1065866b8695SGreg Kroah-Hartman 0xBF7F, 1, 1066866b8695SGreg Kroah-Hartman 0xBF52, framelen[0], 1067866b8695SGreg Kroah-Hartman 0xBF53, framelen[1], 1068866b8695SGreg Kroah-Hartman 0xBF54, framelen[2], 1069866b8695SGreg Kroah-Hartman 0xBF55, framelen[3], 1070866b8695SGreg Kroah-Hartman 0, 0, 1071866b8695SGreg Kroah-Hartman }; 1072866b8695SGreg Kroah-Hartman 1073866b8695SGreg Kroah-Hartman return copy_packages(code, pack, 6, space); 1074866b8695SGreg Kroah-Hartman } 1075866b8695SGreg Kroah-Hartman 10769febd042SHarvey Harrison static int config_package(struct go7007 *go, __le16 *code, int space) 1077866b8695SGreg Kroah-Hartman { 1078866b8695SGreg Kroah-Hartman int fps = go->sensor_framerate / go->fps_scale / 1000; 1079866b8695SGreg Kroah-Hartman int rows = go->interlace_coding ? go->height / 32 : go->height / 16; 1080866b8695SGreg Kroah-Hartman int brc_window_size = fps; 1081866b8695SGreg Kroah-Hartman int q_min = 2, q_max = 31; 1082866b8695SGreg Kroah-Hartman int THACCoeffSet0 = 0; 1083866b8695SGreg Kroah-Hartman u16 pack[] = { 1084866b8695SGreg Kroah-Hartman 0x200e, 0x0000, 1085866b8695SGreg Kroah-Hartman 0xc002, 0x14b4, 1086866b8695SGreg Kroah-Hartman 0xc003, 0x28b4, 1087866b8695SGreg Kroah-Hartman 0xc004, 0x3c5a, 1088866b8695SGreg Kroah-Hartman 0xdc05, 0x2a77, 108935d2d76dSHans Verkuil 0xc6c3, go->format == V4L2_PIX_FMT_MPEG4 ? 0 : 109035d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_H263 ? 0 : 1), 109135d2d76dSHans Verkuil 0xc680, go->format == V4L2_PIX_FMT_MPEG4 ? 0xf1 : 109235d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_H263 ? 0x61 : 1093866b8695SGreg Kroah-Hartman 0xd3), 1094866b8695SGreg Kroah-Hartman 0xc780, 0x0140, 1095866b8695SGreg Kroah-Hartman 0xe009, 0x0001, 1096866b8695SGreg Kroah-Hartman 0xc60f, 0x0008, 1097866b8695SGreg Kroah-Hartman 0xd4ff, 0x0002, 1098866b8695SGreg Kroah-Hartman 0xe403, 2340, 1099866b8695SGreg Kroah-Hartman 0xe406, 75, 1100866b8695SGreg Kroah-Hartman 0xd411, 0x0001, 1101866b8695SGreg Kroah-Hartman 0xd410, 0xa1d6, 1102866b8695SGreg Kroah-Hartman 0x0001, 0x2801, 1103866b8695SGreg Kroah-Hartman 1104866b8695SGreg Kroah-Hartman 0x200d, 0x0000, 1105866b8695SGreg Kroah-Hartman 0xe402, 0x018b, 1106866b8695SGreg Kroah-Hartman 0xe401, 0x8b01, 1107866b8695SGreg Kroah-Hartman 0xd472, (go->board_info->sensor_flags & 1108866b8695SGreg Kroah-Hartman GO7007_SENSOR_TV) && 1109866b8695SGreg Kroah-Hartman (!go->interlace_coding) ? 1110866b8695SGreg Kroah-Hartman 0x01b0 : 0x0170, 1111866b8695SGreg Kroah-Hartman 0xd475, (go->board_info->sensor_flags & 1112866b8695SGreg Kroah-Hartman GO7007_SENSOR_TV) && 1113866b8695SGreg Kroah-Hartman (!go->interlace_coding) ? 1114866b8695SGreg Kroah-Hartman 0x0008 : 0x0009, 1115866b8695SGreg Kroah-Hartman 0xc404, go->interlace_coding ? 0x44 : 111635d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG4 ? 0x11 : 111735d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG1 ? 0x02 : 111835d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG2 ? 0x04 : 111935d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_H263 ? 0x08 : 1120866b8695SGreg Kroah-Hartman 0x20)))), 112135d2d76dSHans Verkuil 0xbf0a, (go->format == V4L2_PIX_FMT_MPEG4 ? 8 : 112235d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG1 ? 1 : 112335d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG2 ? 2 : 112435d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_H263 ? 4 : 16)))) | 1125866b8695SGreg Kroah-Hartman ((go->repeat_seqhead ? 1 : 0) << 6) | 1126866b8695SGreg Kroah-Hartman ((go->dvd_mode ? 1 : 0) << 9) | 1127866b8695SGreg Kroah-Hartman ((go->gop_header_enable ? 1 : 0) << 10), 1128866b8695SGreg Kroah-Hartman 0xbf0b, 0, 1129866b8695SGreg Kroah-Hartman 0xdd5a, go->ipb ? 0x14 : 0x0a, 1130866b8695SGreg Kroah-Hartman 0xbf0c, 0, 1131866b8695SGreg Kroah-Hartman 0xbf0d, 0, 1132866b8695SGreg Kroah-Hartman 0xc683, THACCoeffSet0, 1133866b8695SGreg Kroah-Hartman 0xc40a, (go->width << 4) | rows, 1134866b8695SGreg Kroah-Hartman 0xe01a, go->board_info->hpi_buffer_cap, 1135866b8695SGreg Kroah-Hartman 0, 0, 1136866b8695SGreg Kroah-Hartman 0, 0, 1137866b8695SGreg Kroah-Hartman 1138866b8695SGreg Kroah-Hartman 0x2008, 0, 1139866b8695SGreg Kroah-Hartman 0xe402, 0x88, 1140866b8695SGreg Kroah-Hartman 0xe401, 0x8f01, 1141866b8695SGreg Kroah-Hartman 0xbf6a, 0, 1142866b8695SGreg Kroah-Hartman 0xbf6b, 0, 1143866b8695SGreg Kroah-Hartman 0xbf6c, 0, 1144866b8695SGreg Kroah-Hartman 0xbf6d, 0, 1145866b8695SGreg Kroah-Hartman 0xbf6e, 0, 1146866b8695SGreg Kroah-Hartman 0xbf6f, 0, 1147866b8695SGreg Kroah-Hartman 0, 0, 1148866b8695SGreg Kroah-Hartman 0, 0, 1149866b8695SGreg Kroah-Hartman 0, 0, 1150866b8695SGreg Kroah-Hartman 0, 0, 1151866b8695SGreg Kroah-Hartman 0, 0, 1152866b8695SGreg Kroah-Hartman 0, 0, 1153866b8695SGreg Kroah-Hartman 0, 0, 1154866b8695SGreg Kroah-Hartman 1155866b8695SGreg Kroah-Hartman 0x200e, 0, 1156866b8695SGreg Kroah-Hartman 0xbf66, brc_window_size, 1157866b8695SGreg Kroah-Hartman 0xbf67, 0, 1158866b8695SGreg Kroah-Hartman 0xbf68, q_min, 1159866b8695SGreg Kroah-Hartman 0xbf69, q_max, 1160866b8695SGreg Kroah-Hartman 0xbfe0, 0, 1161866b8695SGreg Kroah-Hartman 0xbfe1, 0, 1162866b8695SGreg Kroah-Hartman 0xbfe2, 0, 1163866b8695SGreg Kroah-Hartman 0xbfe3, go->ipb ? 3 : 1, 1164866b8695SGreg Kroah-Hartman 0xc031, go->board_info->sensor_flags & 1165866b8695SGreg Kroah-Hartman GO7007_SENSOR_VBI ? 1 : 0, 1166866b8695SGreg Kroah-Hartman 0xc01c, 0x1f, 1167866b8695SGreg Kroah-Hartman 0xdd8c, 0x15, 1168866b8695SGreg Kroah-Hartman 0xdd94, 0x15, 1169866b8695SGreg Kroah-Hartman 0xdd88, go->ipb ? 0x1401 : 0x0a01, 1170866b8695SGreg Kroah-Hartman 0xdd90, go->ipb ? 0x1401 : 0x0a01, 1171866b8695SGreg Kroah-Hartman 0, 0, 1172866b8695SGreg Kroah-Hartman 1173866b8695SGreg Kroah-Hartman 0x200e, 0, 1174866b8695SGreg Kroah-Hartman 0xbfe4, 0, 1175866b8695SGreg Kroah-Hartman 0xbfe5, 0, 1176866b8695SGreg Kroah-Hartman 0xbfe6, 0, 1177866b8695SGreg Kroah-Hartman 0xbfe7, fps << 8, 1178866b8695SGreg Kroah-Hartman 0xbfe8, 0x3a00, 1179866b8695SGreg Kroah-Hartman 0xbfe9, 0, 1180866b8695SGreg Kroah-Hartman 0xbfea, 0, 1181866b8695SGreg Kroah-Hartman 0xbfeb, 0, 1182866b8695SGreg Kroah-Hartman 0xbfec, (go->interlace_coding ? 1 << 15 : 0) | 1183866b8695SGreg Kroah-Hartman (go->modet_enable ? 0xa : 0) | 1184866b8695SGreg Kroah-Hartman (go->board_info->sensor_flags & 1185866b8695SGreg Kroah-Hartman GO7007_SENSOR_VBI ? 1 : 0), 1186866b8695SGreg Kroah-Hartman 0xbfed, 0, 1187866b8695SGreg Kroah-Hartman 0xbfee, 0, 1188866b8695SGreg Kroah-Hartman 0xbfef, 0, 1189866b8695SGreg Kroah-Hartman 0xbff0, go->board_info->sensor_flags & 1190866b8695SGreg Kroah-Hartman GO7007_SENSOR_TV ? 0xf060 : 0xb060, 1191866b8695SGreg Kroah-Hartman 0xbff1, 0, 1192866b8695SGreg Kroah-Hartman 0, 0, 1193866b8695SGreg Kroah-Hartman }; 1194866b8695SGreg Kroah-Hartman 1195866b8695SGreg Kroah-Hartman return copy_packages(code, pack, 5, space); 1196866b8695SGreg Kroah-Hartman } 1197866b8695SGreg Kroah-Hartman 11989febd042SHarvey Harrison static int seqhead_to_package(struct go7007 *go, __le16 *code, int space, 1199866b8695SGreg Kroah-Hartman int (*sequence_header_func)(struct go7007 *go, 1200866b8695SGreg Kroah-Hartman unsigned char *buf, int ext)) 1201866b8695SGreg Kroah-Hartman { 1202866b8695SGreg Kroah-Hartman int vop_time_increment_bitlength = vti_bitlen(go); 1203866b8695SGreg Kroah-Hartman int fps = go->sensor_framerate / go->fps_scale * 1204866b8695SGreg Kroah-Hartman (go->interlace_coding ? 2 : 1); 1205866b8695SGreg Kroah-Hartman unsigned char buf[40] = { }; 1206866b8695SGreg Kroah-Hartman int len = sequence_header_func(go, buf, 1); 1207866b8695SGreg Kroah-Hartman u16 pack[] = { 1208866b8695SGreg Kroah-Hartman 0x2006, 0, 1209866b8695SGreg Kroah-Hartman 0xbf08, fps, 1210866b8695SGreg Kroah-Hartman 0xbf09, 0, 1211866b8695SGreg Kroah-Hartman 0xbff2, vop_time_increment_bitlength, 1212866b8695SGreg Kroah-Hartman 0xbff3, (1 << vop_time_increment_bitlength) - 1, 1213866b8695SGreg Kroah-Hartman 0xbfe6, 0, 1214866b8695SGreg Kroah-Hartman 0xbfe7, (fps / 1000) << 8, 1215866b8695SGreg Kroah-Hartman 0, 0, 1216866b8695SGreg Kroah-Hartman 0, 0, 1217866b8695SGreg Kroah-Hartman 0, 0, 1218866b8695SGreg Kroah-Hartman 0, 0, 1219866b8695SGreg Kroah-Hartman 0, 0, 1220866b8695SGreg Kroah-Hartman 0, 0, 1221866b8695SGreg Kroah-Hartman 0, 0, 1222866b8695SGreg Kroah-Hartman 0, 0, 1223866b8695SGreg Kroah-Hartman 0, 0, 1224866b8695SGreg Kroah-Hartman 1225866b8695SGreg Kroah-Hartman 0x2007, 0, 1226866b8695SGreg Kroah-Hartman 0xc800, buf[2] << 8 | buf[3], 1227866b8695SGreg Kroah-Hartman 0xc801, buf[4] << 8 | buf[5], 1228866b8695SGreg Kroah-Hartman 0xc802, buf[6] << 8 | buf[7], 1229866b8695SGreg Kroah-Hartman 0xc803, buf[8] << 8 | buf[9], 1230866b8695SGreg Kroah-Hartman 0xc406, 64, 1231866b8695SGreg Kroah-Hartman 0xc407, len - 64, 1232866b8695SGreg Kroah-Hartman 0xc61b, 1, 1233866b8695SGreg Kroah-Hartman 0, 0, 1234866b8695SGreg Kroah-Hartman 0, 0, 1235866b8695SGreg Kroah-Hartman 0, 0, 1236866b8695SGreg Kroah-Hartman 0, 0, 1237866b8695SGreg Kroah-Hartman 0, 0, 1238866b8695SGreg Kroah-Hartman 0, 0, 1239866b8695SGreg Kroah-Hartman 0, 0, 1240866b8695SGreg Kroah-Hartman 0, 0, 1241866b8695SGreg Kroah-Hartman 1242866b8695SGreg Kroah-Hartman 0x200e, 0, 1243866b8695SGreg Kroah-Hartman 0xc808, buf[10] << 8 | buf[11], 1244866b8695SGreg Kroah-Hartman 0xc809, buf[12] << 8 | buf[13], 1245866b8695SGreg Kroah-Hartman 0xc80a, buf[14] << 8 | buf[15], 1246866b8695SGreg Kroah-Hartman 0xc80b, buf[16] << 8 | buf[17], 1247866b8695SGreg Kroah-Hartman 0xc80c, buf[18] << 8 | buf[19], 1248866b8695SGreg Kroah-Hartman 0xc80d, buf[20] << 8 | buf[21], 1249866b8695SGreg Kroah-Hartman 0xc80e, buf[22] << 8 | buf[23], 1250866b8695SGreg Kroah-Hartman 0xc80f, buf[24] << 8 | buf[25], 1251866b8695SGreg Kroah-Hartman 0xc810, buf[26] << 8 | buf[27], 1252866b8695SGreg Kroah-Hartman 0xc811, buf[28] << 8 | buf[29], 1253866b8695SGreg Kroah-Hartman 0xc812, buf[30] << 8 | buf[31], 1254866b8695SGreg Kroah-Hartman 0xc813, buf[32] << 8 | buf[33], 1255866b8695SGreg Kroah-Hartman 0xc814, buf[34] << 8 | buf[35], 1256866b8695SGreg Kroah-Hartman 0xc815, buf[36] << 8 | buf[37], 1257866b8695SGreg Kroah-Hartman 0, 0, 1258866b8695SGreg Kroah-Hartman 0, 0, 1259866b8695SGreg Kroah-Hartman 0, 0, 1260866b8695SGreg Kroah-Hartman }; 1261866b8695SGreg Kroah-Hartman 1262866b8695SGreg Kroah-Hartman return copy_packages(code, pack, 3, space); 1263866b8695SGreg Kroah-Hartman } 1264866b8695SGreg Kroah-Hartman 1265866b8695SGreg Kroah-Hartman static int relative_prime(int big, int little) 1266866b8695SGreg Kroah-Hartman { 1267866b8695SGreg Kroah-Hartman int remainder; 1268866b8695SGreg Kroah-Hartman 1269866b8695SGreg Kroah-Hartman while (little != 0) { 1270866b8695SGreg Kroah-Hartman remainder = big % little; 1271866b8695SGreg Kroah-Hartman big = little; 1272866b8695SGreg Kroah-Hartman little = remainder; 1273866b8695SGreg Kroah-Hartman } 1274866b8695SGreg Kroah-Hartman return big; 1275866b8695SGreg Kroah-Hartman } 1276866b8695SGreg Kroah-Hartman 12779febd042SHarvey Harrison static int avsync_to_package(struct go7007 *go, __le16 *code, int space) 1278866b8695SGreg Kroah-Hartman { 1279866b8695SGreg Kroah-Hartman int arate = go->board_info->audio_rate * 1001 * go->fps_scale; 1280866b8695SGreg Kroah-Hartman int ratio = arate / go->sensor_framerate; 1281866b8695SGreg Kroah-Hartman int adjratio = ratio * 215 / 100; 1282866b8695SGreg Kroah-Hartman int rprime = relative_prime(go->sensor_framerate, 1283866b8695SGreg Kroah-Hartman arate % go->sensor_framerate); 1284866b8695SGreg Kroah-Hartman int f1 = (arate % go->sensor_framerate) / rprime; 1285866b8695SGreg Kroah-Hartman int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime; 1286866b8695SGreg Kroah-Hartman u16 pack[] = { 1287866b8695SGreg Kroah-Hartman 0x200e, 0, 1288866b8695SGreg Kroah-Hartman 0xbf98, (u16)((-adjratio) & 0xffff), 1289866b8695SGreg Kroah-Hartman 0xbf99, (u16)((-adjratio) >> 16), 1290866b8695SGreg Kroah-Hartman 0xbf92, 0, 1291866b8695SGreg Kroah-Hartman 0xbf93, 0, 1292866b8695SGreg Kroah-Hartman 0xbff4, f1 > f2 ? f1 : f2, 1293866b8695SGreg Kroah-Hartman 0xbff5, f1 < f2 ? f1 : f2, 1294866b8695SGreg Kroah-Hartman 0xbff6, f1 < f2 ? ratio : ratio + 1, 1295866b8695SGreg Kroah-Hartman 0xbff7, f1 > f2 ? ratio : ratio + 1, 1296866b8695SGreg Kroah-Hartman 0xbff8, 0, 1297866b8695SGreg Kroah-Hartman 0xbff9, 0, 1298866b8695SGreg Kroah-Hartman 0xbffa, adjratio & 0xffff, 1299866b8695SGreg Kroah-Hartman 0xbffb, adjratio >> 16, 1300866b8695SGreg Kroah-Hartman 0xbf94, 0, 1301866b8695SGreg Kroah-Hartman 0xbf95, 0, 1302866b8695SGreg Kroah-Hartman 0, 0, 1303866b8695SGreg Kroah-Hartman }; 1304866b8695SGreg Kroah-Hartman 1305866b8695SGreg Kroah-Hartman return copy_packages(code, pack, 1, space); 1306866b8695SGreg Kroah-Hartman } 1307866b8695SGreg Kroah-Hartman 13089febd042SHarvey Harrison static int final_package(struct go7007 *go, __le16 *code, int space) 1309866b8695SGreg Kroah-Hartman { 1310866b8695SGreg Kroah-Hartman int rows = go->interlace_coding ? go->height / 32 : go->height / 16; 1311866b8695SGreg Kroah-Hartman u16 pack[] = { 1312866b8695SGreg Kroah-Hartman 0x8000, 1313866b8695SGreg Kroah-Hartman 0, 1314866b8695SGreg Kroah-Hartman 0, 1315866b8695SGreg Kroah-Hartman 0, 1316866b8695SGreg Kroah-Hartman 0, 1317866b8695SGreg Kroah-Hartman 0, 1318866b8695SGreg Kroah-Hartman 0, 1319866b8695SGreg Kroah-Hartman 2, 1320866b8695SGreg Kroah-Hartman ((go->board_info->sensor_flags & GO7007_SENSOR_TV) && 1321866b8695SGreg Kroah-Hartman (!go->interlace_coding) ? 1322866b8695SGreg Kroah-Hartman (1 << 14) | (1 << 9) : 0) | 1323866b8695SGreg Kroah-Hartman ((go->encoder_subsample ? 1 : 0) << 8) | 1324866b8695SGreg Kroah-Hartman (go->board_info->sensor_flags & 1325866b8695SGreg Kroah-Hartman GO7007_SENSOR_CONFIG_MASK), 1326866b8695SGreg Kroah-Hartman ((go->encoder_v_halve ? 1 : 0) << 14) | 1327866b8695SGreg Kroah-Hartman (go->encoder_v_halve ? rows << 9 : rows << 8) | 1328866b8695SGreg Kroah-Hartman (go->encoder_h_halve ? 1 << 6 : 0) | 1329866b8695SGreg Kroah-Hartman (go->encoder_h_halve ? go->width >> 3 : go->width >> 4), 1330866b8695SGreg Kroah-Hartman (1 << 15) | (go->encoder_v_offset << 6) | 1331866b8695SGreg Kroah-Hartman (1 << 7) | (go->encoder_h_offset >> 2), 1332866b8695SGreg Kroah-Hartman (1 << 6), 1333866b8695SGreg Kroah-Hartman 0, 1334866b8695SGreg Kroah-Hartman 0, 1335866b8695SGreg Kroah-Hartman ((go->fps_scale - 1) << 8) | 1336866b8695SGreg Kroah-Hartman (go->board_info->sensor_flags & GO7007_SENSOR_TV ? 1337866b8695SGreg Kroah-Hartman (1 << 7) : 0) | 1338866b8695SGreg Kroah-Hartman 0x41, 1339866b8695SGreg Kroah-Hartman go->ipb ? 0xd4c : 0x36b, 1340866b8695SGreg Kroah-Hartman (rows << 8) | (go->width >> 4), 134135d2d76dSHans Verkuil go->format == V4L2_PIX_FMT_MPEG4 ? 0x0404 : 0, 1342866b8695SGreg Kroah-Hartman (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) | 1343866b8695SGreg Kroah-Hartman ((go->closed_gop ? 1 : 0) << 12) | 134435d2d76dSHans Verkuil ((go->format == V4L2_PIX_FMT_MPEG4 ? 1 : 0) << 11) | 1345866b8695SGreg Kroah-Hartman /* (1 << 9) | */ 1346866b8695SGreg Kroah-Hartman ((go->ipb ? 3 : 0) << 7) | 1347866b8695SGreg Kroah-Hartman ((go->modet_enable ? 1 : 0) << 2) | 1348866b8695SGreg Kroah-Hartman ((go->dvd_mode ? 1 : 0) << 1) | 1, 134935d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG1 ? 0x89a0 : 135035d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG2 ? 0x89a0 : 135135d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MJPEG ? 0x89a0 : 135235d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_MPEG4 ? 0x8920 : 135335d2d76dSHans Verkuil (go->format == V4L2_PIX_FMT_H263 ? 0x8920 : 0))))), 1354866b8695SGreg Kroah-Hartman go->ipb ? 0x1f15 : 0x1f0b, 1355866b8695SGreg Kroah-Hartman go->ipb ? 0x0015 : 0x000b, 1356866b8695SGreg Kroah-Hartman go->ipb ? 0xa800 : 0x5800, 1357866b8695SGreg Kroah-Hartman 0xffff, 1358866b8695SGreg Kroah-Hartman 0x0020 + 0x034b * 0, 1359866b8695SGreg Kroah-Hartman 0x0020 + 0x034b * 1, 1360866b8695SGreg Kroah-Hartman 0x0020 + 0x034b * 2, 1361866b8695SGreg Kroah-Hartman 0x0020 + 0x034b * 3, 1362866b8695SGreg Kroah-Hartman 0x0020 + 0x034b * 4, 1363866b8695SGreg Kroah-Hartman 0x0020 + 0x034b * 5, 1364866b8695SGreg Kroah-Hartman go->ipb ? (go->gop_size / 3) : go->gop_size, 1365866b8695SGreg Kroah-Hartman (go->height >> 4) * (go->width >> 4) * 110 / 100, 1366866b8695SGreg Kroah-Hartman }; 1367866b8695SGreg Kroah-Hartman 1368866b8695SGreg Kroah-Hartman return copy_packages(code, pack, 1, space); 1369866b8695SGreg Kroah-Hartman } 1370866b8695SGreg Kroah-Hartman 13719febd042SHarvey Harrison static int audio_to_package(struct go7007 *go, __le16 *code, int space) 1372866b8695SGreg Kroah-Hartman { 1373866b8695SGreg Kroah-Hartman int clock_config = ((go->board_info->audio_flags & 1374866b8695SGreg Kroah-Hartman GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) | 1375866b8695SGreg Kroah-Hartman ((go->board_info->audio_flags & 1376866b8695SGreg Kroah-Hartman GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) | 1377866b8695SGreg Kroah-Hartman (((go->board_info->audio_bclk_div / 4) - 1) << 4) | 1378866b8695SGreg Kroah-Hartman (go->board_info->audio_main_div - 1); 1379866b8695SGreg Kroah-Hartman u16 pack[] = { 1380866b8695SGreg Kroah-Hartman 0x200d, 0, 1381866b8695SGreg Kroah-Hartman 0x9002, 0, 1382866b8695SGreg Kroah-Hartman 0x9002, 0, 1383866b8695SGreg Kroah-Hartman 0x9031, 0, 1384866b8695SGreg Kroah-Hartman 0x9032, 0, 1385866b8695SGreg Kroah-Hartman 0x9033, 0, 1386866b8695SGreg Kroah-Hartman 0x9034, 0, 1387866b8695SGreg Kroah-Hartman 0x9035, 0, 1388866b8695SGreg Kroah-Hartman 0x9036, 0, 1389866b8695SGreg Kroah-Hartman 0x9037, 0, 1390866b8695SGreg Kroah-Hartman 0x9040, 0, 1391866b8695SGreg Kroah-Hartman 0x9000, clock_config, 1392866b8695SGreg Kroah-Hartman 0x9001, (go->board_info->audio_flags & 0xffff) | 1393866b8695SGreg Kroah-Hartman (1 << 9), 1394866b8695SGreg Kroah-Hartman 0x9000, ((go->board_info->audio_flags & 1395866b8695SGreg Kroah-Hartman GO7007_AUDIO_I2S_MASTER ? 1396866b8695SGreg Kroah-Hartman 1 : 0) << 10) | 1397866b8695SGreg Kroah-Hartman clock_config, 1398866b8695SGreg Kroah-Hartman 0, 0, 1399866b8695SGreg Kroah-Hartman 0, 0, 1400866b8695SGreg Kroah-Hartman 0x2005, 0, 1401866b8695SGreg Kroah-Hartman 0x9041, 0, 1402866b8695SGreg Kroah-Hartman 0x9042, 256, 1403866b8695SGreg Kroah-Hartman 0x9043, 0, 1404866b8695SGreg Kroah-Hartman 0x9044, 16, 1405866b8695SGreg Kroah-Hartman 0x9045, 16, 1406866b8695SGreg Kroah-Hartman 0, 0, 1407866b8695SGreg Kroah-Hartman 0, 0, 1408866b8695SGreg Kroah-Hartman 0, 0, 1409866b8695SGreg Kroah-Hartman 0, 0, 1410866b8695SGreg Kroah-Hartman 0, 0, 1411866b8695SGreg Kroah-Hartman 0, 0, 1412866b8695SGreg Kroah-Hartman 0, 0, 1413866b8695SGreg Kroah-Hartman 0, 0, 1414866b8695SGreg Kroah-Hartman 0, 0, 1415866b8695SGreg Kroah-Hartman 0, 0, 1416866b8695SGreg Kroah-Hartman }; 1417866b8695SGreg Kroah-Hartman 1418866b8695SGreg Kroah-Hartman return copy_packages(code, pack, 2, space); 1419866b8695SGreg Kroah-Hartman } 1420866b8695SGreg Kroah-Hartman 14219febd042SHarvey Harrison static int modet_to_package(struct go7007 *go, __le16 *code, int space) 1422866b8695SGreg Kroah-Hartman { 14230ee58f84SHans Verkuil bool has_modet0 = go->modet[0].enable; 14240ee58f84SHans Verkuil bool has_modet1 = go->modet[1].enable; 14250ee58f84SHans Verkuil bool has_modet2 = go->modet[2].enable; 14260ee58f84SHans Verkuil bool has_modet3 = go->modet[3].enable; 1427866b8695SGreg Kroah-Hartman int ret, mb, i, addr, cnt = 0; 1428866b8695SGreg Kroah-Hartman u16 pack[32]; 1429866b8695SGreg Kroah-Hartman u16 thresholds[] = { 1430866b8695SGreg Kroah-Hartman 0x200e, 0, 14310ee58f84SHans Verkuil 0xbf82, has_modet0 ? go->modet[0].pixel_threshold : 32767, 14320ee58f84SHans Verkuil 0xbf83, has_modet1 ? go->modet[1].pixel_threshold : 32767, 14330ee58f84SHans Verkuil 0xbf84, has_modet2 ? go->modet[2].pixel_threshold : 32767, 14340ee58f84SHans Verkuil 0xbf85, has_modet3 ? go->modet[3].pixel_threshold : 32767, 14350ee58f84SHans Verkuil 0xbf86, has_modet0 ? go->modet[0].motion_threshold : 32767, 14360ee58f84SHans Verkuil 0xbf87, has_modet1 ? go->modet[1].motion_threshold : 32767, 14370ee58f84SHans Verkuil 0xbf88, has_modet2 ? go->modet[2].motion_threshold : 32767, 14380ee58f84SHans Verkuil 0xbf89, has_modet3 ? go->modet[3].motion_threshold : 32767, 14390ee58f84SHans Verkuil 0xbf8a, has_modet0 ? go->modet[0].mb_threshold : 32767, 14400ee58f84SHans Verkuil 0xbf8b, has_modet1 ? go->modet[1].mb_threshold : 32767, 14410ee58f84SHans Verkuil 0xbf8c, has_modet2 ? go->modet[2].mb_threshold : 32767, 14420ee58f84SHans Verkuil 0xbf8d, has_modet3 ? go->modet[3].mb_threshold : 32767, 1443866b8695SGreg Kroah-Hartman 0xbf8e, 0, 1444866b8695SGreg Kroah-Hartman 0xbf8f, 0, 1445866b8695SGreg Kroah-Hartman 0, 0, 1446866b8695SGreg Kroah-Hartman }; 1447866b8695SGreg Kroah-Hartman 1448866b8695SGreg Kroah-Hartman ret = copy_packages(code, thresholds, 1, space); 1449866b8695SGreg Kroah-Hartman if (ret < 0) 1450866b8695SGreg Kroah-Hartman return -1; 1451866b8695SGreg Kroah-Hartman cnt += ret; 1452866b8695SGreg Kroah-Hartman 1453866b8695SGreg Kroah-Hartman addr = 0xbac0; 1454866b8695SGreg Kroah-Hartman memset(pack, 0, 64); 1455866b8695SGreg Kroah-Hartman i = 0; 1456866b8695SGreg Kroah-Hartman for (mb = 0; mb < 1624; ++mb) { 1457866b8695SGreg Kroah-Hartman pack[i * 2 + 3] <<= 2; 1458866b8695SGreg Kroah-Hartman pack[i * 2 + 3] |= go->modet_map[mb]; 1459866b8695SGreg Kroah-Hartman if (mb % 8 != 7) 1460866b8695SGreg Kroah-Hartman continue; 1461866b8695SGreg Kroah-Hartman pack[i * 2 + 2] = addr++; 1462866b8695SGreg Kroah-Hartman ++i; 1463866b8695SGreg Kroah-Hartman if (i == 10 || mb == 1623) { 1464866b8695SGreg Kroah-Hartman pack[0] = 0x2000 | i; 1465866b8695SGreg Kroah-Hartman ret = copy_packages(code + cnt, pack, 1, space - cnt); 1466866b8695SGreg Kroah-Hartman if (ret < 0) 1467866b8695SGreg Kroah-Hartman return -1; 1468866b8695SGreg Kroah-Hartman cnt += ret; 1469866b8695SGreg Kroah-Hartman i = 0; 1470866b8695SGreg Kroah-Hartman memset(pack, 0, 64); 1471866b8695SGreg Kroah-Hartman } 1472866b8695SGreg Kroah-Hartman pack[i * 2 + 3] = 0; 1473866b8695SGreg Kroah-Hartman } 1474866b8695SGreg Kroah-Hartman 1475866b8695SGreg Kroah-Hartman memset(pack, 0, 64); 1476866b8695SGreg Kroah-Hartman i = 0; 1477866b8695SGreg Kroah-Hartman for (addr = 0xbb90; addr < 0xbbfa; ++addr) { 1478866b8695SGreg Kroah-Hartman pack[i * 2 + 2] = addr; 1479866b8695SGreg Kroah-Hartman pack[i * 2 + 3] = 0; 1480866b8695SGreg Kroah-Hartman ++i; 1481866b8695SGreg Kroah-Hartman if (i == 10 || addr == 0xbbf9) { 1482866b8695SGreg Kroah-Hartman pack[0] = 0x2000 | i; 1483866b8695SGreg Kroah-Hartman ret = copy_packages(code + cnt, pack, 1, space - cnt); 1484866b8695SGreg Kroah-Hartman if (ret < 0) 1485866b8695SGreg Kroah-Hartman return -1; 1486866b8695SGreg Kroah-Hartman cnt += ret; 1487866b8695SGreg Kroah-Hartman i = 0; 1488866b8695SGreg Kroah-Hartman memset(pack, 0, 64); 1489866b8695SGreg Kroah-Hartman } 1490866b8695SGreg Kroah-Hartman } 1491866b8695SGreg Kroah-Hartman return cnt; 1492866b8695SGreg Kroah-Hartman } 1493866b8695SGreg Kroah-Hartman 1494ed713a4aSArnd Bergmann static noinline_for_stack int do_special(struct go7007 *go, u16 type, 1495ed713a4aSArnd Bergmann __le16 *code, int space, int *framelen) 1496866b8695SGreg Kroah-Hartman { 1497866b8695SGreg Kroah-Hartman switch (type) { 1498866b8695SGreg Kroah-Hartman case SPECIAL_FRM_HEAD: 1499866b8695SGreg Kroah-Hartman switch (go->format) { 150035d2d76dSHans Verkuil case V4L2_PIX_FMT_MJPEG: 1501866b8695SGreg Kroah-Hartman return gen_mjpeghdr_to_package(go, code, space); 150235d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG1: 150335d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG2: 1504866b8695SGreg Kroah-Hartman return gen_mpeg1hdr_to_package(go, code, space, 1505866b8695SGreg Kroah-Hartman framelen); 150635d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG4: 1507866b8695SGreg Kroah-Hartman return gen_mpeg4hdr_to_package(go, code, space, 1508866b8695SGreg Kroah-Hartman framelen); 1509a7f3482dSHans Verkuil default: 1510a7f3482dSHans Verkuil break; 1511866b8695SGreg Kroah-Hartman } 1512a7f3482dSHans Verkuil break; 1513866b8695SGreg Kroah-Hartman case SPECIAL_BRC_CTRL: 1514866b8695SGreg Kroah-Hartman return brctrl_to_package(go, code, space, framelen); 1515866b8695SGreg Kroah-Hartman case SPECIAL_CONFIG: 1516866b8695SGreg Kroah-Hartman return config_package(go, code, space); 1517866b8695SGreg Kroah-Hartman case SPECIAL_SEQHEAD: 1518866b8695SGreg Kroah-Hartman switch (go->format) { 151935d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG1: 152035d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG2: 1521866b8695SGreg Kroah-Hartman return seqhead_to_package(go, code, space, 1522866b8695SGreg Kroah-Hartman mpeg1_sequence_header); 152335d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG4: 1524866b8695SGreg Kroah-Hartman return seqhead_to_package(go, code, space, 1525866b8695SGreg Kroah-Hartman mpeg4_sequence_header); 1526866b8695SGreg Kroah-Hartman default: 1527866b8695SGreg Kroah-Hartman return 0; 1528866b8695SGreg Kroah-Hartman } 1529866b8695SGreg Kroah-Hartman case SPECIAL_AV_SYNC: 1530866b8695SGreg Kroah-Hartman return avsync_to_package(go, code, space); 1531866b8695SGreg Kroah-Hartman case SPECIAL_FINAL: 1532866b8695SGreg Kroah-Hartman return final_package(go, code, space); 1533866b8695SGreg Kroah-Hartman case SPECIAL_AUDIO: 1534866b8695SGreg Kroah-Hartman return audio_to_package(go, code, space); 1535866b8695SGreg Kroah-Hartman case SPECIAL_MODET: 1536866b8695SGreg Kroah-Hartman return modet_to_package(go, code, space); 1537866b8695SGreg Kroah-Hartman } 153879280714SYAMANE Toshiaki dev_err(go->dev, 153979280714SYAMANE Toshiaki "firmware file contains unsupported feature %04x\n", type); 1540866b8695SGreg Kroah-Hartman return -1; 1541866b8695SGreg Kroah-Hartman } 1542866b8695SGreg Kroah-Hartman 1543866b8695SGreg Kroah-Hartman int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen) 1544866b8695SGreg Kroah-Hartman { 1545866b8695SGreg Kroah-Hartman const struct firmware *fw_entry; 15469febd042SHarvey Harrison __le16 *code, *src; 1547866b8695SGreg Kroah-Hartman int framelen[8] = { }; /* holds the lengths of empty frame templates */ 1548866b8695SGreg Kroah-Hartman int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags; 1549866b8695SGreg Kroah-Hartman int mode_flag; 1550866b8695SGreg Kroah-Hartman int ret; 1551866b8695SGreg Kroah-Hartman 1552866b8695SGreg Kroah-Hartman switch (go->format) { 155335d2d76dSHans Verkuil case V4L2_PIX_FMT_MJPEG: 1554866b8695SGreg Kroah-Hartman mode_flag = FLAG_MODE_MJPEG; 1555866b8695SGreg Kroah-Hartman break; 155635d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG1: 1557866b8695SGreg Kroah-Hartman mode_flag = FLAG_MODE_MPEG1; 1558866b8695SGreg Kroah-Hartman break; 155935d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG2: 1560866b8695SGreg Kroah-Hartman mode_flag = FLAG_MODE_MPEG2; 1561866b8695SGreg Kroah-Hartman break; 156235d2d76dSHans Verkuil case V4L2_PIX_FMT_MPEG4: 1563866b8695SGreg Kroah-Hartman mode_flag = FLAG_MODE_MPEG4; 1564866b8695SGreg Kroah-Hartman break; 1565866b8695SGreg Kroah-Hartman default: 1566866b8695SGreg Kroah-Hartman return -1; 1567866b8695SGreg Kroah-Hartman } 15680a6ecbb4SHans Verkuil if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) { 156979280714SYAMANE Toshiaki dev_err(go->dev, 157079280714SYAMANE Toshiaki "unable to load firmware from file \"%s\"\n", 15710a6ecbb4SHans Verkuil GO7007_FW_NAME); 1572866b8695SGreg Kroah-Hartman return -1; 1573866b8695SGreg Kroah-Hartman } 15746396bb22SKees Cook code = kcalloc(codespace, 2, GFP_KERNEL); 1575535ec049SJoe Perches if (code == NULL) 1576866b8695SGreg Kroah-Hartman goto fw_failed; 1577535ec049SJoe Perches 15789febd042SHarvey Harrison src = (__le16 *)fw_entry->data; 1579866b8695SGreg Kroah-Hartman srclen = fw_entry->size / 2; 1580866b8695SGreg Kroah-Hartman while (srclen >= 2) { 1581866b8695SGreg Kroah-Hartman chunk_flags = __le16_to_cpu(src[0]); 1582866b8695SGreg Kroah-Hartman chunk_len = __le16_to_cpu(src[1]); 1583866b8695SGreg Kroah-Hartman if (chunk_len + 2 > srclen) { 158479280714SYAMANE Toshiaki dev_err(go->dev, 158579280714SYAMANE Toshiaki "firmware file \"%s\" appears to be corrupted\n", 15860a6ecbb4SHans Verkuil GO7007_FW_NAME); 1587866b8695SGreg Kroah-Hartman goto fw_failed; 1588866b8695SGreg Kroah-Hartman } 1589866b8695SGreg Kroah-Hartman if (chunk_flags & mode_flag) { 1590866b8695SGreg Kroah-Hartman if (chunk_flags & FLAG_SPECIAL) { 1591866b8695SGreg Kroah-Hartman ret = do_special(go, __le16_to_cpu(src[2]), 1592866b8695SGreg Kroah-Hartman &code[i], codespace - i, framelen); 1593866b8695SGreg Kroah-Hartman if (ret < 0) { 159479280714SYAMANE Toshiaki dev_err(go->dev, 159579280714SYAMANE Toshiaki "insufficient memory for firmware construction\n"); 1596866b8695SGreg Kroah-Hartman goto fw_failed; 1597866b8695SGreg Kroah-Hartman } 1598866b8695SGreg Kroah-Hartman i += ret; 1599866b8695SGreg Kroah-Hartman } else { 1600866b8695SGreg Kroah-Hartman if (codespace - i < chunk_len) { 160179280714SYAMANE Toshiaki dev_err(go->dev, 160279280714SYAMANE Toshiaki "insufficient memory for firmware construction\n"); 1603866b8695SGreg Kroah-Hartman goto fw_failed; 1604866b8695SGreg Kroah-Hartman } 1605866b8695SGreg Kroah-Hartman memcpy(&code[i], &src[2], chunk_len * 2); 1606866b8695SGreg Kroah-Hartman i += chunk_len; 1607866b8695SGreg Kroah-Hartman } 1608866b8695SGreg Kroah-Hartman } 1609866b8695SGreg Kroah-Hartman srclen -= chunk_len + 2; 1610866b8695SGreg Kroah-Hartman src += chunk_len + 2; 1611866b8695SGreg Kroah-Hartman } 1612866b8695SGreg Kroah-Hartman release_firmware(fw_entry); 1613866b8695SGreg Kroah-Hartman *fw = (u8 *)code; 1614866b8695SGreg Kroah-Hartman *fwlen = i * 2; 1615866b8695SGreg Kroah-Hartman return 0; 1616866b8695SGreg Kroah-Hartman 1617866b8695SGreg Kroah-Hartman fw_failed: 1618866b8695SGreg Kroah-Hartman kfree(code); 1619866b8695SGreg Kroah-Hartman release_firmware(fw_entry); 1620866b8695SGreg Kroah-Hartman return -1; 1621866b8695SGreg Kroah-Hartman } 16220a6ecbb4SHans Verkuil 16230a6ecbb4SHans Verkuil MODULE_FIRMWARE(GO7007_FW_NAME); 1624