1 /* 2 * TW5864 driver - video encoding functions 3 * 4 * Copyright (C) 2016 Bluecherry, LLC <maintainers@bluecherrydvr.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/module.h> 18 #include <media/v4l2-common.h> 19 #include <media/v4l2-event.h> 20 #include <media/videobuf2-dma-contig.h> 21 22 #include "tw5864.h" 23 #include "tw5864-reg.h" 24 25 #define QUANTIZATION_TABLE_LEN 96 26 #define VLC_LOOKUP_TABLE_LEN 1024 27 28 static const u16 forward_quantization_table[QUANTIZATION_TABLE_LEN] = { 29 0x3333, 0x1f82, 0x3333, 0x1f82, 0x1f82, 0x147b, 0x1f82, 0x147b, 30 0x3333, 0x1f82, 0x3333, 0x1f82, 0x1f82, 0x147b, 0x1f82, 0x147b, 31 0x2e8c, 0x1d42, 0x2e8c, 0x1d42, 0x1d42, 0x1234, 0x1d42, 0x1234, 32 0x2e8c, 0x1d42, 0x2e8c, 0x1d42, 0x1d42, 0x1234, 0x1d42, 0x1234, 33 0x2762, 0x199a, 0x2762, 0x199a, 0x199a, 0x1062, 0x199a, 0x1062, 34 0x2762, 0x199a, 0x2762, 0x199a, 0x199a, 0x1062, 0x199a, 0x1062, 35 0x2492, 0x16c1, 0x2492, 0x16c1, 0x16c1, 0x0e3f, 0x16c1, 0x0e3f, 36 0x2492, 0x16c1, 0x2492, 0x16c1, 0x16c1, 0x0e3f, 0x16c1, 0x0e3f, 37 0x2000, 0x147b, 0x2000, 0x147b, 0x147b, 0x0d1b, 0x147b, 0x0d1b, 38 0x2000, 0x147b, 0x2000, 0x147b, 0x147b, 0x0d1b, 0x147b, 0x0d1b, 39 0x1c72, 0x11cf, 0x1c72, 0x11cf, 0x11cf, 0x0b4d, 0x11cf, 0x0b4d, 40 0x1c72, 0x11cf, 0x1c72, 0x11cf, 0x11cf, 0x0b4d, 0x11cf, 0x0b4d 41 }; 42 43 static const u16 inverse_quantization_table[QUANTIZATION_TABLE_LEN] = { 44 0x800a, 0x800d, 0x800a, 0x800d, 0x800d, 0x8010, 0x800d, 0x8010, 45 0x800a, 0x800d, 0x800a, 0x800d, 0x800d, 0x8010, 0x800d, 0x8010, 46 0x800b, 0x800e, 0x800b, 0x800e, 0x800e, 0x8012, 0x800e, 0x8012, 47 0x800b, 0x800e, 0x800b, 0x800e, 0x800e, 0x8012, 0x800e, 0x8012, 48 0x800d, 0x8010, 0x800d, 0x8010, 0x8010, 0x8014, 0x8010, 0x8014, 49 0x800d, 0x8010, 0x800d, 0x8010, 0x8010, 0x8014, 0x8010, 0x8014, 50 0x800e, 0x8012, 0x800e, 0x8012, 0x8012, 0x8017, 0x8012, 0x8017, 51 0x800e, 0x8012, 0x800e, 0x8012, 0x8012, 0x8017, 0x8012, 0x8017, 52 0x8010, 0x8014, 0x8010, 0x8014, 0x8014, 0x8019, 0x8014, 0x8019, 53 0x8010, 0x8014, 0x8010, 0x8014, 0x8014, 0x8019, 0x8014, 0x8019, 54 0x8012, 0x8017, 0x8012, 0x8017, 0x8017, 0x801d, 0x8017, 0x801d, 55 0x8012, 0x8017, 0x8012, 0x8017, 0x8017, 0x801d, 0x8017, 0x801d 56 }; 57 58 static const u16 encoder_vlc_lookup_table[VLC_LOOKUP_TABLE_LEN] = { 59 0x011, 0x000, 0x000, 0x000, 0x065, 0x021, 0x000, 0x000, 0x087, 0x064, 60 0x031, 0x000, 0x097, 0x086, 0x075, 0x053, 0x0a7, 0x096, 0x085, 0x063, 61 0x0b7, 0x0a6, 0x095, 0x074, 0x0df, 0x0b6, 0x0a5, 0x084, 0x0db, 0x0de, 62 0x0b5, 0x094, 0x0d8, 0x0da, 0x0dd, 0x0a4, 0x0ef, 0x0ee, 0x0d9, 0x0b4, 63 0x0eb, 0x0ea, 0x0ed, 0x0dc, 0x0ff, 0x0fe, 0x0e9, 0x0ec, 0x0fb, 0x0fa, 64 0x0fd, 0x0e8, 0x10f, 0x0f1, 0x0f9, 0x0fc, 0x10b, 0x10e, 0x10d, 0x0f8, 65 0x107, 0x10a, 0x109, 0x10c, 0x104, 0x106, 0x105, 0x108, 0x023, 0x000, 66 0x000, 0x000, 0x06b, 0x022, 0x000, 0x000, 0x067, 0x057, 0x033, 0x000, 67 0x077, 0x06a, 0x069, 0x045, 0x087, 0x066, 0x065, 0x044, 0x084, 0x076, 68 0x075, 0x056, 0x097, 0x086, 0x085, 0x068, 0x0bf, 0x096, 0x095, 0x064, 69 0x0bb, 0x0be, 0x0bd, 0x074, 0x0cf, 0x0ba, 0x0b9, 0x094, 0x0cb, 0x0ce, 70 0x0cd, 0x0bc, 0x0c8, 0x0ca, 0x0c9, 0x0b8, 0x0df, 0x0de, 0x0dd, 0x0cc, 71 0x0db, 0x0da, 0x0d9, 0x0dc, 0x0d7, 0x0eb, 0x0d6, 0x0d8, 0x0e9, 0x0e8, 72 0x0ea, 0x0d1, 0x0e7, 0x0e6, 0x0e5, 0x0e4, 0x04f, 0x000, 0x000, 0x000, 73 0x06f, 0x04e, 0x000, 0x000, 0x06b, 0x05f, 0x04d, 0x000, 0x068, 0x05c, 74 0x05e, 0x04c, 0x07f, 0x05a, 0x05b, 0x04b, 0x07b, 0x058, 0x059, 0x04a, 75 0x079, 0x06e, 0x06d, 0x049, 0x078, 0x06a, 0x069, 0x048, 0x08f, 0x07e, 76 0x07d, 0x05d, 0x08b, 0x08e, 0x07a, 0x06c, 0x09f, 0x08a, 0x08d, 0x07c, 77 0x09b, 0x09e, 0x089, 0x08c, 0x098, 0x09a, 0x09d, 0x088, 0x0ad, 0x097, 78 0x099, 0x09c, 0x0a9, 0x0ac, 0x0ab, 0x0aa, 0x0a5, 0x0a8, 0x0a7, 0x0a6, 79 0x0a1, 0x0a4, 0x0a3, 0x0a2, 0x021, 0x000, 0x000, 0x000, 0x067, 0x011, 80 0x000, 0x000, 0x064, 0x066, 0x031, 0x000, 0x063, 0x073, 0x072, 0x065, 81 0x062, 0x083, 0x082, 0x070, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 82 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 83 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 84 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 85 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 86 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 87 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 88 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 89 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 90 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 91 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 92 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 93 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 94 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 95 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 96 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 97 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 98 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 99 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 100 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 101 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 102 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 103 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 104 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 105 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 106 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 107 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 108 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 109 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 110 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 111 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x011, 0x010, 112 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 113 0x000, 0x000, 0x000, 0x000, 0x011, 0x021, 0x020, 0x000, 0x000, 0x000, 114 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 115 0x023, 0x022, 0x021, 0x020, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 116 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x023, 0x022, 0x021, 0x031, 117 0x030, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 118 0x000, 0x000, 0x023, 0x022, 0x033, 0x032, 0x031, 0x030, 0x000, 0x000, 119 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x023, 0x030, 120 0x031, 0x033, 0x032, 0x035, 0x034, 0x000, 0x000, 0x000, 0x000, 0x000, 121 0x000, 0x000, 0x000, 0x000, 0x037, 0x036, 0x035, 0x034, 0x033, 0x032, 122 0x031, 0x041, 0x051, 0x061, 0x071, 0x081, 0x091, 0x0a1, 0x0b1, 0x000, 123 0x002, 0x000, 0x0e4, 0x011, 0x0f4, 0x002, 0x024, 0x003, 0x005, 0x012, 124 0x034, 0x013, 0x065, 0x024, 0x013, 0x063, 0x015, 0x022, 0x075, 0x034, 125 0x044, 0x023, 0x023, 0x073, 0x054, 0x033, 0x033, 0x004, 0x043, 0x014, 126 0x011, 0x043, 0x014, 0x001, 0x025, 0x015, 0x035, 0x025, 0x064, 0x055, 127 0x045, 0x035, 0x074, 0x065, 0x085, 0x0d5, 0x012, 0x095, 0x055, 0x045, 128 0x095, 0x0e5, 0x084, 0x075, 0x022, 0x0a5, 0x094, 0x085, 0x032, 0x0b5, 129 0x003, 0x0c5, 0x001, 0x044, 0x0a5, 0x032, 0x0b5, 0x094, 0x0c5, 0x0a4, 130 0x0a4, 0x054, 0x0d5, 0x0b4, 0x0b4, 0x064, 0x0f5, 0x0f5, 0x053, 0x0d4, 131 0x0e5, 0x0c4, 0x105, 0x105, 0x0c4, 0x074, 0x063, 0x0e4, 0x0d4, 0x084, 132 0x073, 0x0f4, 0x004, 0x005, 0x000, 0x053, 0x000, 0x000, 0x000, 0x000, 133 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 134 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 135 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 136 0x000, 0x000, 0x011, 0x021, 0x031, 0x030, 0x011, 0x021, 0x020, 0x000, 137 0x011, 0x010, 0x000, 0x000, 0x011, 0x033, 0x032, 0x043, 0x042, 0x053, 138 0x052, 0x063, 0x062, 0x073, 0x072, 0x083, 0x082, 0x093, 0x092, 0x091, 139 0x037, 0x036, 0x035, 0x034, 0x033, 0x045, 0x044, 0x043, 0x042, 0x053, 140 0x052, 0x063, 0x062, 0x061, 0x060, 0x000, 0x045, 0x037, 0x036, 0x035, 141 0x044, 0x043, 0x034, 0x033, 0x042, 0x053, 0x052, 0x061, 0x051, 0x060, 142 0x000, 0x000, 0x053, 0x037, 0x045, 0x044, 0x036, 0x035, 0x034, 0x043, 143 0x033, 0x042, 0x052, 0x051, 0x050, 0x000, 0x000, 0x000, 0x045, 0x044, 144 0x043, 0x037, 0x036, 0x035, 0x034, 0x033, 0x042, 0x051, 0x041, 0x050, 145 0x000, 0x000, 0x000, 0x000, 0x061, 0x051, 0x037, 0x036, 0x035, 0x034, 146 0x033, 0x032, 0x041, 0x031, 0x060, 0x000, 0x000, 0x000, 0x000, 0x000, 147 0x061, 0x051, 0x035, 0x034, 0x033, 0x023, 0x032, 0x041, 0x031, 0x060, 148 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x061, 0x041, 0x051, 0x033, 149 0x023, 0x022, 0x032, 0x031, 0x060, 0x000, 0x000, 0x000, 0x000, 0x000, 150 0x000, 0x000, 0x061, 0x060, 0x041, 0x023, 0x022, 0x031, 0x021, 0x051, 151 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x051, 0x050, 152 0x031, 0x023, 0x022, 0x021, 0x041, 0x000, 0x000, 0x000, 0x000, 0x000, 153 0x000, 0x000, 0x000, 0x000, 0x040, 0x041, 0x031, 0x032, 0x011, 0x033, 154 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 155 0x040, 0x041, 0x021, 0x011, 0x031, 0x000, 0x000, 0x000, 0x000, 0x000, 156 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x030, 0x031, 0x011, 0x021, 157 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 158 0x000, 0x000, 0x020, 0x021, 0x011, 0x000, 0x000, 0x000, 0x000, 0x000, 159 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x010, 0x011, 160 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 161 0x000, 0x000, 0x000, 0x000 162 }; 163 164 static const unsigned int lambda_lookup_table[] = { 165 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 166 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 167 0x0040, 0x0040, 0x0040, 0x0040, 0x0060, 0x0060, 0x0060, 0x0080, 168 0x0080, 0x0080, 0x00a0, 0x00c0, 0x00c0, 0x00e0, 0x0100, 0x0120, 169 0x0140, 0x0160, 0x01a0, 0x01c0, 0x0200, 0x0240, 0x0280, 0x02e0, 170 0x0320, 0x03a0, 0x0400, 0x0480, 0x0500, 0x05a0, 0x0660, 0x0720, 171 0x0800, 0x0900, 0x0a20, 0x0b60 172 }; 173 174 static const unsigned int intra4x4_lambda3[] = { 175 1, 1, 1, 1, 1, 1, 1, 1, 176 1, 1, 1, 1, 1, 1, 1, 1, 177 2, 2, 2, 2, 3, 3, 3, 4, 178 4, 4, 5, 6, 6, 7, 8, 9, 179 10, 11, 13, 14, 16, 18, 20, 23, 180 25, 29, 32, 36, 40, 45, 51, 57, 181 64, 72, 81, 91 182 }; 183 184 static v4l2_std_id tw5864_get_v4l2_std(enum tw5864_vid_std std); 185 static enum tw5864_vid_std tw5864_from_v4l2_std(v4l2_std_id v4l2_std); 186 187 static void tw5864_handle_frame_task(unsigned long data); 188 static void tw5864_handle_frame(struct tw5864_h264_frame *frame); 189 static void tw5864_frame_interval_set(struct tw5864_input *input); 190 191 static int tw5864_queue_setup(struct vb2_queue *q, unsigned int *num_buffers, 192 unsigned int *num_planes, unsigned int sizes[], 193 struct device *alloc_ctxs[]) 194 { 195 if (*num_planes) 196 return sizes[0] < H264_VLC_BUF_SIZE ? -EINVAL : 0; 197 198 sizes[0] = H264_VLC_BUF_SIZE; 199 *num_planes = 1; 200 201 return 0; 202 } 203 204 static void tw5864_buf_queue(struct vb2_buffer *vb) 205 { 206 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 207 struct vb2_queue *vq = vb->vb2_queue; 208 struct tw5864_input *dev = vb2_get_drv_priv(vq); 209 struct tw5864_buf *buf = container_of(vbuf, struct tw5864_buf, vb); 210 unsigned long flags; 211 212 spin_lock_irqsave(&dev->slock, flags); 213 list_add_tail(&buf->list, &dev->active); 214 spin_unlock_irqrestore(&dev->slock, flags); 215 } 216 217 static int tw5864_input_std_get(struct tw5864_input *input, 218 enum tw5864_vid_std *std) 219 { 220 struct tw5864_dev *dev = input->root; 221 u8 std_reg = tw_indir_readb(TW5864_INDIR_VIN_E(input->nr)); 222 223 *std = (std_reg & 0x70) >> 4; 224 225 if (std_reg & 0x80) { 226 dev_dbg(&dev->pci->dev, 227 "Video format detection is in progress, please wait\n"); 228 return -EAGAIN; 229 } 230 231 return 0; 232 } 233 234 static int tw5864_enable_input(struct tw5864_input *input) 235 { 236 struct tw5864_dev *dev = input->root; 237 int nr = input->nr; 238 unsigned long flags; 239 int d1_width = 720; 240 int d1_height; 241 int frame_width_bus_value = 0; 242 int frame_height_bus_value = 0; 243 int reg_frame_bus = 0x1c; 244 int fmt_reg_value = 0; 245 int downscale_enabled = 0; 246 247 dev_dbg(&dev->pci->dev, "Enabling channel %d\n", nr); 248 249 input->frame_seqno = 0; 250 input->frame_gop_seqno = 0; 251 input->h264_idr_pic_id = 0; 252 253 input->reg_dsp_qp = input->qp; 254 input->reg_dsp_ref_mvp_lambda = lambda_lookup_table[input->qp]; 255 input->reg_dsp_i4x4_weight = intra4x4_lambda3[input->qp]; 256 input->reg_emu = TW5864_EMU_EN_LPF | TW5864_EMU_EN_BHOST 257 | TW5864_EMU_EN_SEN | TW5864_EMU_EN_ME | TW5864_EMU_EN_DDR; 258 input->reg_dsp = nr /* channel id */ 259 | TW5864_DSP_CHROM_SW 260 | ((0xa << 8) & TW5864_DSP_MB_DELAY) 261 ; 262 263 input->resolution = D1; 264 265 d1_height = (input->std == STD_NTSC) ? 480 : 576; 266 267 input->width = d1_width; 268 input->height = d1_height; 269 270 input->reg_interlacing = 0x4; 271 272 switch (input->resolution) { 273 case D1: 274 frame_width_bus_value = 0x2cf; 275 frame_height_bus_value = input->height - 1; 276 reg_frame_bus = 0x1c; 277 fmt_reg_value = 0; 278 downscale_enabled = 0; 279 input->reg_dsp_codec |= TW5864_CIF_MAP_MD | TW5864_HD1_MAP_MD; 280 input->reg_emu |= TW5864_DSP_FRAME_TYPE_D1; 281 input->reg_interlacing = TW5864_DI_EN | TW5864_DSP_INTER_ST; 282 283 tw_setl(TW5864_FULL_HALF_FLAG, 1 << nr); 284 break; 285 case HD1: 286 input->height /= 2; 287 input->width /= 2; 288 frame_width_bus_value = 0x2cf; 289 frame_height_bus_value = input->height * 2 - 1; 290 reg_frame_bus = 0x1c; 291 fmt_reg_value = 0; 292 downscale_enabled = 0; 293 input->reg_dsp_codec |= TW5864_HD1_MAP_MD; 294 input->reg_emu |= TW5864_DSP_FRAME_TYPE_D1; 295 296 tw_clearl(TW5864_FULL_HALF_FLAG, 1 << nr); 297 298 break; 299 case CIF: 300 input->height /= 4; 301 input->width /= 2; 302 frame_width_bus_value = 0x15f; 303 frame_height_bus_value = input->height * 2 - 1; 304 reg_frame_bus = 0x07; 305 fmt_reg_value = 1; 306 downscale_enabled = 1; 307 input->reg_dsp_codec |= TW5864_CIF_MAP_MD; 308 309 tw_clearl(TW5864_FULL_HALF_FLAG, 1 << nr); 310 break; 311 case QCIF: 312 input->height /= 4; 313 input->width /= 4; 314 frame_width_bus_value = 0x15f; 315 frame_height_bus_value = input->height * 2 - 1; 316 reg_frame_bus = 0x07; 317 fmt_reg_value = 1; 318 downscale_enabled = 1; 319 input->reg_dsp_codec |= TW5864_CIF_MAP_MD; 320 321 tw_clearl(TW5864_FULL_HALF_FLAG, 1 << nr); 322 break; 323 } 324 325 /* analog input width / 4 */ 326 tw_indir_writeb(TW5864_INDIR_IN_PIC_WIDTH(nr), d1_width / 4); 327 tw_indir_writeb(TW5864_INDIR_IN_PIC_HEIGHT(nr), d1_height / 4); 328 329 /* output width / 4 */ 330 tw_indir_writeb(TW5864_INDIR_OUT_PIC_WIDTH(nr), input->width / 4); 331 tw_indir_writeb(TW5864_INDIR_OUT_PIC_HEIGHT(nr), input->height / 4); 332 333 /* 334 * Crop width from 720 to 704. 335 * Above register settings need value 720 involved. 336 */ 337 input->width = 704; 338 tw_indir_writeb(TW5864_INDIR_CROP_ETC, 339 tw_indir_readb(TW5864_INDIR_CROP_ETC) | 340 TW5864_INDIR_CROP_ETC_CROP_EN); 341 342 tw_writel(TW5864_DSP_PIC_MAX_MB, 343 ((input->width / 16) << 8) | (input->height / 16)); 344 345 tw_writel(TW5864_FRAME_WIDTH_BUS_A(nr), 346 frame_width_bus_value); 347 tw_writel(TW5864_FRAME_WIDTH_BUS_B(nr), 348 frame_width_bus_value); 349 tw_writel(TW5864_FRAME_HEIGHT_BUS_A(nr), 350 frame_height_bus_value); 351 tw_writel(TW5864_FRAME_HEIGHT_BUS_B(nr), 352 (frame_height_bus_value + 1) / 2 - 1); 353 354 tw5864_frame_interval_set(input); 355 356 if (downscale_enabled) 357 tw_setl(TW5864_H264EN_CH_DNS, 1 << nr); 358 359 tw_mask_shift_writel(TW5864_H264EN_CH_FMT_REG1, 0x3, 2 * nr, 360 fmt_reg_value); 361 362 tw_mask_shift_writel((nr < 2 363 ? TW5864_H264EN_RATE_MAX_LINE_REG1 364 : TW5864_H264EN_RATE_MAX_LINE_REG2), 365 0x1f, 5 * (nr % 2), 366 input->std == STD_NTSC ? 29 : 24); 367 368 tw_mask_shift_writel((nr < 2) ? TW5864_FRAME_BUS1 : 369 TW5864_FRAME_BUS2, 0xff, (nr % 2) * 8, 370 reg_frame_bus); 371 372 spin_lock_irqsave(&dev->slock, flags); 373 input->enabled = 1; 374 spin_unlock_irqrestore(&dev->slock, flags); 375 376 return 0; 377 } 378 379 void tw5864_request_encoded_frame(struct tw5864_input *input) 380 { 381 struct tw5864_dev *dev = input->root; 382 u32 enc_buf_id_new; 383 384 tw_setl(TW5864_DSP_CODEC, TW5864_CIF_MAP_MD | TW5864_HD1_MAP_MD); 385 tw_writel(TW5864_EMU, input->reg_emu); 386 tw_writel(TW5864_INTERLACING, input->reg_interlacing); 387 tw_writel(TW5864_DSP, input->reg_dsp); 388 389 tw_writel(TW5864_DSP_QP, input->reg_dsp_qp); 390 tw_writel(TW5864_DSP_REF_MVP_LAMBDA, input->reg_dsp_ref_mvp_lambda); 391 tw_writel(TW5864_DSP_I4x4_WEIGHT, input->reg_dsp_i4x4_weight); 392 tw_mask_shift_writel(TW5864_DSP_INTRA_MODE, TW5864_DSP_INTRA_MODE_MASK, 393 TW5864_DSP_INTRA_MODE_SHIFT, 394 TW5864_DSP_INTRA_MODE_16x16); 395 396 if (input->frame_gop_seqno == 0) { 397 /* Produce I-frame */ 398 tw_writel(TW5864_MOTION_SEARCH_ETC, TW5864_INTRA_EN); 399 input->h264_idr_pic_id++; 400 input->h264_idr_pic_id &= TW5864_DSP_REF_FRM; 401 } else { 402 /* Produce P-frame */ 403 tw_writel(TW5864_MOTION_SEARCH_ETC, TW5864_INTRA_EN | 404 TW5864_ME_EN | BIT(5) /* SRCH_OPT default */); 405 } 406 tw5864_prepare_frame_headers(input); 407 tw_writel(TW5864_VLC, 408 TW5864_VLC_PCI_SEL | 409 ((input->tail_nb_bits + 24) << TW5864_VLC_BIT_ALIGN_SHIFT) | 410 input->reg_dsp_qp); 411 412 enc_buf_id_new = tw_mask_shift_readl(TW5864_ENC_BUF_PTR_REC1, 0x3, 413 2 * input->nr); 414 tw_writel(TW5864_DSP_ENC_ORG_PTR_REG, 415 enc_buf_id_new << TW5864_DSP_ENC_ORG_PTR_SHIFT); 416 tw_writel(TW5864_DSP_ENC_REC, 417 enc_buf_id_new << 12 | ((enc_buf_id_new + 3) & 3)); 418 419 tw_writel(TW5864_SLICE, TW5864_START_NSLICE); 420 tw_writel(TW5864_SLICE, 0); 421 } 422 423 static int tw5864_disable_input(struct tw5864_input *input) 424 { 425 struct tw5864_dev *dev = input->root; 426 unsigned long flags; 427 428 dev_dbg(&dev->pci->dev, "Disabling channel %d\n", input->nr); 429 430 spin_lock_irqsave(&dev->slock, flags); 431 input->enabled = 0; 432 spin_unlock_irqrestore(&dev->slock, flags); 433 return 0; 434 } 435 436 static int tw5864_start_streaming(struct vb2_queue *q, unsigned int count) 437 { 438 struct tw5864_input *input = vb2_get_drv_priv(q); 439 int ret; 440 441 ret = tw5864_enable_input(input); 442 if (!ret) 443 return 0; 444 445 while (!list_empty(&input->active)) { 446 struct tw5864_buf *buf = list_entry(input->active.next, 447 struct tw5864_buf, list); 448 449 list_del(&buf->list); 450 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); 451 } 452 return ret; 453 } 454 455 static void tw5864_stop_streaming(struct vb2_queue *q) 456 { 457 unsigned long flags; 458 struct tw5864_input *input = vb2_get_drv_priv(q); 459 460 tw5864_disable_input(input); 461 462 spin_lock_irqsave(&input->slock, flags); 463 if (input->vb) { 464 vb2_buffer_done(&input->vb->vb.vb2_buf, VB2_BUF_STATE_ERROR); 465 input->vb = NULL; 466 } 467 while (!list_empty(&input->active)) { 468 struct tw5864_buf *buf = list_entry(input->active.next, 469 struct tw5864_buf, list); 470 471 list_del(&buf->list); 472 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 473 } 474 spin_unlock_irqrestore(&input->slock, flags); 475 } 476 477 static const struct vb2_ops tw5864_video_qops = { 478 .queue_setup = tw5864_queue_setup, 479 .buf_queue = tw5864_buf_queue, 480 .start_streaming = tw5864_start_streaming, 481 .stop_streaming = tw5864_stop_streaming, 482 .wait_prepare = vb2_ops_wait_prepare, 483 .wait_finish = vb2_ops_wait_finish, 484 }; 485 486 static int tw5864_s_ctrl(struct v4l2_ctrl *ctrl) 487 { 488 struct tw5864_input *input = 489 container_of(ctrl->handler, struct tw5864_input, hdl); 490 struct tw5864_dev *dev = input->root; 491 unsigned long flags; 492 493 switch (ctrl->id) { 494 case V4L2_CID_BRIGHTNESS: 495 tw_indir_writeb(TW5864_INDIR_VIN_A_BRIGHT(input->nr), 496 (u8)ctrl->val); 497 break; 498 case V4L2_CID_HUE: 499 tw_indir_writeb(TW5864_INDIR_VIN_7_HUE(input->nr), 500 (u8)ctrl->val); 501 break; 502 case V4L2_CID_CONTRAST: 503 tw_indir_writeb(TW5864_INDIR_VIN_9_CNTRST(input->nr), 504 (u8)ctrl->val); 505 break; 506 case V4L2_CID_SATURATION: 507 tw_indir_writeb(TW5864_INDIR_VIN_B_SAT_U(input->nr), 508 (u8)ctrl->val); 509 tw_indir_writeb(TW5864_INDIR_VIN_C_SAT_V(input->nr), 510 (u8)ctrl->val); 511 break; 512 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 513 input->gop = ctrl->val; 514 return 0; 515 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: 516 spin_lock_irqsave(&input->slock, flags); 517 input->qp = ctrl->val; 518 input->reg_dsp_qp = input->qp; 519 input->reg_dsp_ref_mvp_lambda = lambda_lookup_table[input->qp]; 520 input->reg_dsp_i4x4_weight = intra4x4_lambda3[input->qp]; 521 spin_unlock_irqrestore(&input->slock, flags); 522 return 0; 523 case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: 524 memset(input->md_threshold_grid_values, ctrl->val, 525 sizeof(input->md_threshold_grid_values)); 526 return 0; 527 case V4L2_CID_DETECT_MD_MODE: 528 return 0; 529 case V4L2_CID_DETECT_MD_THRESHOLD_GRID: 530 /* input->md_threshold_grid_ctrl->p_new.p_u16 contains data */ 531 memcpy(input->md_threshold_grid_values, 532 input->md_threshold_grid_ctrl->p_new.p_u16, 533 sizeof(input->md_threshold_grid_values)); 534 return 0; 535 } 536 return 0; 537 } 538 539 static int tw5864_fmt_vid_cap(struct file *file, void *priv, 540 struct v4l2_format *f) 541 { 542 struct tw5864_input *input = video_drvdata(file); 543 544 f->fmt.pix.width = 704; 545 switch (input->std) { 546 default: 547 WARN_ON_ONCE(1); 548 case STD_NTSC: 549 f->fmt.pix.height = 480; 550 break; 551 case STD_PAL: 552 case STD_SECAM: 553 f->fmt.pix.height = 576; 554 break; 555 } 556 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 557 f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; 558 f->fmt.pix.sizeimage = H264_VLC_BUF_SIZE; 559 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 560 return 0; 561 } 562 563 static int tw5864_enum_input(struct file *file, void *priv, 564 struct v4l2_input *i) 565 { 566 struct tw5864_input *input = video_drvdata(file); 567 struct tw5864_dev *dev = input->root; 568 569 u8 indir_0x000 = tw_indir_readb(TW5864_INDIR_VIN_0(input->nr)); 570 u8 indir_0x00d = tw_indir_readb(TW5864_INDIR_VIN_D(input->nr)); 571 u8 v1 = indir_0x000; 572 u8 v2 = indir_0x00d; 573 574 if (i->index) 575 return -EINVAL; 576 577 i->type = V4L2_INPUT_TYPE_CAMERA; 578 snprintf(i->name, sizeof(i->name), "Encoder %d", input->nr); 579 i->std = TW5864_NORMS; 580 if (v1 & (1 << 7)) 581 i->status |= V4L2_IN_ST_NO_SYNC; 582 if (!(v1 & (1 << 6))) 583 i->status |= V4L2_IN_ST_NO_H_LOCK; 584 if (v1 & (1 << 2)) 585 i->status |= V4L2_IN_ST_NO_SIGNAL; 586 if (v1 & (1 << 1)) 587 i->status |= V4L2_IN_ST_NO_COLOR; 588 if (v2 & (1 << 2)) 589 i->status |= V4L2_IN_ST_MACROVISION; 590 591 return 0; 592 } 593 594 static int tw5864_g_input(struct file *file, void *priv, unsigned int *i) 595 { 596 *i = 0; 597 return 0; 598 } 599 600 static int tw5864_s_input(struct file *file, void *priv, unsigned int i) 601 { 602 if (i) 603 return -EINVAL; 604 return 0; 605 } 606 607 static int tw5864_querycap(struct file *file, void *priv, 608 struct v4l2_capability *cap) 609 { 610 struct tw5864_input *input = video_drvdata(file); 611 612 strcpy(cap->driver, "tw5864"); 613 snprintf(cap->card, sizeof(cap->card), "TW5864 Encoder %d", 614 input->nr); 615 sprintf(cap->bus_info, "PCI:%s", pci_name(input->root->pci)); 616 return 0; 617 } 618 619 static int tw5864_querystd(struct file *file, void *priv, v4l2_std_id *std) 620 { 621 struct tw5864_input *input = video_drvdata(file); 622 enum tw5864_vid_std tw_std; 623 int ret; 624 625 ret = tw5864_input_std_get(input, &tw_std); 626 if (ret) 627 return ret; 628 *std = tw5864_get_v4l2_std(tw_std); 629 630 return 0; 631 } 632 633 static int tw5864_g_std(struct file *file, void *priv, v4l2_std_id *std) 634 { 635 struct tw5864_input *input = video_drvdata(file); 636 637 *std = input->v4l2_std; 638 return 0; 639 } 640 641 static int tw5864_s_std(struct file *file, void *priv, v4l2_std_id std) 642 { 643 struct tw5864_input *input = video_drvdata(file); 644 struct tw5864_dev *dev = input->root; 645 646 input->v4l2_std = std; 647 input->std = tw5864_from_v4l2_std(std); 648 tw_indir_writeb(TW5864_INDIR_VIN_E(input->nr), input->std); 649 return 0; 650 } 651 652 static int tw5864_enum_fmt_vid_cap(struct file *file, void *priv, 653 struct v4l2_fmtdesc *f) 654 { 655 if (f->index) 656 return -EINVAL; 657 658 f->pixelformat = V4L2_PIX_FMT_H264; 659 660 return 0; 661 } 662 663 static int tw5864_subscribe_event(struct v4l2_fh *fh, 664 const struct v4l2_event_subscription *sub) 665 { 666 switch (sub->type) { 667 case V4L2_EVENT_CTRL: 668 return v4l2_ctrl_subscribe_event(fh, sub); 669 case V4L2_EVENT_MOTION_DET: 670 /* 671 * Allow for up to 30 events (1 second for NTSC) to be stored. 672 */ 673 return v4l2_event_subscribe(fh, sub, 30, NULL); 674 } 675 return -EINVAL; 676 } 677 678 static void tw5864_frame_interval_set(struct tw5864_input *input) 679 { 680 /* 681 * This register value seems to follow such approach: In each second 682 * interval, when processing Nth frame, it checks Nth bit of register 683 * value and, if the bit is 1, it processes the frame, otherwise the 684 * frame is discarded. 685 * So unary representation would work, but more or less equal gaps 686 * between the frames should be preserved. 687 * 688 * For 1 FPS - 0x00000001 689 * 00000000 00000000 00000000 00000001 690 * 691 * For max FPS - set all 25/30 lower bits: 692 * 00111111 11111111 11111111 11111111 (NTSC) 693 * 00000001 11111111 11111111 11111111 (PAL) 694 * 695 * For half of max FPS - use such pattern: 696 * 00010101 01010101 01010101 01010101 (NTSC) 697 * 00000001 01010101 01010101 01010101 (PAL) 698 * 699 * Et cetera. 700 * 701 * The value supplied to hardware is capped by mask of 25/30 lower bits. 702 */ 703 struct tw5864_dev *dev = input->root; 704 u32 unary_framerate = 0; 705 int shift = 0; 706 int std_max_fps = input->std == STD_NTSC ? 30 : 25; 707 708 for (shift = 0; shift < std_max_fps; shift += input->frame_interval) 709 unary_framerate |= 0x00000001 << shift; 710 711 tw_writel(TW5864_H264EN_RATE_CNTL_LO_WORD(input->nr, 0), 712 unary_framerate >> 16); 713 tw_writel(TW5864_H264EN_RATE_CNTL_HI_WORD(input->nr, 0), 714 unary_framerate & 0xffff); 715 } 716 717 static int tw5864_frameinterval_get(struct tw5864_input *input, 718 struct v4l2_fract *frameinterval) 719 { 720 switch (input->std) { 721 case STD_NTSC: 722 frameinterval->numerator = 1001; 723 frameinterval->denominator = 30000; 724 break; 725 case STD_PAL: 726 case STD_SECAM: 727 frameinterval->numerator = 1; 728 frameinterval->denominator = 25; 729 break; 730 default: 731 WARN(1, "tw5864_frameinterval_get requested for unknown std %d\n", 732 input->std); 733 return -EINVAL; 734 } 735 736 return 0; 737 } 738 739 static int tw5864_enum_framesizes(struct file *file, void *priv, 740 struct v4l2_frmsizeenum *fsize) 741 { 742 struct tw5864_input *input = video_drvdata(file); 743 744 if (fsize->index > 0) 745 return -EINVAL; 746 if (fsize->pixel_format != V4L2_PIX_FMT_H264) 747 return -EINVAL; 748 749 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 750 fsize->discrete.width = 704; 751 fsize->discrete.height = input->std == STD_NTSC ? 480 : 576; 752 753 return 0; 754 } 755 756 static int tw5864_enum_frameintervals(struct file *file, void *priv, 757 struct v4l2_frmivalenum *fintv) 758 { 759 struct tw5864_input *input = video_drvdata(file); 760 struct v4l2_fract frameinterval; 761 int std_max_fps = input->std == STD_NTSC ? 30 : 25; 762 struct v4l2_frmsizeenum fsize = { .index = fintv->index, 763 .pixel_format = fintv->pixel_format }; 764 int ret; 765 766 ret = tw5864_enum_framesizes(file, priv, &fsize); 767 if (ret) 768 return ret; 769 770 if (fintv->width != fsize.discrete.width || 771 fintv->height != fsize.discrete.height) 772 return -EINVAL; 773 774 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; 775 776 ret = tw5864_frameinterval_get(input, &frameinterval); 777 fintv->stepwise.step = frameinterval; 778 fintv->stepwise.min = frameinterval; 779 fintv->stepwise.max = frameinterval; 780 fintv->stepwise.max.numerator *= std_max_fps; 781 782 return ret; 783 } 784 785 static int tw5864_g_parm(struct file *file, void *priv, 786 struct v4l2_streamparm *sp) 787 { 788 struct tw5864_input *input = video_drvdata(file); 789 struct v4l2_captureparm *cp = &sp->parm.capture; 790 int ret; 791 792 cp->capability = V4L2_CAP_TIMEPERFRAME; 793 794 ret = tw5864_frameinterval_get(input, &cp->timeperframe); 795 cp->timeperframe.numerator *= input->frame_interval; 796 cp->capturemode = 0; 797 cp->readbuffers = 2; 798 799 return ret; 800 } 801 802 static int tw5864_s_parm(struct file *file, void *priv, 803 struct v4l2_streamparm *sp) 804 { 805 struct tw5864_input *input = video_drvdata(file); 806 struct v4l2_fract *t = &sp->parm.capture.timeperframe; 807 struct v4l2_fract time_base; 808 int ret; 809 810 ret = tw5864_frameinterval_get(input, &time_base); 811 if (ret) 812 return ret; 813 814 if (!t->numerator || !t->denominator) { 815 t->numerator = time_base.numerator * input->frame_interval; 816 t->denominator = time_base.denominator; 817 } else if (t->denominator != time_base.denominator) { 818 t->numerator = t->numerator * time_base.denominator / 819 t->denominator; 820 t->denominator = time_base.denominator; 821 } 822 823 input->frame_interval = t->numerator / time_base.numerator; 824 if (input->frame_interval < 1) 825 input->frame_interval = 1; 826 tw5864_frame_interval_set(input); 827 return tw5864_g_parm(file, priv, sp); 828 } 829 830 static const struct v4l2_ctrl_ops tw5864_ctrl_ops = { 831 .s_ctrl = tw5864_s_ctrl, 832 }; 833 834 static const struct v4l2_file_operations video_fops = { 835 .owner = THIS_MODULE, 836 .open = v4l2_fh_open, 837 .release = vb2_fop_release, 838 .read = vb2_fop_read, 839 .poll = vb2_fop_poll, 840 .mmap = vb2_fop_mmap, 841 .unlocked_ioctl = video_ioctl2, 842 }; 843 844 #ifdef CONFIG_VIDEO_ADV_DEBUG 845 846 #define INDIR_SPACE_MAP_SHIFT 0x100000 847 848 static int tw5864_g_reg(struct file *file, void *fh, 849 struct v4l2_dbg_register *reg) 850 { 851 struct tw5864_input *input = video_drvdata(file); 852 struct tw5864_dev *dev = input->root; 853 854 if (reg->reg < INDIR_SPACE_MAP_SHIFT) { 855 if (reg->reg > 0x87fff) 856 return -EINVAL; 857 reg->size = 4; 858 reg->val = tw_readl(reg->reg); 859 } else { 860 __u64 indir_addr = reg->reg - INDIR_SPACE_MAP_SHIFT; 861 862 if (indir_addr > 0xefe) 863 return -EINVAL; 864 reg->size = 1; 865 reg->val = tw_indir_readb(reg->reg); 866 } 867 return 0; 868 } 869 870 static int tw5864_s_reg(struct file *file, void *fh, 871 const struct v4l2_dbg_register *reg) 872 { 873 struct tw5864_input *input = video_drvdata(file); 874 struct tw5864_dev *dev = input->root; 875 876 if (reg->reg < INDIR_SPACE_MAP_SHIFT) { 877 if (reg->reg > 0x87fff) 878 return -EINVAL; 879 tw_writel(reg->reg, reg->val); 880 } else { 881 __u64 indir_addr = reg->reg - INDIR_SPACE_MAP_SHIFT; 882 883 if (indir_addr > 0xefe) 884 return -EINVAL; 885 tw_indir_writeb(reg->reg, reg->val); 886 } 887 return 0; 888 } 889 #endif 890 891 static const struct v4l2_ioctl_ops video_ioctl_ops = { 892 .vidioc_querycap = tw5864_querycap, 893 .vidioc_enum_fmt_vid_cap = tw5864_enum_fmt_vid_cap, 894 .vidioc_reqbufs = vb2_ioctl_reqbufs, 895 .vidioc_create_bufs = vb2_ioctl_create_bufs, 896 .vidioc_querybuf = vb2_ioctl_querybuf, 897 .vidioc_qbuf = vb2_ioctl_qbuf, 898 .vidioc_dqbuf = vb2_ioctl_dqbuf, 899 .vidioc_expbuf = vb2_ioctl_expbuf, 900 .vidioc_querystd = tw5864_querystd, 901 .vidioc_s_std = tw5864_s_std, 902 .vidioc_g_std = tw5864_g_std, 903 .vidioc_enum_input = tw5864_enum_input, 904 .vidioc_g_input = tw5864_g_input, 905 .vidioc_s_input = tw5864_s_input, 906 .vidioc_streamon = vb2_ioctl_streamon, 907 .vidioc_streamoff = vb2_ioctl_streamoff, 908 .vidioc_try_fmt_vid_cap = tw5864_fmt_vid_cap, 909 .vidioc_s_fmt_vid_cap = tw5864_fmt_vid_cap, 910 .vidioc_g_fmt_vid_cap = tw5864_fmt_vid_cap, 911 .vidioc_log_status = v4l2_ctrl_log_status, 912 .vidioc_subscribe_event = tw5864_subscribe_event, 913 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 914 .vidioc_enum_framesizes = tw5864_enum_framesizes, 915 .vidioc_enum_frameintervals = tw5864_enum_frameintervals, 916 .vidioc_s_parm = tw5864_s_parm, 917 .vidioc_g_parm = tw5864_g_parm, 918 #ifdef CONFIG_VIDEO_ADV_DEBUG 919 .vidioc_g_register = tw5864_g_reg, 920 .vidioc_s_register = tw5864_s_reg, 921 #endif 922 }; 923 924 static const struct video_device tw5864_video_template = { 925 .name = "tw5864_video", 926 .fops = &video_fops, 927 .ioctl_ops = &video_ioctl_ops, 928 .release = video_device_release_empty, 929 .tvnorms = TW5864_NORMS, 930 .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | 931 V4L2_CAP_STREAMING, 932 }; 933 934 /* Motion Detection Threshold matrix */ 935 static const struct v4l2_ctrl_config tw5864_md_thresholds = { 936 .ops = &tw5864_ctrl_ops, 937 .id = V4L2_CID_DETECT_MD_THRESHOLD_GRID, 938 .dims = {MD_CELLS_HOR, MD_CELLS_VERT}, 939 .def = 14, 940 /* See tw5864_md_metric_from_mvd() */ 941 .max = 2 * 0x0f, 942 .step = 1, 943 }; 944 945 static int tw5864_video_input_init(struct tw5864_input *dev, int video_nr); 946 static void tw5864_video_input_fini(struct tw5864_input *dev); 947 static void tw5864_encoder_tables_upload(struct tw5864_dev *dev); 948 949 int tw5864_video_init(struct tw5864_dev *dev, int *video_nr) 950 { 951 int i; 952 int ret; 953 unsigned long flags; 954 int last_dma_allocated = -1; 955 int last_input_nr_registered = -1; 956 957 for (i = 0; i < H264_BUF_CNT; i++) { 958 struct tw5864_h264_frame *frame = &dev->h264_buf[i]; 959 960 frame->vlc.addr = dma_alloc_coherent(&dev->pci->dev, 961 H264_VLC_BUF_SIZE, 962 &frame->vlc.dma_addr, 963 GFP_KERNEL | GFP_DMA32); 964 if (!frame->vlc.addr) { 965 dev_err(&dev->pci->dev, "dma alloc fail\n"); 966 ret = -ENOMEM; 967 goto free_dma; 968 } 969 frame->mv.addr = dma_alloc_coherent(&dev->pci->dev, 970 H264_MV_BUF_SIZE, 971 &frame->mv.dma_addr, 972 GFP_KERNEL | GFP_DMA32); 973 if (!frame->mv.addr) { 974 dev_err(&dev->pci->dev, "dma alloc fail\n"); 975 ret = -ENOMEM; 976 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, 977 frame->vlc.addr, frame->vlc.dma_addr); 978 goto free_dma; 979 } 980 last_dma_allocated = i; 981 } 982 983 tw5864_encoder_tables_upload(dev); 984 985 /* Picture is distorted without this block */ 986 /* use falling edge to sample 54M to 108M */ 987 tw_indir_writeb(TW5864_INDIR_VD_108_POL, TW5864_INDIR_VD_108_POL_BOTH); 988 tw_indir_writeb(TW5864_INDIR_CLK0_SEL, 0x00); 989 990 tw_indir_writeb(TW5864_INDIR_DDRA_DLL_DQS_SEL0, 0x02); 991 tw_indir_writeb(TW5864_INDIR_DDRA_DLL_DQS_SEL1, 0x02); 992 tw_indir_writeb(TW5864_INDIR_DDRA_DLL_CLK90_SEL, 0x02); 993 tw_indir_writeb(TW5864_INDIR_DDRB_DLL_DQS_SEL0, 0x02); 994 tw_indir_writeb(TW5864_INDIR_DDRB_DLL_DQS_SEL1, 0x02); 995 tw_indir_writeb(TW5864_INDIR_DDRB_DLL_CLK90_SEL, 0x02); 996 997 /* video input reset */ 998 tw_indir_writeb(TW5864_INDIR_RESET, 0); 999 tw_indir_writeb(TW5864_INDIR_RESET, TW5864_INDIR_RESET_VD | 1000 TW5864_INDIR_RESET_DLL | TW5864_INDIR_RESET_MUX_CORE); 1001 msleep(20); 1002 1003 /* 1004 * Select Part A mode for all channels. 1005 * tw_setl instead of tw_clearl for Part B mode. 1006 * 1007 * I guess "Part B" is primarily for downscaled version of same channel 1008 * which goes in Part A of same bus 1009 */ 1010 tw_writel(TW5864_FULL_HALF_MODE_SEL, 0); 1011 1012 tw_indir_writeb(TW5864_INDIR_PV_VD_CK_POL, 1013 TW5864_INDIR_PV_VD_CK_POL_VD(0) | 1014 TW5864_INDIR_PV_VD_CK_POL_VD(1) | 1015 TW5864_INDIR_PV_VD_CK_POL_VD(2) | 1016 TW5864_INDIR_PV_VD_CK_POL_VD(3)); 1017 1018 spin_lock_irqsave(&dev->slock, flags); 1019 dev->encoder_busy = 0; 1020 dev->h264_buf_r_index = 0; 1021 dev->h264_buf_w_index = 0; 1022 tw_writel(TW5864_VLC_STREAM_BASE_ADDR, 1023 dev->h264_buf[dev->h264_buf_w_index].vlc.dma_addr); 1024 tw_writel(TW5864_MV_STREAM_BASE_ADDR, 1025 dev->h264_buf[dev->h264_buf_w_index].mv.dma_addr); 1026 spin_unlock_irqrestore(&dev->slock, flags); 1027 1028 tw_writel(TW5864_SEN_EN_CH, 0x000f); 1029 tw_writel(TW5864_H264EN_CH_EN, 0x000f); 1030 1031 tw_writel(TW5864_H264EN_BUS0_MAP, 0x00000000); 1032 tw_writel(TW5864_H264EN_BUS1_MAP, 0x00001111); 1033 tw_writel(TW5864_H264EN_BUS2_MAP, 0x00002222); 1034 tw_writel(TW5864_H264EN_BUS3_MAP, 0x00003333); 1035 1036 /* 1037 * Quote from Intersil (manufacturer): 1038 * 0x0038 is managed by HW, and by default it won't pass the pointer set 1039 * at 0x0010. So if you don't do encoding, 0x0038 should stay at '3' 1040 * (with 4 frames in buffer). If you encode one frame and then move 1041 * 0x0010 to '1' for example, HW will take one more frame and set it to 1042 * buffer #0, and then you should see 0x0038 is set to '0'. There is 1043 * only one HW encoder engine, so 4 channels cannot get encoded 1044 * simultaneously. But each channel does have its own buffer (for 1045 * original frames and reconstructed frames). So there is no problem to 1046 * manage encoding for 4 channels at same time and no need to force 1047 * I-frames in switching channels. 1048 * End of quote. 1049 * 1050 * If we set 0x0010 (TW5864_ENC_BUF_PTR_REC1) to 0 (for any channel), we 1051 * have no "rolling" (until we change this value). 1052 * If we set 0x0010 (TW5864_ENC_BUF_PTR_REC1) to 0x3, it starts to roll 1053 * continuously together with 0x0038. 1054 */ 1055 tw_writel(TW5864_ENC_BUF_PTR_REC1, 0x00ff); 1056 tw_writel(TW5864_PCI_INTTM_SCALE, 0); 1057 1058 tw_writel(TW5864_INTERLACING, TW5864_DI_EN); 1059 tw_writel(TW5864_MASTER_ENB_REG, TW5864_PCI_VLC_INTR_ENB); 1060 tw_writel(TW5864_PCI_INTR_CTL, 1061 TW5864_TIMER_INTR_ENB | TW5864_PCI_MAST_ENB | 1062 TW5864_MVD_VLC_MAST_ENB); 1063 1064 dev->irqmask |= TW5864_INTR_VLC_DONE | TW5864_INTR_TIMER; 1065 tw5864_irqmask_apply(dev); 1066 1067 tasklet_init(&dev->tasklet, tw5864_handle_frame_task, 1068 (unsigned long)dev); 1069 1070 for (i = 0; i < TW5864_INPUTS; i++) { 1071 dev->inputs[i].root = dev; 1072 dev->inputs[i].nr = i; 1073 ret = tw5864_video_input_init(&dev->inputs[i], video_nr[i]); 1074 if (ret) 1075 goto fini_video_inputs; 1076 last_input_nr_registered = i; 1077 } 1078 1079 return 0; 1080 1081 fini_video_inputs: 1082 for (i = last_input_nr_registered; i >= 0; i--) 1083 tw5864_video_input_fini(&dev->inputs[i]); 1084 1085 tasklet_kill(&dev->tasklet); 1086 1087 free_dma: 1088 for (i = last_dma_allocated; i >= 0; i--) { 1089 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, 1090 dev->h264_buf[i].vlc.addr, 1091 dev->h264_buf[i].vlc.dma_addr); 1092 dma_free_coherent(&dev->pci->dev, H264_MV_BUF_SIZE, 1093 dev->h264_buf[i].mv.addr, 1094 dev->h264_buf[i].mv.dma_addr); 1095 } 1096 1097 return ret; 1098 } 1099 1100 static int tw5864_video_input_init(struct tw5864_input *input, int video_nr) 1101 { 1102 struct tw5864_dev *dev = input->root; 1103 int ret; 1104 struct v4l2_ctrl_handler *hdl = &input->hdl; 1105 1106 mutex_init(&input->lock); 1107 spin_lock_init(&input->slock); 1108 1109 /* setup video buffers queue */ 1110 INIT_LIST_HEAD(&input->active); 1111 input->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1112 input->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1113 input->vidq.io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF; 1114 input->vidq.ops = &tw5864_video_qops; 1115 input->vidq.mem_ops = &vb2_dma_contig_memops; 1116 input->vidq.drv_priv = input; 1117 input->vidq.gfp_flags = 0; 1118 input->vidq.buf_struct_size = sizeof(struct tw5864_buf); 1119 input->vidq.lock = &input->lock; 1120 input->vidq.min_buffers_needed = 2; 1121 input->vidq.dev = &input->root->pci->dev; 1122 ret = vb2_queue_init(&input->vidq); 1123 if (ret) 1124 goto free_mutex; 1125 1126 input->vdev = tw5864_video_template; 1127 input->vdev.v4l2_dev = &input->root->v4l2_dev; 1128 input->vdev.lock = &input->lock; 1129 input->vdev.queue = &input->vidq; 1130 video_set_drvdata(&input->vdev, input); 1131 1132 /* Initialize the device control structures */ 1133 v4l2_ctrl_handler_init(hdl, 6); 1134 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, 1135 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); 1136 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, 1137 V4L2_CID_CONTRAST, 0, 255, 1, 100); 1138 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, 1139 V4L2_CID_SATURATION, 0, 255, 1, 128); 1140 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, V4L2_CID_HUE, -128, 127, 1, 0); 1141 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1142 1, MAX_GOP_SIZE, 1, GOP_SIZE); 1143 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, 1144 V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 28, 51, 1, QP_VALUE); 1145 v4l2_ctrl_new_std_menu(hdl, &tw5864_ctrl_ops, 1146 V4L2_CID_DETECT_MD_MODE, 1147 V4L2_DETECT_MD_MODE_THRESHOLD_GRID, 0, 1148 V4L2_DETECT_MD_MODE_DISABLED); 1149 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, 1150 V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD, 1151 tw5864_md_thresholds.min, tw5864_md_thresholds.max, 1152 tw5864_md_thresholds.step, tw5864_md_thresholds.def); 1153 input->md_threshold_grid_ctrl = 1154 v4l2_ctrl_new_custom(hdl, &tw5864_md_thresholds, NULL); 1155 if (hdl->error) { 1156 ret = hdl->error; 1157 goto free_v4l2_hdl; 1158 } 1159 input->vdev.ctrl_handler = hdl; 1160 v4l2_ctrl_handler_setup(hdl); 1161 1162 input->qp = QP_VALUE; 1163 input->gop = GOP_SIZE; 1164 input->frame_interval = 1; 1165 1166 ret = video_register_device(&input->vdev, VFL_TYPE_GRABBER, video_nr); 1167 if (ret) 1168 goto free_v4l2_hdl; 1169 1170 dev_info(&input->root->pci->dev, "Registered video device %s\n", 1171 video_device_node_name(&input->vdev)); 1172 1173 /* 1174 * Set default video standard. Doesn't matter which, the detected value 1175 * will be found out by VIDIOC_QUERYSTD handler. 1176 */ 1177 input->v4l2_std = V4L2_STD_NTSC_M; 1178 input->std = STD_NTSC; 1179 1180 tw_indir_writeb(TW5864_INDIR_VIN_E(video_nr), 0x07); 1181 /* to initiate auto format recognition */ 1182 tw_indir_writeb(TW5864_INDIR_VIN_F(video_nr), 0xff); 1183 1184 return 0; 1185 1186 free_v4l2_hdl: 1187 v4l2_ctrl_handler_free(hdl); 1188 vb2_queue_release(&input->vidq); 1189 free_mutex: 1190 mutex_destroy(&input->lock); 1191 1192 return ret; 1193 } 1194 1195 static void tw5864_video_input_fini(struct tw5864_input *dev) 1196 { 1197 video_unregister_device(&dev->vdev); 1198 v4l2_ctrl_handler_free(&dev->hdl); 1199 vb2_queue_release(&dev->vidq); 1200 } 1201 1202 void tw5864_video_fini(struct tw5864_dev *dev) 1203 { 1204 int i; 1205 1206 tasklet_kill(&dev->tasklet); 1207 1208 for (i = 0; i < TW5864_INPUTS; i++) 1209 tw5864_video_input_fini(&dev->inputs[i]); 1210 1211 for (i = 0; i < H264_BUF_CNT; i++) { 1212 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, 1213 dev->h264_buf[i].vlc.addr, 1214 dev->h264_buf[i].vlc.dma_addr); 1215 dma_free_coherent(&dev->pci->dev, H264_MV_BUF_SIZE, 1216 dev->h264_buf[i].mv.addr, 1217 dev->h264_buf[i].mv.dma_addr); 1218 } 1219 } 1220 1221 void tw5864_prepare_frame_headers(struct tw5864_input *input) 1222 { 1223 struct tw5864_buf *vb = input->vb; 1224 u8 *dst; 1225 size_t dst_space; 1226 unsigned long flags; 1227 1228 if (!vb) { 1229 spin_lock_irqsave(&input->slock, flags); 1230 if (list_empty(&input->active)) { 1231 spin_unlock_irqrestore(&input->slock, flags); 1232 input->vb = NULL; 1233 return; 1234 } 1235 vb = list_first_entry(&input->active, struct tw5864_buf, list); 1236 list_del(&vb->list); 1237 spin_unlock_irqrestore(&input->slock, flags); 1238 } 1239 1240 dst = vb2_plane_vaddr(&vb->vb.vb2_buf, 0); 1241 dst_space = vb2_plane_size(&vb->vb.vb2_buf, 0); 1242 1243 /* 1244 * Low-level bitstream writing functions don't have a fine way to say 1245 * correctly that supplied buffer is too small. So we just check there 1246 * and warn, and don't care at lower level. 1247 * Currently all headers take below 32 bytes. 1248 * The buffer is supposed to have plenty of free space at this point, 1249 * anyway. 1250 */ 1251 if (WARN_ON_ONCE(dst_space < 128)) 1252 return; 1253 1254 /* 1255 * Generate H264 headers: 1256 * If this is first frame, put SPS and PPS 1257 */ 1258 if (input->frame_gop_seqno == 0) 1259 tw5864_h264_put_stream_header(&dst, &dst_space, input->qp, 1260 input->width, input->height); 1261 1262 /* Put slice header */ 1263 tw5864_h264_put_slice_header(&dst, &dst_space, input->h264_idr_pic_id, 1264 input->frame_gop_seqno, 1265 &input->tail_nb_bits, &input->tail); 1266 input->vb = vb; 1267 input->buf_cur_ptr = dst; 1268 input->buf_cur_space_left = dst_space; 1269 } 1270 1271 /* 1272 * Returns heuristic motion detection metric value from known components of 1273 * hardware-provided Motion Vector Data. 1274 */ 1275 static unsigned int tw5864_md_metric_from_mvd(u32 mvd) 1276 { 1277 /* 1278 * Format of motion vector data exposed by tw5864, according to 1279 * manufacturer: 1280 * mv_x 10 bits 1281 * mv_y 10 bits 1282 * non_zero_members 8 bits 1283 * mb_type 3 bits 1284 * reserved 1 bit 1285 * 1286 * non_zero_members: number of non-zero residuals in each macro block 1287 * after quantization 1288 * 1289 * unsigned int reserved = mvd >> 31; 1290 * unsigned int mb_type = (mvd >> 28) & 0x7; 1291 * unsigned int non_zero_members = (mvd >> 20) & 0xff; 1292 */ 1293 unsigned int mv_y = (mvd >> 10) & 0x3ff; 1294 unsigned int mv_x = mvd & 0x3ff; 1295 1296 /* heuristic: */ 1297 mv_x &= 0x0f; 1298 mv_y &= 0x0f; 1299 1300 return mv_y + mv_x; 1301 } 1302 1303 static int tw5864_is_motion_triggered(struct tw5864_h264_frame *frame) 1304 { 1305 struct tw5864_input *input = frame->input; 1306 u32 *mv = (u32 *)frame->mv.addr; 1307 int i; 1308 int detected = 0; 1309 1310 for (i = 0; i < MD_CELLS; i++) { 1311 const u16 thresh = input->md_threshold_grid_values[i]; 1312 const unsigned int metric = tw5864_md_metric_from_mvd(mv[i]); 1313 1314 if (metric > thresh) 1315 detected = 1; 1316 1317 if (detected) 1318 break; 1319 } 1320 return detected; 1321 } 1322 1323 static void tw5864_handle_frame_task(unsigned long data) 1324 { 1325 struct tw5864_dev *dev = (struct tw5864_dev *)data; 1326 unsigned long flags; 1327 int batch_size = H264_BUF_CNT; 1328 1329 spin_lock_irqsave(&dev->slock, flags); 1330 while (dev->h264_buf_r_index != dev->h264_buf_w_index && batch_size--) { 1331 struct tw5864_h264_frame *frame = 1332 &dev->h264_buf[dev->h264_buf_r_index]; 1333 1334 spin_unlock_irqrestore(&dev->slock, flags); 1335 dma_sync_single_for_cpu(&dev->pci->dev, frame->vlc.dma_addr, 1336 H264_VLC_BUF_SIZE, DMA_FROM_DEVICE); 1337 dma_sync_single_for_cpu(&dev->pci->dev, frame->mv.dma_addr, 1338 H264_MV_BUF_SIZE, DMA_FROM_DEVICE); 1339 tw5864_handle_frame(frame); 1340 dma_sync_single_for_device(&dev->pci->dev, frame->vlc.dma_addr, 1341 H264_VLC_BUF_SIZE, DMA_FROM_DEVICE); 1342 dma_sync_single_for_device(&dev->pci->dev, frame->mv.dma_addr, 1343 H264_MV_BUF_SIZE, DMA_FROM_DEVICE); 1344 spin_lock_irqsave(&dev->slock, flags); 1345 1346 dev->h264_buf_r_index++; 1347 dev->h264_buf_r_index %= H264_BUF_CNT; 1348 } 1349 spin_unlock_irqrestore(&dev->slock, flags); 1350 } 1351 1352 #ifdef DEBUG 1353 static u32 tw5864_vlc_checksum(u32 *data, int len) 1354 { 1355 u32 val, count_len = len; 1356 1357 val = *data++; 1358 while (((count_len >> 2) - 1) > 0) { 1359 val ^= *data++; 1360 count_len -= 4; 1361 } 1362 val ^= htonl((len >> 2)); 1363 return val; 1364 } 1365 #endif 1366 1367 static void tw5864_handle_frame(struct tw5864_h264_frame *frame) 1368 { 1369 #define SKIP_VLCBUF_BYTES 3 1370 struct tw5864_input *input = frame->input; 1371 struct tw5864_dev *dev = input->root; 1372 struct tw5864_buf *vb; 1373 struct vb2_v4l2_buffer *v4l2_buf; 1374 int frame_len = frame->vlc_len - SKIP_VLCBUF_BYTES; 1375 u8 *dst = input->buf_cur_ptr; 1376 u8 tail_mask, vlc_mask = 0; 1377 int i; 1378 u8 vlc_first_byte = ((u8 *)(frame->vlc.addr + SKIP_VLCBUF_BYTES))[0]; 1379 unsigned long flags; 1380 int zero_run; 1381 u8 *src; 1382 u8 *src_end; 1383 1384 #ifdef DEBUG 1385 if (frame->checksum != 1386 tw5864_vlc_checksum((u32 *)frame->vlc.addr, frame_len)) 1387 dev_err(&dev->pci->dev, 1388 "Checksum of encoded frame doesn't match!\n"); 1389 #endif 1390 1391 spin_lock_irqsave(&input->slock, flags); 1392 vb = input->vb; 1393 input->vb = NULL; 1394 spin_unlock_irqrestore(&input->slock, flags); 1395 1396 v4l2_buf = to_vb2_v4l2_buffer(&vb->vb.vb2_buf); 1397 1398 if (!vb) { /* Gone because of disabling */ 1399 dev_dbg(&dev->pci->dev, "vb is empty, dropping frame\n"); 1400 return; 1401 } 1402 1403 /* 1404 * Check for space. 1405 * Mind the overhead of startcode emulation prevention. 1406 */ 1407 if (input->buf_cur_space_left < frame_len * 5 / 4) { 1408 dev_err_once(&dev->pci->dev, 1409 "Left space in vb2 buffer, %d bytes, is less than considered safely enough to put frame of length %d. Dropping this frame.\n", 1410 input->buf_cur_space_left, frame_len); 1411 return; 1412 } 1413 1414 for (i = 0; i < 8 - input->tail_nb_bits; i++) 1415 vlc_mask |= 1 << i; 1416 tail_mask = (~vlc_mask) & 0xff; 1417 1418 dst[0] = (input->tail & tail_mask) | (vlc_first_byte & vlc_mask); 1419 frame_len--; 1420 dst++; 1421 1422 /* H.264 startcode emulation prevention */ 1423 src = frame->vlc.addr + SKIP_VLCBUF_BYTES + 1; 1424 src_end = src + frame_len; 1425 zero_run = 0; 1426 for (; src < src_end; src++) { 1427 if (zero_run < 2) { 1428 if (*src == 0) 1429 ++zero_run; 1430 else 1431 zero_run = 0; 1432 } else { 1433 if ((*src & ~0x03) == 0) 1434 *dst++ = 0x03; 1435 zero_run = *src == 0; 1436 } 1437 *dst++ = *src; 1438 } 1439 1440 vb2_set_plane_payload(&vb->vb.vb2_buf, 0, 1441 dst - (u8 *)vb2_plane_vaddr(&vb->vb.vb2_buf, 0)); 1442 1443 vb->vb.vb2_buf.timestamp = frame->timestamp; 1444 v4l2_buf->field = V4L2_FIELD_INTERLACED; 1445 v4l2_buf->sequence = frame->seqno; 1446 1447 /* Check for motion flags */ 1448 if (frame->gop_seqno /* P-frame */ && 1449 tw5864_is_motion_triggered(frame)) { 1450 struct v4l2_event ev = { 1451 .type = V4L2_EVENT_MOTION_DET, 1452 .u.motion_det = { 1453 .flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ, 1454 .frame_sequence = v4l2_buf->sequence, 1455 }, 1456 }; 1457 1458 v4l2_event_queue(&input->vdev, &ev); 1459 } 1460 1461 vb2_buffer_done(&vb->vb.vb2_buf, VB2_BUF_STATE_DONE); 1462 } 1463 1464 static v4l2_std_id tw5864_get_v4l2_std(enum tw5864_vid_std std) 1465 { 1466 switch (std) { 1467 case STD_NTSC: return V4L2_STD_NTSC_M; 1468 case STD_PAL: return V4L2_STD_PAL_B; 1469 case STD_SECAM: return V4L2_STD_SECAM_B; 1470 case STD_NTSC443: return V4L2_STD_NTSC_443; 1471 case STD_PAL_M: return V4L2_STD_PAL_M; 1472 case STD_PAL_CN: return V4L2_STD_PAL_Nc; 1473 case STD_PAL_60: return V4L2_STD_PAL_60; 1474 case STD_INVALID: return V4L2_STD_UNKNOWN; 1475 } 1476 return 0; 1477 } 1478 1479 static enum tw5864_vid_std tw5864_from_v4l2_std(v4l2_std_id v4l2_std) 1480 { 1481 if (v4l2_std & V4L2_STD_NTSC_M) 1482 return STD_NTSC; 1483 if (v4l2_std & V4L2_STD_PAL_B) 1484 return STD_PAL; 1485 if (v4l2_std & V4L2_STD_SECAM_B) 1486 return STD_SECAM; 1487 if (v4l2_std & V4L2_STD_NTSC_443) 1488 return STD_NTSC443; 1489 if (v4l2_std & V4L2_STD_PAL_M) 1490 return STD_PAL_M; 1491 if (v4l2_std & V4L2_STD_PAL_Nc) 1492 return STD_PAL_CN; 1493 if (v4l2_std & V4L2_STD_PAL_60) 1494 return STD_PAL_60; 1495 1496 return STD_INVALID; 1497 } 1498 1499 static void tw5864_encoder_tables_upload(struct tw5864_dev *dev) 1500 { 1501 int i; 1502 1503 tw_writel(TW5864_VLC_RD, 0x1); 1504 for (i = 0; i < VLC_LOOKUP_TABLE_LEN; i++) { 1505 tw_writel((TW5864_VLC_STREAM_MEM_START + i * 4), 1506 encoder_vlc_lookup_table[i]); 1507 } 1508 tw_writel(TW5864_VLC_RD, 0x0); 1509 1510 for (i = 0; i < QUANTIZATION_TABLE_LEN; i++) { 1511 tw_writel((TW5864_QUAN_TAB + i * 4), 1512 forward_quantization_table[i]); 1513 } 1514 1515 for (i = 0; i < QUANTIZATION_TABLE_LEN; i++) { 1516 tw_writel((TW5864_QUAN_TAB + i * 4), 1517 inverse_quantization_table[i]); 1518 } 1519 } 1520