1 /* Subdriver for the GL860 chip with the MI2020 sensor 2 * Author Olivier LORIN, from logs by Iceman/Soro2005 + Fret_saw/Hulkie/Tricid 3 * with the help of Kytrix/BUGabundo/Blazercist. 4 * Driver achieved thanks to a webcam gift by Kytrix. 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 * 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 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /* Sensor : MI2020 */ 21 22 #include "gl860.h" 23 24 static u8 dat_wbal1[] = {0x8c, 0xa2, 0x0c}; 25 26 static u8 dat_bright1[] = {0x8c, 0xa2, 0x06}; 27 static u8 dat_bright3[] = {0x8c, 0xa1, 0x02}; 28 static u8 dat_bright4[] = {0x90, 0x00, 0x0f}; 29 static u8 dat_bright5[] = {0x8c, 0xa1, 0x03}; 30 static u8 dat_bright6[] = {0x90, 0x00, 0x05}; 31 32 static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19}; 33 static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b}; 34 static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03}; 35 static u8 dat_hvflip6[] = {0x90, 0x00, 0x06}; 36 37 static struct idxdata tbl_middle_hvflip_low[] = { 38 {0x33, {0x90, 0x00, 0x06}}, 39 {6, {0xff, 0xff, 0xff}}, 40 {0x33, {0x90, 0x00, 0x06}}, 41 {6, {0xff, 0xff, 0xff}}, 42 {0x33, {0x90, 0x00, 0x06}}, 43 {6, {0xff, 0xff, 0xff}}, 44 {0x33, {0x90, 0x00, 0x06}}, 45 {6, {0xff, 0xff, 0xff}}, 46 }; 47 48 static struct idxdata tbl_middle_hvflip_big[] = { 49 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, 50 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, 51 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, 52 {102, {0xff, 0xff, 0xff}}, 53 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, 54 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, 55 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, 56 }; 57 58 static struct idxdata tbl_end_hvflip[] = { 59 {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, 60 {6, {0xff, 0xff, 0xff}}, 61 {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, 62 {6, {0xff, 0xff, 0xff}}, 63 {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, 64 {6, {0xff, 0xff, 0xff}}, 65 {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, 66 }; 67 68 static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 }; 69 70 static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 }; 71 static u8 dat_multi6[] = { 0x90, 0x00, 0x05 }; 72 73 static struct validx tbl_init_at_startup[] = { 74 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, 75 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, 76 {53, 0xffff}, 77 {0x0040, 0x0000}, {0x0063, 0x0006}, 78 }; 79 80 static struct validx tbl_common_0B[] = { 81 {0x0002, 0x0004}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, 82 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, 83 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000}, 84 }; 85 86 static struct idxdata tbl_common_3B[] = { 87 {0x33, {0x86, 0x25, 0x01}}, {0x33, {0x86, 0x25, 0x00}}, 88 {2, {0xff, 0xff, 0xff}}, 89 {0x30, {0x1a, 0x0a, 0xcc}}, {0x32, {0x02, 0x00, 0x08}}, 90 {0x33, {0xf4, 0x03, 0x1d}}, 91 {6, {0xff, 0xff, 0xff}}, /* 12 */ 92 {0x34, {0x1e, 0x8f, 0x09}}, {0x34, {0x1c, 0x01, 0x28}}, 93 {0x34, {0x1e, 0x8f, 0x09}}, 94 {2, {0xff, 0xff, 0xff}}, /* - */ 95 {0x34, {0x1e, 0x8f, 0x09}}, {0x32, {0x14, 0x06, 0xe6}}, 96 {0x33, {0x8c, 0x22, 0x23}}, {0x33, {0x90, 0x00, 0x00}}, 97 {0x33, {0x8c, 0xa2, 0x0f}}, {0x33, {0x90, 0x00, 0x0d}}, 98 {0x33, {0x8c, 0xa2, 0x10}}, {0x33, {0x90, 0x00, 0x0b}}, 99 {0x33, {0x8c, 0xa2, 0x11}}, {0x33, {0x90, 0x00, 0x07}}, 100 {0x33, {0xf4, 0x03, 0x1d}}, {0x35, {0xa2, 0x00, 0xe2}}, 101 {0x33, {0x8c, 0xab, 0x05}}, {0x33, {0x90, 0x00, 0x01}}, 102 {0x32, {0x6e, 0x00, 0x86}}, {0x32, {0x70, 0x0f, 0xaa}}, 103 {0x32, {0x72, 0x0f, 0xe4}}, {0x33, {0x8c, 0xa3, 0x4a}}, 104 {0x33, {0x90, 0x00, 0x5a}}, {0x33, {0x8c, 0xa3, 0x4b}}, 105 {0x33, {0x90, 0x00, 0xa6}}, {0x33, {0x8c, 0xa3, 0x61}}, 106 {0x33, {0x90, 0x00, 0xc8}}, {0x33, {0x8c, 0xa3, 0x62}}, 107 {0x33, {0x90, 0x00, 0xe1}}, {0x34, {0xce, 0x01, 0xa8}}, 108 {0x34, {0xd0, 0x66, 0x33}}, {0x34, {0xd2, 0x31, 0x9a}}, 109 {0x34, {0xd4, 0x94, 0x63}}, {0x34, {0xd6, 0x4b, 0x25}}, 110 {0x34, {0xd8, 0x26, 0x70}}, {0x34, {0xda, 0x72, 0x4c}}, 111 {0x34, {0xdc, 0xff, 0x04}}, {0x34, {0xde, 0x01, 0x5b}}, 112 {0x34, {0xe6, 0x01, 0x13}}, {0x34, {0xee, 0x0b, 0xf0}}, 113 {0x34, {0xf6, 0x0b, 0xa4}}, {0x35, {0x00, 0xf6, 0xe7}}, 114 {0x35, {0x08, 0x0d, 0xfd}}, {0x35, {0x10, 0x25, 0x63}}, 115 {0x35, {0x18, 0x35, 0x6c}}, {0x35, {0x20, 0x42, 0x7e}}, 116 {0x35, {0x28, 0x19, 0x44}}, {0x35, {0x30, 0x39, 0xd4}}, 117 {0x35, {0x38, 0xf5, 0xa8}}, {0x35, {0x4c, 0x07, 0x90}}, 118 {0x35, {0x44, 0x07, 0xb8}}, {0x35, {0x5c, 0x06, 0x88}}, 119 {0x35, {0x54, 0x07, 0xff}}, {0x34, {0xe0, 0x01, 0x52}}, 120 {0x34, {0xe8, 0x00, 0xcc}}, {0x34, {0xf0, 0x0d, 0x83}}, 121 {0x34, {0xf8, 0x0c, 0xb3}}, {0x35, {0x02, 0xfe, 0xba}}, 122 {0x35, {0x0a, 0x04, 0xe0}}, {0x35, {0x12, 0x1c, 0x63}}, 123 {0x35, {0x1a, 0x2b, 0x5a}}, {0x35, {0x22, 0x32, 0x5e}}, 124 {0x35, {0x2a, 0x0d, 0x28}}, {0x35, {0x32, 0x2c, 0x02}}, 125 {0x35, {0x3a, 0xf4, 0xfa}}, {0x35, {0x4e, 0x07, 0xef}}, 126 {0x35, {0x46, 0x07, 0x88}}, {0x35, {0x5e, 0x07, 0xc1}}, 127 {0x35, {0x56, 0x04, 0x64}}, {0x34, {0xe4, 0x01, 0x15}}, 128 {0x34, {0xec, 0x00, 0x82}}, {0x34, {0xf4, 0x0c, 0xce}}, 129 {0x34, {0xfc, 0x0c, 0xba}}, {0x35, {0x06, 0x1f, 0x02}}, 130 {0x35, {0x0e, 0x02, 0xe3}}, {0x35, {0x16, 0x1a, 0x50}}, 131 {0x35, {0x1e, 0x24, 0x39}}, {0x35, {0x26, 0x23, 0x4c}}, 132 {0x35, {0x2e, 0xf9, 0x1b}}, {0x35, {0x36, 0x23, 0x19}}, 133 {0x35, {0x3e, 0x12, 0x08}}, {0x35, {0x52, 0x07, 0x22}}, 134 {0x35, {0x4a, 0x03, 0xd3}}, {0x35, {0x62, 0x06, 0x54}}, 135 {0x35, {0x5a, 0x04, 0x5d}}, {0x34, {0xe2, 0x01, 0x04}}, 136 {0x34, {0xea, 0x00, 0xa0}}, {0x34, {0xf2, 0x0c, 0xbc}}, 137 {0x34, {0xfa, 0x0c, 0x5b}}, {0x35, {0x04, 0x17, 0xf2}}, 138 {0x35, {0x0c, 0x02, 0x08}}, {0x35, {0x14, 0x28, 0x43}}, 139 {0x35, {0x1c, 0x28, 0x62}}, {0x35, {0x24, 0x2b, 0x60}}, 140 {0x35, {0x2c, 0x07, 0x33}}, {0x35, {0x34, 0x1f, 0xb0}}, 141 {0x35, {0x3c, 0xed, 0xcd}}, {0x35, {0x50, 0x00, 0x06}}, 142 {0x35, {0x48, 0x07, 0xff}}, {0x35, {0x60, 0x05, 0x89}}, 143 {0x35, {0x58, 0x07, 0xff}}, {0x35, {0x40, 0x00, 0xa0}}, 144 {0x35, {0x42, 0x00, 0x00}}, {0x32, {0x10, 0x01, 0xfc}}, 145 {0x33, {0x8c, 0xa1, 0x18}}, {0x33, {0x90, 0x00, 0x3c}}, 146 {0x33, {0x78, 0x00, 0x00}}, 147 {2, {0xff, 0xff, 0xff}}, 148 {0x35, {0xb8, 0x1f, 0x20}}, {0x33, {0x8c, 0xa2, 0x06}}, 149 {0x33, {0x90, 0x00, 0x10}}, {0x33, {0x8c, 0xa2, 0x07}}, 150 {0x33, {0x90, 0x00, 0x08}}, {0x33, {0x8c, 0xa2, 0x42}}, 151 {0x33, {0x90, 0x00, 0x0b}}, {0x33, {0x8c, 0xa2, 0x4a}}, 152 {0x33, {0x90, 0x00, 0x8c}}, {0x35, {0xba, 0xfa, 0x08}}, 153 {0x33, {0x8c, 0xa2, 0x02}}, {0x33, {0x90, 0x00, 0x22}}, 154 {0x33, {0x8c, 0xa2, 0x03}}, {0x33, {0x90, 0x00, 0xbb}}, 155 {0x33, {0x8c, 0xa4, 0x04}}, {0x33, {0x90, 0x00, 0x80}}, 156 {0x33, {0x8c, 0xa7, 0x9d}}, {0x33, {0x90, 0x00, 0x00}}, 157 {0x33, {0x8c, 0xa7, 0x9e}}, {0x33, {0x90, 0x00, 0x00}}, 158 {0x33, {0x8c, 0xa2, 0x0c}}, {0x33, {0x90, 0x00, 0x17}}, 159 {0x33, {0x8c, 0xa2, 0x15}}, {0x33, {0x90, 0x00, 0x04}}, 160 {0x33, {0x8c, 0xa2, 0x14}}, {0x33, {0x90, 0x00, 0x20}}, 161 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x00}}, 162 {0x33, {0x8c, 0x27, 0x17}}, {0x33, {0x90, 0x21, 0x11}}, 163 {0x33, {0x8c, 0x27, 0x1b}}, {0x33, {0x90, 0x02, 0x4f}}, 164 {0x33, {0x8c, 0x27, 0x25}}, {0x33, {0x90, 0x06, 0x0f}}, 165 {0x33, {0x8c, 0x27, 0x39}}, {0x33, {0x90, 0x21, 0x11}}, 166 {0x33, {0x8c, 0x27, 0x3d}}, {0x33, {0x90, 0x01, 0x20}}, 167 {0x33, {0x8c, 0x27, 0x47}}, {0x33, {0x90, 0x09, 0x4c}}, 168 {0x33, {0x8c, 0x27, 0x03}}, {0x33, {0x90, 0x02, 0x84}}, 169 {0x33, {0x8c, 0x27, 0x05}}, {0x33, {0x90, 0x01, 0xe2}}, 170 {0x33, {0x8c, 0x27, 0x07}}, {0x33, {0x90, 0x06, 0x40}}, 171 {0x33, {0x8c, 0x27, 0x09}}, {0x33, {0x90, 0x04, 0xb0}}, 172 {0x33, {0x8c, 0x27, 0x0d}}, {0x33, {0x90, 0x00, 0x00}}, 173 {0x33, {0x8c, 0x27, 0x0f}}, {0x33, {0x90, 0x00, 0x00}}, 174 {0x33, {0x8c, 0x27, 0x11}}, {0x33, {0x90, 0x04, 0xbd}}, 175 {0x33, {0x8c, 0x27, 0x13}}, {0x33, {0x90, 0x06, 0x4d}}, 176 {0x33, {0x8c, 0x27, 0x15}}, {0x33, {0x90, 0x00, 0x00}}, 177 {0x33, {0x8c, 0x27, 0x17}}, {0x33, {0x90, 0x21, 0x11}}, 178 {0x33, {0x8c, 0x27, 0x19}}, {0x33, {0x90, 0x04, 0x6c}}, 179 {0x33, {0x8c, 0x27, 0x1b}}, {0x33, {0x90, 0x02, 0x4f}}, 180 {0x33, {0x8c, 0x27, 0x1d}}, {0x33, {0x90, 0x01, 0x02}}, 181 {0x33, {0x8c, 0x27, 0x1f}}, {0x33, {0x90, 0x02, 0x79}}, 182 {0x33, {0x8c, 0x27, 0x21}}, {0x33, {0x90, 0x01, 0x55}}, 183 {0x33, {0x8c, 0x27, 0x23}}, {0x33, {0x90, 0x02, 0x85}}, 184 {0x33, {0x8c, 0x27, 0x25}}, {0x33, {0x90, 0x06, 0x0f}}, 185 {0x33, {0x8c, 0x27, 0x27}}, {0x33, {0x90, 0x20, 0x20}}, 186 {0x33, {0x8c, 0x27, 0x29}}, {0x33, {0x90, 0x20, 0x20}}, 187 {0x33, {0x8c, 0x27, 0x2b}}, {0x33, {0x90, 0x10, 0x20}}, 188 {0x33, {0x8c, 0x27, 0x2d}}, {0x33, {0x90, 0x20, 0x07}}, 189 {0x33, {0x8c, 0x27, 0x2f}}, {0x33, {0x90, 0x00, 0x04}}, 190 {0x33, {0x8c, 0x27, 0x31}}, {0x33, {0x90, 0x00, 0x04}}, 191 {0x33, {0x8c, 0x27, 0x33}}, {0x33, {0x90, 0x04, 0xbb}}, 192 {0x33, {0x8c, 0x27, 0x35}}, {0x33, {0x90, 0x06, 0x4b}}, 193 {0x33, {0x8c, 0x27, 0x37}}, {0x33, {0x90, 0x00, 0x00}}, 194 {0x33, {0x8c, 0x27, 0x39}}, {0x33, {0x90, 0x21, 0x11}}, 195 {0x33, {0x8c, 0x27, 0x3b}}, {0x33, {0x90, 0x00, 0x24}}, 196 {0x33, {0x8c, 0x27, 0x3d}}, {0x33, {0x90, 0x01, 0x20}}, 197 {0x33, {0x8c, 0x27, 0x41}}, {0x33, {0x90, 0x01, 0x69}}, 198 {0x33, {0x8c, 0x27, 0x45}}, {0x33, {0x90, 0x04, 0xed}}, 199 {0x33, {0x8c, 0x27, 0x47}}, {0x33, {0x90, 0x09, 0x4c}}, 200 {0x33, {0x8c, 0x27, 0x51}}, {0x33, {0x90, 0x00, 0x00}}, 201 {0x33, {0x8c, 0x27, 0x53}}, {0x33, {0x90, 0x03, 0x20}}, 202 {0x33, {0x8c, 0x27, 0x55}}, {0x33, {0x90, 0x00, 0x00}}, 203 {0x33, {0x8c, 0x27, 0x57}}, {0x33, {0x90, 0x02, 0x58}}, 204 {0x33, {0x8c, 0x27, 0x5f}}, {0x33, {0x90, 0x00, 0x00}}, 205 {0x33, {0x8c, 0x27, 0x61}}, {0x33, {0x90, 0x06, 0x40}}, 206 {0x33, {0x8c, 0x27, 0x63}}, {0x33, {0x90, 0x00, 0x00}}, 207 {0x33, {0x8c, 0x27, 0x65}}, {0x33, {0x90, 0x04, 0xb0}}, 208 {0x33, {0x8c, 0x22, 0x2e}}, {0x33, {0x90, 0x00, 0xa1}}, 209 {0x33, {0x8c, 0xa4, 0x08}}, {0x33, {0x90, 0x00, 0x1f}}, 210 {0x33, {0x8c, 0xa4, 0x09}}, {0x33, {0x90, 0x00, 0x21}}, 211 {0x33, {0x8c, 0xa4, 0x0a}}, {0x33, {0x90, 0x00, 0x25}}, 212 {0x33, {0x8c, 0xa4, 0x0b}}, {0x33, {0x90, 0x00, 0x27}}, 213 {0x33, {0x8c, 0x24, 0x11}}, {0x33, {0x90, 0x00, 0xa1}}, 214 {0x33, {0x8c, 0x24, 0x13}}, {0x33, {0x90, 0x00, 0xc1}}, 215 {0x33, {0x8c, 0x24, 0x15}}, {0x33, {0x90, 0x00, 0x6a}}, 216 {0x33, {0x8c, 0x24, 0x17}}, {0x33, {0x90, 0x00, 0x80}}, 217 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, 218 {2, {0xff, 0xff, 0xff}}, 219 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 220 {3, {0xff, 0xff, 0xff}}, 221 }; 222 223 static struct idxdata tbl_init_post_alt_low1[] = { 224 {0x33, {0x8c, 0x27, 0x15}}, {0x33, {0x90, 0x00, 0x25}}, 225 {0x33, {0x8c, 0x22, 0x2e}}, {0x33, {0x90, 0x00, 0x81}}, 226 {0x33, {0x8c, 0xa4, 0x08}}, {0x33, {0x90, 0x00, 0x17}}, 227 {0x33, {0x8c, 0xa4, 0x09}}, {0x33, {0x90, 0x00, 0x1a}}, 228 {0x33, {0x8c, 0xa4, 0x0a}}, {0x33, {0x90, 0x00, 0x1d}}, 229 {0x33, {0x8c, 0xa4, 0x0b}}, {0x33, {0x90, 0x00, 0x20}}, 230 {0x33, {0x8c, 0x24, 0x11}}, {0x33, {0x90, 0x00, 0x81}}, 231 {0x33, {0x8c, 0x24, 0x13}}, {0x33, {0x90, 0x00, 0x9b}}, 232 }; 233 234 static struct idxdata tbl_init_post_alt_low2[] = { 235 {0x33, {0x8c, 0x27, 0x03}}, {0x33, {0x90, 0x03, 0x24}}, 236 {0x33, {0x8c, 0x27, 0x05}}, {0x33, {0x90, 0x02, 0x58}}, 237 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, 238 {2, {0xff, 0xff, 0xff}}, 239 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 240 {2, {0xff, 0xff, 0xff}}, 241 }; 242 243 static struct idxdata tbl_init_post_alt_low3[] = { 244 {0x34, {0x1e, 0x8f, 0x09}}, {0x34, {0x1c, 0x01, 0x28}}, 245 {0x34, {0x1e, 0x8f, 0x09}}, 246 {2, {0xff, 0xff, 0xff}}, 247 {0x34, {0x1e, 0x8f, 0x09}}, {0x32, {0x14, 0x06, 0xe6}}, 248 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, 249 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, 250 {0x33, {0x2e, 0x01, 0x00}}, {0x34, {0x04, 0x00, 0x2a}}, 251 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, 252 {0x33, {0x8c, 0x27, 0x95}}, {0x33, {0x90, 0x01, 0x00}}, 253 {2, {0xff, 0xff, 0xff}}, 254 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, 255 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, 256 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, 257 {2, {0xff, 0xff, 0xff}}, 258 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, 259 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, 260 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, 261 {2, {0xff, 0xff, 0xff}}, 262 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, 263 {2, {0xff, 0xff, 0xff}}, 264 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 265 {2, {0xff, 0xff, 0xff}}, 266 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, 267 {2, {0xff, 0xff, 0xff}}, 268 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 269 }; 270 271 static struct idxdata tbl_init_post_alt_big[] = { 272 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, 273 {2, {0xff, 0xff, 0xff}}, 274 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 275 {2, {0xff, 0xff, 0xff}}, 276 {0x34, {0x1e, 0x8f, 0x09}}, {0x34, {0x1c, 0x01, 0x28}}, 277 {0x34, {0x1e, 0x8f, 0x09}}, 278 {2, {0xff, 0xff, 0xff}}, 279 {0x34, {0x1e, 0x8f, 0x09}}, {0x32, {0x14, 0x06, 0xe6}}, 280 {0x33, {0x8c, 0xa1, 0x03}}, 281 {0x33, {0x90, 0x00, 0x05}}, 282 {2, {0xff, 0xff, 0xff}}, 283 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 284 {2, {0xff, 0xff, 0xff}}, 285 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, 286 {2, {0xff, 0xff, 0xff}}, 287 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, 288 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, 289 {0x33, {0x8c, 0xa1, 0x30}}, {0x33, {0x90, 0x00, 0x03}}, 290 {0x33, {0x8c, 0xa1, 0x31}}, {0x33, {0x90, 0x00, 0x02}}, 291 {0x33, {0x8c, 0xa1, 0x32}}, {0x33, {0x90, 0x00, 0x03}}, 292 {0x33, {0x8c, 0xa1, 0x34}}, {0x33, {0x90, 0x00, 0x03}}, 293 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, 294 {0x33, {0x2e, 0x01, 0x00}}, {0x34, {0x04, 0x00, 0x2a}}, 295 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, 296 {0x33, {0x8c, 0x27, 0x97}}, {0x33, {0x90, 0x01, 0x00}}, 297 {51, {0xff, 0xff, 0xff}}, 298 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, 299 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, 300 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, 301 {51, {0xff, 0xff, 0xff}}, 302 {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, 303 {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, 304 {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, 305 {51, {0xff, 0xff, 0xff}}, 306 }; 307 308 static struct idxdata tbl_init_post_alt_3B[] = { 309 {0x32, {0x10, 0x01, 0xf8}}, {0x34, {0xce, 0x01, 0xa8}}, 310 {0x34, {0xd0, 0x66, 0x33}}, {0x34, {0xd2, 0x31, 0x9a}}, 311 {0x34, {0xd4, 0x94, 0x63}}, {0x34, {0xd6, 0x4b, 0x25}}, 312 {0x34, {0xd8, 0x26, 0x70}}, {0x34, {0xda, 0x72, 0x4c}}, 313 {0x34, {0xdc, 0xff, 0x04}}, {0x34, {0xde, 0x01, 0x5b}}, 314 {0x34, {0xe6, 0x01, 0x13}}, {0x34, {0xee, 0x0b, 0xf0}}, 315 {0x34, {0xf6, 0x0b, 0xa4}}, {0x35, {0x00, 0xf6, 0xe7}}, 316 {0x35, {0x08, 0x0d, 0xfd}}, {0x35, {0x10, 0x25, 0x63}}, 317 {0x35, {0x18, 0x35, 0x6c}}, {0x35, {0x20, 0x42, 0x7e}}, 318 {0x35, {0x28, 0x19, 0x44}}, {0x35, {0x30, 0x39, 0xd4}}, 319 {0x35, {0x38, 0xf5, 0xa8}}, {0x35, {0x4c, 0x07, 0x90}}, 320 {0x35, {0x44, 0x07, 0xb8}}, {0x35, {0x5c, 0x06, 0x88}}, 321 {0x35, {0x54, 0x07, 0xff}}, {0x34, {0xe0, 0x01, 0x52}}, 322 {0x34, {0xe8, 0x00, 0xcc}}, {0x34, {0xf0, 0x0d, 0x83}}, 323 {0x34, {0xf8, 0x0c, 0xb3}}, {0x35, {0x02, 0xfe, 0xba}}, 324 {0x35, {0x0a, 0x04, 0xe0}}, {0x35, {0x12, 0x1c, 0x63}}, 325 {0x35, {0x1a, 0x2b, 0x5a}}, {0x35, {0x22, 0x32, 0x5e}}, 326 {0x35, {0x2a, 0x0d, 0x28}}, {0x35, {0x32, 0x2c, 0x02}}, 327 {0x35, {0x3a, 0xf4, 0xfa}}, {0x35, {0x4e, 0x07, 0xef}}, 328 {0x35, {0x46, 0x07, 0x88}}, {0x35, {0x5e, 0x07, 0xc1}}, 329 {0x35, {0x56, 0x04, 0x64}}, {0x34, {0xe4, 0x01, 0x15}}, 330 {0x34, {0xec, 0x00, 0x82}}, {0x34, {0xf4, 0x0c, 0xce}}, 331 {0x34, {0xfc, 0x0c, 0xba}}, {0x35, {0x06, 0x1f, 0x02}}, 332 {0x35, {0x0e, 0x02, 0xe3}}, {0x35, {0x16, 0x1a, 0x50}}, 333 {0x35, {0x1e, 0x24, 0x39}}, {0x35, {0x26, 0x23, 0x4c}}, 334 {0x35, {0x2e, 0xf9, 0x1b}}, {0x35, {0x36, 0x23, 0x19}}, 335 {0x35, {0x3e, 0x12, 0x08}}, {0x35, {0x52, 0x07, 0x22}}, 336 {0x35, {0x4a, 0x03, 0xd3}}, {0x35, {0x62, 0x06, 0x54}}, 337 {0x35, {0x5a, 0x04, 0x5d}}, {0x34, {0xe2, 0x01, 0x04}}, 338 {0x34, {0xea, 0x00, 0xa0}}, {0x34, {0xf2, 0x0c, 0xbc}}, 339 {0x34, {0xfa, 0x0c, 0x5b}}, {0x35, {0x04, 0x17, 0xf2}}, 340 {0x35, {0x0c, 0x02, 0x08}}, {0x35, {0x14, 0x28, 0x43}}, 341 {0x35, {0x1c, 0x28, 0x62}}, {0x35, {0x24, 0x2b, 0x60}}, 342 {0x35, {0x2c, 0x07, 0x33}}, {0x35, {0x34, 0x1f, 0xb0}}, 343 {0x35, {0x3c, 0xed, 0xcd}}, {0x35, {0x50, 0x00, 0x06}}, 344 {0x35, {0x48, 0x07, 0xff}}, {0x35, {0x60, 0x05, 0x89}}, 345 {0x35, {0x58, 0x07, 0xff}}, {0x35, {0x40, 0x00, 0xa0}}, 346 {0x35, {0x42, 0x00, 0x00}}, {0x32, {0x10, 0x01, 0xfc}}, 347 {0x33, {0x8c, 0xa1, 0x18}}, {0x33, {0x90, 0x00, 0x3c}}, 348 }; 349 350 static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81"; 351 static u8 *dat_800 = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21"; 352 static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01"; 353 static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41"; 354 355 static int mi2020_init_at_startup(struct gspca_dev *gspca_dev); 356 static int mi2020_configure_alt(struct gspca_dev *gspca_dev); 357 static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev); 358 static int mi2020_init_post_alt(struct gspca_dev *gspca_dev); 359 static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev); 360 static int mi2020_camera_settings(struct gspca_dev *gspca_dev); 361 /*==========================================================================*/ 362 363 void mi2020_init_settings(struct gspca_dev *gspca_dev) 364 { 365 struct sd *sd = (struct sd *) gspca_dev; 366 367 sd->vcur.backlight = 0; 368 sd->vcur.brightness = 70; 369 sd->vcur.sharpness = 20; 370 sd->vcur.contrast = 0; 371 sd->vcur.gamma = 0; 372 sd->vcur.hue = 0; 373 sd->vcur.saturation = 60; 374 sd->vcur.whitebal = 0; /* 50, not done by hardware */ 375 sd->vcur.mirror = 0; 376 sd->vcur.flip = 0; 377 sd->vcur.AC50Hz = 1; 378 379 sd->vmax.backlight = 64; 380 sd->vmax.brightness = 128; 381 sd->vmax.sharpness = 40; 382 sd->vmax.contrast = 3; 383 sd->vmax.gamma = 2; 384 sd->vmax.hue = 0 + 1; /* 200, not done by hardware */ 385 sd->vmax.saturation = 0; /* 100, not done by hardware */ 386 sd->vmax.whitebal = 2; /* 100, not done by hardware */ 387 sd->vmax.mirror = 1; 388 sd->vmax.flip = 1; 389 sd->vmax.AC50Hz = 1; 390 391 sd->dev_camera_settings = mi2020_camera_settings; 392 sd->dev_init_at_startup = mi2020_init_at_startup; 393 sd->dev_configure_alt = mi2020_configure_alt; 394 sd->dev_init_pre_alt = mi2020_init_pre_alt; 395 sd->dev_post_unset_alt = mi2020_post_unset_alt; 396 } 397 398 /*==========================================================================*/ 399 400 static void common(struct gspca_dev *gspca_dev) 401 { 402 fetch_validx(gspca_dev, tbl_common_0B, ARRAY_SIZE(tbl_common_0B)); 403 fetch_idxdata(gspca_dev, tbl_common_3B, ARRAY_SIZE(tbl_common_3B)); 404 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); 405 } 406 407 static int mi2020_init_at_startup(struct gspca_dev *gspca_dev) 408 { 409 u8 c; 410 411 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c); 412 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c); 413 414 fetch_validx(gspca_dev, tbl_init_at_startup, 415 ARRAY_SIZE(tbl_init_at_startup)); 416 417 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL); 418 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &c); 419 420 common(gspca_dev); 421 422 msleep(61); 423 /* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ 424 /* msleep(36); */ 425 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL); 426 427 return 0; 428 } 429 430 static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev) 431 { 432 struct sd *sd = (struct sd *) gspca_dev; 433 434 sd->mirrorMask = 0; 435 sd->vold.hue = -1; 436 437 /* These controls need to be reset */ 438 sd->vold.brightness = -1; 439 sd->vold.sharpness = -1; 440 441 /* If not different from default, they do not need to be set */ 442 sd->vold.contrast = 0; 443 sd->vold.gamma = 0; 444 sd->vold.backlight = 0; 445 446 mi2020_init_post_alt(gspca_dev); 447 448 return 0; 449 } 450 451 static int mi2020_init_post_alt(struct gspca_dev *gspca_dev) 452 { 453 struct sd *sd = (struct sd *) gspca_dev; 454 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 455 456 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0); 457 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0); 458 s32 freq = (sd->vcur.AC50Hz > 0); 459 s32 wbal = sd->vcur.whitebal; 460 461 u8 dat_freq2[] = {0x90, 0x00, 0x80}; 462 u8 dat_multi1[] = {0x8c, 0xa7, 0x00}; 463 u8 dat_multi2[] = {0x90, 0x00, 0x00}; 464 u8 dat_multi3[] = {0x8c, 0xa7, 0x00}; 465 u8 dat_multi4[] = {0x90, 0x00, 0x00}; 466 u8 dat_hvflip2[] = {0x90, 0x04, 0x6c}; 467 u8 dat_hvflip4[] = {0x90, 0x00, 0x24}; 468 u8 dat_wbal2[] = {0x90, 0x00, 0x00}; 469 u8 c; 470 471 sd->nbIm = -1; 472 473 dat_freq2[2] = freq ? 0xc0 : 0x80; 474 dat_multi1[2] = 0x9d; 475 dat_multi3[2] = dat_multi1[2] + 1; 476 if (wbal == 0) { 477 dat_multi4[2] = dat_multi2[2] = 0; 478 dat_wbal2[2] = 0x17; 479 } else if (wbal == 1) { 480 dat_multi4[2] = dat_multi2[2] = 0; 481 dat_wbal2[2] = 0x35; 482 } else if (wbal == 2) { 483 dat_multi4[2] = dat_multi2[2] = 0x20; 484 dat_wbal2[2] = 0x17; 485 } 486 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror); 487 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror); 488 489 msleep(200); 490 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); 491 msleep(2); 492 493 common(gspca_dev); 494 495 msleep(142); 496 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL); 497 ctrl_out(gspca_dev, 0x40, 1, 0x0003, 0x00c1, 0, NULL); 498 ctrl_out(gspca_dev, 0x40, 1, 0x0042, 0x00c2, 0, NULL); 499 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL); 500 501 switch (reso) { 502 case IMAGE_640: 503 case IMAGE_800: 504 if (reso != IMAGE_800) 505 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 506 12, dat_640); 507 else 508 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 509 12, dat_800); 510 511 fetch_idxdata(gspca_dev, tbl_init_post_alt_low1, 512 ARRAY_SIZE(tbl_init_post_alt_low1)); 513 514 if (reso == IMAGE_800) 515 fetch_idxdata(gspca_dev, tbl_init_post_alt_low2, 516 ARRAY_SIZE(tbl_init_post_alt_low2)); 517 518 fetch_idxdata(gspca_dev, tbl_init_post_alt_low3, 519 ARRAY_SIZE(tbl_init_post_alt_low3)); 520 521 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL); 522 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL); 523 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL); 524 msleep(120); 525 break; 526 527 case IMAGE_1280: 528 case IMAGE_1600: 529 if (reso == IMAGE_1280) { 530 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 531 12, dat_1280); 532 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 533 3, "\x8c\x27\x07"); 534 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 535 3, "\x90\x05\x04"); 536 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 537 3, "\x8c\x27\x09"); 538 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 539 3, "\x90\x04\x02"); 540 } else { 541 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 542 12, dat_1600); 543 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 544 3, "\x8c\x27\x07"); 545 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 546 3, "\x90\x06\x40"); 547 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 548 3, "\x8c\x27\x09"); 549 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 550 3, "\x90\x04\xb0"); 551 } 552 553 fetch_idxdata(gspca_dev, tbl_init_post_alt_big, 554 ARRAY_SIZE(tbl_init_post_alt_big)); 555 556 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL); 557 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL); 558 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL); 559 msleep(1850); 560 } 561 562 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL); 563 msleep(40); 564 565 /* AC power frequency */ 566 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1); 567 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2); 568 msleep(33); 569 /* light source */ 570 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); 571 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); 572 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); 573 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); 574 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1); 575 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2); 576 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); 577 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); 578 msleep(7); 579 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c); 580 581 fetch_idxdata(gspca_dev, tbl_init_post_alt_3B, 582 ARRAY_SIZE(tbl_init_post_alt_3B)); 583 584 /* hvflip */ 585 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); 586 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2); 587 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3); 588 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4); 589 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5); 590 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6); 591 msleep(250); 592 593 if (reso == IMAGE_640 || reso == IMAGE_800) 594 fetch_idxdata(gspca_dev, tbl_middle_hvflip_low, 595 ARRAY_SIZE(tbl_middle_hvflip_low)); 596 else 597 fetch_idxdata(gspca_dev, tbl_middle_hvflip_big, 598 ARRAY_SIZE(tbl_middle_hvflip_big)); 599 600 fetch_idxdata(gspca_dev, tbl_end_hvflip, 601 ARRAY_SIZE(tbl_end_hvflip)); 602 603 sd->nbIm = 0; 604 605 sd->vold.mirror = mirror; 606 sd->vold.flip = flip; 607 sd->vold.AC50Hz = freq; 608 sd->vold.whitebal = wbal; 609 610 mi2020_camera_settings(gspca_dev); 611 612 return 0; 613 } 614 615 static int mi2020_configure_alt(struct gspca_dev *gspca_dev) 616 { 617 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 618 619 switch (reso) { 620 case IMAGE_640: 621 gspca_dev->alt = 3 + 1; 622 break; 623 624 case IMAGE_800: 625 case IMAGE_1280: 626 case IMAGE_1600: 627 gspca_dev->alt = 1 + 1; 628 break; 629 } 630 return 0; 631 } 632 633 static int mi2020_camera_settings(struct gspca_dev *gspca_dev) 634 { 635 struct sd *sd = (struct sd *) gspca_dev; 636 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 637 638 s32 backlight = sd->vcur.backlight; 639 s32 bright = sd->vcur.brightness; 640 s32 sharp = sd->vcur.sharpness; 641 s32 cntr = sd->vcur.contrast; 642 s32 gam = sd->vcur.gamma; 643 s32 hue = (sd->vcur.hue > 0); 644 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0); 645 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0); 646 s32 freq = (sd->vcur.AC50Hz > 0); 647 s32 wbal = sd->vcur.whitebal; 648 649 u8 dat_sharp[] = {0x6c, 0x00, 0x08}; 650 u8 dat_bright2[] = {0x90, 0x00, 0x00}; 651 u8 dat_freq2[] = {0x90, 0x00, 0x80}; 652 u8 dat_multi1[] = {0x8c, 0xa7, 0x00}; 653 u8 dat_multi2[] = {0x90, 0x00, 0x00}; 654 u8 dat_multi3[] = {0x8c, 0xa7, 0x00}; 655 u8 dat_multi4[] = {0x90, 0x00, 0x00}; 656 u8 dat_hvflip2[] = {0x90, 0x04, 0x6c}; 657 u8 dat_hvflip4[] = {0x90, 0x00, 0x24}; 658 u8 dat_wbal2[] = {0x90, 0x00, 0x00}; 659 660 /* Less than 4 images received -> too early to set the settings */ 661 if (sd->nbIm < 4) { 662 sd->waitSet = 1; 663 return 0; 664 } 665 sd->waitSet = 0; 666 667 if (freq != sd->vold.AC50Hz) { 668 sd->vold.AC50Hz = freq; 669 670 dat_freq2[2] = freq ? 0xc0 : 0x80; 671 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1); 672 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2); 673 msleep(20); 674 } 675 676 if (wbal != sd->vold.whitebal) { 677 sd->vold.whitebal = wbal; 678 if (wbal < 0 || wbal > sd->vmax.whitebal) 679 wbal = 0; 680 681 dat_multi1[2] = 0x9d; 682 dat_multi3[2] = dat_multi1[2] + 1; 683 if (wbal == 0) { 684 dat_multi4[2] = dat_multi2[2] = 0; 685 dat_wbal2[2] = 0x17; 686 } else if (wbal == 1) { 687 dat_multi4[2] = dat_multi2[2] = 0; 688 dat_wbal2[2] = 0x35; 689 } else if (wbal == 2) { 690 dat_multi4[2] = dat_multi2[2] = 0x20; 691 dat_wbal2[2] = 0x17; 692 } 693 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); 694 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); 695 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); 696 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); 697 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1); 698 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2); 699 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); 700 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); 701 } 702 703 if (mirror != sd->vold.mirror || flip != sd->vold.flip) { 704 sd->vold.mirror = mirror; 705 sd->vold.flip = flip; 706 707 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror); 708 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror); 709 710 fetch_idxdata(gspca_dev, tbl_init_post_alt_3B, 711 ARRAY_SIZE(tbl_init_post_alt_3B)); 712 713 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1); 714 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2); 715 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3); 716 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4); 717 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5); 718 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6); 719 msleep(40); 720 721 if (reso == IMAGE_640 || reso == IMAGE_800) 722 fetch_idxdata(gspca_dev, tbl_middle_hvflip_low, 723 ARRAY_SIZE(tbl_middle_hvflip_low)); 724 else 725 fetch_idxdata(gspca_dev, tbl_middle_hvflip_big, 726 ARRAY_SIZE(tbl_middle_hvflip_big)); 727 728 fetch_idxdata(gspca_dev, tbl_end_hvflip, 729 ARRAY_SIZE(tbl_end_hvflip)); 730 } 731 732 if (bright != sd->vold.brightness) { 733 sd->vold.brightness = bright; 734 if (bright < 0 || bright > sd->vmax.brightness) 735 bright = 0; 736 737 dat_bright2[2] = bright; 738 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1); 739 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2); 740 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3); 741 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4); 742 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5); 743 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6); 744 } 745 746 if (cntr != sd->vold.contrast || gam != sd->vold.gamma) { 747 sd->vold.contrast = cntr; 748 if (cntr < 0 || cntr > sd->vmax.contrast) 749 cntr = 0; 750 sd->vold.gamma = gam; 751 if (gam < 0 || gam > sd->vmax.gamma) 752 gam = 0; 753 754 dat_multi1[2] = 0x6d; 755 dat_multi3[2] = dat_multi1[2] + 1; 756 if (cntr == 0) 757 cntr = 4; 758 dat_multi4[2] = dat_multi2[2] = cntr * 0x10 + 2 - gam; 759 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); 760 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); 761 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); 762 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); 763 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); 764 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); 765 } 766 767 if (backlight != sd->vold.backlight) { 768 sd->vold.backlight = backlight; 769 if (backlight < 0 || backlight > sd->vmax.backlight) 770 backlight = 0; 771 772 dat_multi1[2] = 0x9d; 773 dat_multi3[2] = dat_multi1[2] + 1; 774 dat_multi4[2] = dat_multi2[2] = backlight; 775 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1); 776 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2); 777 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3); 778 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4); 779 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5); 780 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6); 781 } 782 783 if (sharp != sd->vold.sharpness) { 784 sd->vold.sharpness = sharp; 785 if (sharp < 0 || sharp > sd->vmax.sharpness) 786 sharp = 0; 787 788 dat_sharp[1] = sharp; 789 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp); 790 } 791 792 if (hue != sd->vold.hue) { 793 sd->swapRB = hue; 794 sd->vold.hue = hue; 795 } 796 797 return 0; 798 } 799 800 static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev) 801 { 802 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); 803 msleep(40); 804 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL); 805 } 806