1 /* 2 * UPEK TouchStrip Sensor-Only driver for libfprint 3 * Copyright (C) 2008 Daniel Drake <dsd@gentoo.org> 4 * 5 * TCS4C (USB ID 147e:1000) support: 6 * Copyright (C) 2010 Hugo Grostabussiat <dw23.devel@gmail.com> 7 * 8 * TCRD5B (USB ID 147e:1001) support: 9 * Copyright (C) 2014 Vasily Khoruzhick <anarsoul@gmail.com> 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 24 */ 25 26 #define IMG_WIDTH_2016 288 27 #define IMG_WIDTH_1000 288 28 #define IMG_WIDTH_1001 216 29 30 struct sonly_regwrite { 31 uint8_t reg; 32 uint8_t value; 33 }; 34 35 /***** AWAIT FINGER *****/ 36 37 static const struct sonly_regwrite awfsm_2016_writev_1[] = { 38 { 0x0a, 0x00 }, { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x3b }, 39 { 0x00, 0x67 }, { 0x00, 0x67 }, 40 }; 41 42 static const struct sonly_regwrite awfsm_1000_writev_1[] = { 43 /* Initialize sensor settings */ 44 { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x37 }, { 0x00, 0x5f }, 45 { 0x01, 0x6e }, { 0x01, 0xee }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, 46 { 0x0e, 0x0e }, { 0x0f, 0x0d }, 47 48 { 0x13, 0x05 }, { 0x13, 0x45 }, 49 50 /* Initialize finger detection registers (not enabling yet) */ 51 { 0x30, 0xe0 }, { 0x15, 0x26 }, 52 53 { 0x12, 0x01 }, { 0x20, 0x01 }, { 0x07, 0x10 }, 54 { 0x10, 0x00 }, { 0x11, 0xbf }, 55 }; 56 57 static const struct sonly_regwrite awfsm_2016_writev_2[] = { 58 { 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e }, 59 { 0x0f, 0x0d }, { 0x0b, 0x00 }, 60 }; 61 62 static const struct sonly_regwrite awfsm_1000_writev_2[] = { 63 /* Enable finger detection */ 64 { 0x30, 0xe1 }, { 0x15, 0x06 }, { 0x15, 0x86 }, 65 }; 66 67 static const struct sonly_regwrite awfsm_2016_writev_3[] = { 68 { 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 }, 69 { 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 }, 70 }; 71 72 static const struct sonly_regwrite awfsm_2016_writev_4[] = { 73 { 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf }, 74 { 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 },\ 75 { 0x05, 0x00 }, { 0x0b, 0x00 }, 76 77 /* enter finger detection mode */ 78 { 0x15, 0x20 }, { 0x30, 0xe1 }, { 0x15, 0x24 }, { 0x15, 0x04 }, 79 { 0x15, 0x84 }, 80 }; 81 82 /***** CAPTURE MODE *****/ 83 84 static const struct sonly_regwrite capsm_2016_writev[] = { 85 /* enter capture mode */ 86 { 0x09, 0x28 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, { 0x04, 0x00 }, 87 { 0x05, 0x00 }, 88 }; 89 90 static const struct sonly_regwrite capsm_1000_writev[] = { 91 { 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */ 92 }; 93 94 static const struct sonly_regwrite capsm_1001_writev_1[] = { 95 { 0x1a, 0x02 }, 96 { 0x4a, 0x9d }, 97 { 0x4e, 0x05 }, 98 }; 99 100 101 static const struct sonly_regwrite capsm_1001_writev_2[] = { 102 { 0x4d, 0xc0 }, { 0x4e, 0x09 }, 103 }; 104 105 static const struct sonly_regwrite capsm_1001_writev_3[] = { 106 { 0x4a, 0x9c }, 107 { 0x1a, 0x00 }, 108 { 0x0b, 0x00 }, 109 { 0x04, 0x00 }, 110 { 0x05, 0x00 }, 111 { 0x1a, 0x02 }, 112 { 0x4a, 0x9d }, 113 { 0x4d, 0x40 }, { 0x4e, 0x09 }, 114 }; 115 116 static const struct sonly_regwrite capsm_1001_writev_4[] = { 117 { 0x4a, 0x9c }, 118 { 0x1a, 0x00 }, 119 { 0x1a, 0x02 }, 120 { 0x4a, 0x9d }, 121 { 0x4e, 0x08 }, 122 }; 123 124 125 static const struct sonly_regwrite capsm_1001_writev_5[] = { 126 { 0x4a, 0x9c }, 127 { 0x1a, 0x00 }, 128 { 0x1a, 0x02 }, 129 { 0x00, 0x5f }, { 0x01, 0xee }, 130 { 0x03, 0x2c }, 131 { 0x07, 0x00 }, { 0x08, 0x00 }, { 0x09, 0x29 }, { 0x0a, 0x00 }, { 0x0b, 0x00 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e }, 132 { 0x0f, 0x0d }, { 0x10, 0x00 }, { 0x11, 0x8f }, { 0x12, 0x01 }, { 0x13, 0x45 }, 133 { 0x15, 0x26 }, 134 { 0x1e, 0x02 }, 135 { 0x20, 0x01 }, 136 { 0x25, 0x8f }, 137 { 0x27, 0x23 }, 138 { 0x30, 0xe0 }, 139 { 0x07, 0x10 }, 140 { 0x09, 0x21 }, 141 { 0x13, 0x75 }, 142 { 0x0b, 0x80 }, 143 }; 144 145 /***** DEINITIALIZATION *****/ 146 147 static const struct sonly_regwrite deinitsm_2016_writev[] = { 148 /* reset + enter low power mode */ 149 { 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 }, 150 }; 151 152 static const struct sonly_regwrite deinitsm_1000_writev[] = { 153 { 0x15, 0x26 }, { 0x30, 0xe0 }, /* Disable finger detection */ 154 155 { 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */ 156 }; 157 158 static const struct sonly_regwrite deinitsm_1001_writev[] = { 159 { 0x0b, 0x00 }, 160 { 0x13, 0x45 }, 161 { 0x09, 0x29 }, 162 { 0x1a, 0x00 }, 163 }; 164 165 /***** INITIALIZATION *****/ 166 167 static const struct sonly_regwrite initsm_2016_writev_1[] = { 168 { 0x49, 0x00 }, 169 170 /* BSAPI writes different values to register 0x3e each time. I initially 171 * thought this was some kind of clever authentication, but just blasting 172 * these sniffed values each time seems to work. */ 173 { 0x3e, 0x83 }, { 0x3e, 0x4f }, { 0x3e, 0x0f }, { 0x3e, 0xbf }, 174 { 0x3e, 0x45 }, { 0x3e, 0x35 }, { 0x3e, 0x1c }, { 0x3e, 0xae }, 175 176 { 0x44, 0x01 }, { 0x43, 0x06 }, { 0x43, 0x05 }, { 0x43, 0x04 }, 177 { 0x44, 0x00 }, { 0x0b, 0x00 }, 178 }; 179 180 static const struct sonly_regwrite initsm_1000_writev_1[] = { 181 { 0x49, 0x00 }, /* Encryption disabled */ 182 183 /* Setting encryption key. Doesn't need to be random since we don't use any 184 * encryption. */ 185 { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, 186 { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, 187 188 { 0x04, 0x00 }, { 0x05, 0x00 }, 189 190 { 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */ 191 }; 192 193 static const struct sonly_regwrite initsm_1001_writev_1[] = { 194 { 0x4a, 0x9d }, 195 { 0x4f, 0x06 }, 196 { 0x4f, 0x05 }, 197 { 0x4f, 0x04 }, 198 { 0x4a, 0x9c }, 199 { 0x3e, 0xa6 }, 200 { 0x3e, 0x01 }, 201 { 0x3e, 0x68 }, 202 { 0x3e, 0xfd }, 203 { 0x3e, 0x72 }, 204 { 0x3e, 0xef }, 205 { 0x3e, 0x5d }, 206 { 0x3e, 0xc5 }, 207 { 0x1a, 0x02 }, 208 { 0x4a, 0x9d }, 209 { 0x4c, 0x1f }, { 0x4d, 0xb8 }, { 0x4e, 0x00 }, 210 }; 211 212 213 static const struct sonly_regwrite initsm_1001_writev_2[] = { 214 { 0x4c, 0x03 }, { 0x4d, 0xb8 }, { 0x4e, 0x00 }, 215 }; 216 217 static const struct sonly_regwrite initsm_1001_writev_3[] = { 218 { 0x4a, 0x9c }, 219 { 0x1a, 0x00 }, 220 { 0x1a, 0x02 }, 221 { 0x4a, 0x9d }, 222 { 0x4c, 0xff }, { 0x4d, 0xc0 }, { 0x4e, 0x00 }, 223 }; 224 225 226 static const struct sonly_regwrite initsm_1001_writev_4[] = { 227 { 0x4a, 0x9c }, 228 { 0x1a, 0x00 }, 229 { 0x09, 0x27 }, 230 { 0x1a, 0x02 }, 231 { 0x49, 0x01 }, 232 { 0x47, 0x02 }, 233 { 0x47, 0x02 }, 234 { 0x47, 0x02 }, 235 { 0x47, 0x02 }, 236 { 0x47, 0x02 }, 237 { 0x47, 0x02 }, 238 { 0x47, 0x02 }, 239 { 0x47, 0x0a }, 240 { 0x47, 0x00 }, 241 { 0x47, 0x04 }, 242 { 0x47, 0x04 }, 243 { 0x47, 0x04 }, 244 { 0x47, 0x04 }, 245 { 0x47, 0x04 }, 246 { 0x47, 0x04 }, 247 { 0x47, 0x04 }, 248 { 0x47, 0x04 }, 249 { 0x47, 0x02 }, 250 { 0x47, 0x02 }, 251 { 0x47, 0x02 }, 252 { 0x47, 0x02 }, 253 { 0x47, 0x02 }, 254 { 0x47, 0x02 }, 255 { 0x47, 0x02 }, 256 { 0x47, 0x0a }, 257 { 0x47, 0x00 }, 258 { 0x47, 0x04 }, 259 { 0x47, 0x04 }, 260 { 0x47, 0x04 }, 261 { 0x47, 0x04 }, 262 { 0x47, 0x04 }, 263 { 0x47, 0x04 }, 264 { 0x47, 0x04 }, 265 { 0x47, 0x04 }, 266 { 0x47, 0x02 }, 267 { 0x47, 0x02 }, 268 { 0x47, 0x02 }, 269 { 0x47, 0x02 }, 270 { 0x47, 0x02 }, 271 { 0x47, 0x02 }, 272 { 0x47, 0x02 }, 273 { 0x47, 0x0a }, 274 { 0x47, 0x00 }, 275 { 0x47, 0x04 }, 276 { 0x47, 0x04 }, 277 { 0x47, 0x04 }, 278 { 0x47, 0x04 }, 279 { 0x47, 0x04 }, 280 { 0x47, 0x04 }, 281 { 0x47, 0x04 }, 282 { 0x47, 0x04 }, 283 { 0x47, 0x02 }, 284 { 0x47, 0x02 }, 285 { 0x47, 0x02 }, 286 { 0x47, 0x02 }, 287 { 0x47, 0x02 }, 288 { 0x47, 0x02 }, 289 { 0x47, 0x02 }, 290 { 0x47, 0x0a }, 291 { 0x47, 0x00 }, 292 { 0x47, 0x04 }, 293 { 0x47, 0x04 }, 294 { 0x47, 0x04 }, 295 { 0x47, 0x04 }, 296 { 0x47, 0x04 }, 297 { 0x47, 0x04 }, 298 { 0x47, 0x04 }, 299 { 0x47, 0x04 }, 300 { 0x49, 0x00 }, 301 { 0x3e, 0x90 }, 302 { 0x3e, 0xbd }, 303 { 0x3e, 0xbf }, 304 { 0x3e, 0x48 }, 305 { 0x3e, 0x2a }, 306 { 0x3e, 0xe3 }, 307 { 0x3e, 0xd2 }, 308 { 0x3e, 0x58 }, 309 { 0x09, 0x2f }, 310 { 0x1a, 0x00 }, 311 { 0x1a, 0x02 }, 312 { 0x4a, 0x9d }, 313 { 0x4d, 0x40 }, { 0x4e, 0x03 }, 314 }; 315 316 static const struct sonly_regwrite initsm_1001_writev_5[] = { 317 { 0x4a, 0x9c }, 318 { 0x1a, 0x00 }, 319 }; 320