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