1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <errno.h> 18 #include <float.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <eventnums.h> 23 #include <gpio.h> 24 #include <heap.h> 25 #include <hostIntf.h> 26 #include <isr.h> 27 #include <i2c.h> 28 #include <nanohubPacket.h> 29 #include <sensors.h> 30 #include <seos.h> 31 #include <timer.h> 32 #include <util.h> 33 34 #include <cpu/cpuMath.h> 35 36 #include <plat/exti.h> 37 #include <plat/gpio.h> 38 #include <plat/syscfg.h> 39 40 #define S3708_APP_ID APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 13) 41 #define S3708_APP_VERSION 1 42 43 #define I2C_BUS_ID 0 44 #define I2C_SPEED 400000 45 #define I2C_ADDR 0x20 46 47 #define S3708_REG_PAGE_SELECT 0xFF 48 49 #define S3708_REG_F01_DATA_BASE 0x06 50 #define S3708_INT_STATUS_LPWG 0x04 51 52 #define S3708_REG_DATA_BASE 0x08 53 #define S3708_REG_DATA_4_OFFSET 0x02 54 #define S3708_INT_STATUS_DOUBLE_TAP 0x03 55 56 #define S3708_REG_F01_CTRL_BASE 0x14 57 #define S3708_NORMAL_MODE 0x00 58 #define S3708_SLEEP_MODE 0x01 59 60 #define S3708_REG_CTRL_BASE 0x1b 61 #define S3708_REG_CTRL_20_OFFSET 0x07 62 #define S3708_REPORT_MODE_CONT 0x00 63 #define S3708_REPORT_MODE_LPWG 0x02 64 65 #define MAX_PENDING_I2C_REQUESTS 4 66 #define MAX_I2C_TRANSFER_SIZE 8 67 #define MAX_I2C_RETRY_DELAY 250000000ull // 250 milliseconds 68 #define MAX_I2C_RETRY_COUNT (15000000000ull / MAX_I2C_RETRY_DELAY) // 15 seconds 69 #define HACK_RETRY_SKIP_COUNT 1 70 71 #define DEFAULT_PROX_RATE_HZ SENSOR_HZ(5.0f) 72 #define DEFAULT_PROX_LATENCY 0.0 73 #define PROXIMITY_THRESH_NEAR 5.0f // distance in cm 74 75 #define EVT_SENSOR_PROX sensorGetMyEventType(SENS_TYPE_PROX) 76 77 #define ENABLE_DEBUG 0 78 79 #define VERBOSE_PRINT(fmt, ...) osLog(LOG_VERBOSE, "[DoubleTouch] " fmt, ##__VA_ARGS__) 80 #define INFO_PRINT(fmt, ...) osLog(LOG_INFO, "[DoubleTouch] " fmt, ##__VA_ARGS__) 81 #define ERROR_PRINT(fmt, ...) osLog(LOG_ERROR, "[DoubleTouch] " fmt, ##__VA_ARGS__) 82 #if ENABLE_DEBUG 83 #define DEBUG_PRINT(fmt, ...) osLog(LOG_DEBUG, "[DoubleTouch] " fmt, ##__VA_ARGS__) 84 #else 85 #define DEBUG_PRINT(fmt, ...) ((void)0) 86 #endif 87 88 89 #ifndef TOUCH_PIN 90 #error "TOUCH_PIN is not defined; please define in variant.h" 91 #endif 92 93 #ifndef TOUCH_IRQ 94 #error "TOUCH_IRQ is not defined; please define in variant.h" 95 #endif 96 97 enum SensorEvents 98 { 99 EVT_SENSOR_I2C = EVT_APP_START + 1, 100 EVT_SENSOR_TOUCH_INTERRUPT, 101 EVT_SENSOR_RETRY_TIMER, 102 }; 103 104 enum TaskState 105 { 106 STATE_ENABLE_0, 107 STATE_ENABLE_1, 108 STATE_ENABLE_2, 109 STATE_DISABLE_0, 110 STATE_INT_HANDLE_0, 111 STATE_INT_HANDLE_1, 112 STATE_IDLE, 113 STATE_CANCELLED, 114 }; 115 116 struct I2cTransfer 117 { 118 size_t tx; 119 size_t rx; 120 int err; 121 uint8_t txrxBuf[MAX_I2C_TRANSFER_SIZE]; 122 uint8_t state; 123 bool inUse; 124 }; 125 126 struct TaskStatistics { 127 uint64_t enabledTimestamp; 128 uint64_t proxEnabledTimestamp; 129 uint64_t lastProxFarTimestamp; 130 uint64_t totalEnabledTime; 131 uint64_t totalProxEnabledTime; 132 uint64_t totalProxFarTime; 133 uint32_t totalProxBecomesFar; 134 uint32_t totalProxBecomesNear; 135 }; 136 137 enum ProxState { 138 PROX_STATE_UNKNOWN, 139 PROX_STATE_NEAR, 140 PROX_STATE_FAR 141 }; 142 143 static struct TaskStruct 144 { 145 struct Gpio *pin; 146 struct ChainedIsr isr; 147 struct TaskStatistics stats; 148 struct I2cTransfer transfers[MAX_PENDING_I2C_REQUESTS]; 149 uint32_t id; 150 uint32_t handle; 151 uint32_t retryTimerHandle; 152 uint32_t retryCnt; 153 uint32_t proxHandle; 154 enum ProxState proxState; 155 bool on; 156 bool gestureEnabled; 157 bool isrEnabled; 158 } mTask; 159 160 static inline void enableInterrupt(bool enable) 161 { 162 if (!mTask.isrEnabled && enable) { 163 extiEnableIntGpio(mTask.pin, EXTI_TRIGGER_FALLING); 164 extiChainIsr(TOUCH_IRQ, &mTask.isr); 165 } else if (mTask.isrEnabled && !enable) { 166 extiUnchainIsr(TOUCH_IRQ, &mTask.isr); 167 extiDisableIntGpio(mTask.pin); 168 } 169 mTask.isrEnabled = enable; 170 } 171 172 static bool touchIsr(struct ChainedIsr *localIsr) 173 { 174 struct TaskStruct *data = container_of(localIsr, struct TaskStruct, isr); 175 176 if (!extiIsPendingGpio(data->pin)) { 177 return false; 178 } 179 180 osEnqueuePrivateEvt(EVT_SENSOR_TOUCH_INTERRUPT, NULL, NULL, data->id); 181 182 extiClearPendingGpio(data->pin); 183 184 return true; 185 } 186 187 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err) 188 { 189 struct I2cTransfer *xfer = cookie; 190 191 xfer->tx = tx; 192 xfer->rx = rx; 193 xfer->err = err; 194 195 osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.id); 196 // Do not print error for ENXIO since we expect there to be times where we 197 // cannot talk to the touch controller. 198 if (err == -ENXIO) { 199 DEBUG_PRINT("i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err); 200 } else if (err != 0) { 201 ERROR_PRINT("i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err); 202 } 203 } 204 205 static void retryTimerCallback(uint32_t timerId, void *cookie) 206 { 207 osEnqueuePrivateEvt(EVT_SENSOR_RETRY_TIMER, cookie, NULL, mTask.id); 208 } 209 210 // Allocate a buffer and mark it as in use with the given state, or return NULL 211 // if no buffers available. Must *not* be called from interrupt context. 212 static struct I2cTransfer *allocXfer(uint8_t state) 213 { 214 size_t i; 215 216 for (i = 0; i < ARRAY_SIZE(mTask.transfers); i++) { 217 if (!mTask.transfers[i].inUse) { 218 mTask.transfers[i].inUse = true; 219 mTask.transfers[i].state = state; 220 memset(mTask.transfers[i].txrxBuf, 0x00, sizeof(mTask.transfers[i].txrxBuf)); 221 return &mTask.transfers[i]; 222 } 223 } 224 225 ERROR_PRINT("Ran out of I2C buffers!"); 226 return NULL; 227 } 228 229 // Helper function to initiate the I2C transfer. Returns true is the transaction 230 // was successfully register by I2C driver. Otherwise, returns false. 231 static bool performXfer(struct I2cTransfer *xfer, size_t txBytes, size_t rxBytes) 232 { 233 int ret; 234 235 if ((txBytes > MAX_I2C_TRANSFER_SIZE) || (rxBytes > MAX_I2C_TRANSFER_SIZE)) { 236 ERROR_PRINT("txBytes and rxBytes must be less than %d", MAX_I2C_TRANSFER_SIZE); 237 return false; 238 } 239 240 if (rxBytes) { 241 ret = i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, txBytes, xfer->txrxBuf, rxBytes, i2cCallback, xfer); 242 } else { 243 ret = i2cMasterTx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, txBytes, i2cCallback, xfer); 244 } 245 246 if (ret != 0) { 247 ERROR_PRINT("I2C transfer was not successful (error %d)!", ret); 248 } 249 250 return (ret == 0); 251 } 252 253 // Helper function to write a one byte register. Returns true if we got a 254 // successful return value from i2cMasterTx(). 255 static bool writeRegister(uint8_t reg, uint8_t value, uint8_t state) 256 { 257 struct I2cTransfer *xfer = allocXfer(state); 258 259 if (xfer != NULL) { 260 xfer->txrxBuf[0] = reg; 261 xfer->txrxBuf[1] = value; 262 return performXfer(xfer, 2, 0); 263 } 264 265 return false; 266 } 267 268 static bool setSleepEnable(bool enable, uint8_t state) 269 { 270 return writeRegister(S3708_REG_F01_CTRL_BASE, enable ? S3708_SLEEP_MODE : S3708_NORMAL_MODE, state); 271 } 272 273 static bool setReportingMode(uint8_t mode, uint8_t state) 274 { 275 struct I2cTransfer *xfer; 276 277 xfer = allocXfer(state); 278 if (xfer != NULL) { 279 xfer->txrxBuf[0] = S3708_REG_CTRL_BASE + S3708_REG_CTRL_20_OFFSET; 280 xfer->txrxBuf[1] = 0x00; 281 xfer->txrxBuf[2] = 0x00; 282 xfer->txrxBuf[3] = mode; 283 return performXfer(xfer, 4, 0); 284 } 285 286 return false; 287 } 288 289 static void setRetryTimer() 290 { 291 mTask.retryCnt++; 292 if (mTask.retryCnt < MAX_I2C_RETRY_COUNT) { 293 mTask.retryTimerHandle = timTimerSet(MAX_I2C_RETRY_DELAY, 0, 50, retryTimerCallback, NULL, true); 294 if (!mTask.retryTimerHandle) { 295 ERROR_PRINT("failed to allocate timer"); 296 } 297 } else { 298 ERROR_PRINT("could not communicate with touch controller"); 299 } 300 } 301 302 static void setGesturePower(bool enable, bool skipI2c) 303 { 304 bool ret; 305 size_t i; 306 307 VERBOSE_PRINT("gesture: %d", enable); 308 309 // Cancel any pending I2C transactions by changing the callback state 310 for (i = 0; i < ARRAY_SIZE(mTask.transfers); i++) { 311 if (mTask.transfers[i].inUse) { 312 mTask.transfers[i].state = STATE_CANCELLED; 313 } 314 } 315 316 if (enable) { 317 mTask.retryCnt = 0; 318 319 // Set page number to 0x00 320 ret = writeRegister(S3708_REG_PAGE_SELECT, 0x00, STATE_ENABLE_0); 321 } else { 322 // Cancel any pending retries 323 if (mTask.retryTimerHandle) { 324 timTimerCancel(mTask.retryTimerHandle); 325 mTask.retryTimerHandle = 0; 326 } 327 328 if (skipI2c) { 329 ret = true; 330 } else { 331 // Reset to continuous reporting mode 332 ret = setReportingMode(S3708_REPORT_MODE_CONT, STATE_DISABLE_0); 333 } 334 } 335 336 if (ret) { 337 mTask.gestureEnabled = enable; 338 enableInterrupt(enable); 339 } 340 } 341 342 static void configProx(bool on) { 343 if (on) { 344 mTask.stats.proxEnabledTimestamp = sensorGetTime(); 345 sensorRequest(mTask.id, mTask.proxHandle, DEFAULT_PROX_RATE_HZ, 346 DEFAULT_PROX_LATENCY); 347 osEventSubscribe(mTask.id, EVT_SENSOR_PROX); 348 } else { 349 sensorRelease(mTask.id, mTask.proxHandle); 350 osEventUnsubscribe(mTask.id, EVT_SENSOR_PROX); 351 352 mTask.stats.totalProxEnabledTime += sensorGetTime() - mTask.stats.proxEnabledTimestamp; 353 if (mTask.proxState == PROX_STATE_FAR) { 354 mTask.stats.totalProxFarTime += sensorGetTime() - mTask.stats.lastProxFarTimestamp; 355 } 356 } 357 mTask.proxState = PROX_STATE_UNKNOWN; 358 } 359 360 static bool callbackPower(bool on, void *cookie) 361 { 362 uint32_t enabledSeconds, proxEnabledSeconds, proxFarSeconds; 363 364 VERBOSE_PRINT("power: %d", on); 365 366 if (on) { 367 mTask.stats.enabledTimestamp = sensorGetTime(); 368 } else { 369 mTask.stats.totalEnabledTime += sensorGetTime() - mTask.stats.enabledTimestamp; 370 } 371 372 enabledSeconds = U64_DIV_BY_U64_CONSTANT(mTask.stats.totalEnabledTime, 1000000000); 373 proxEnabledSeconds = U64_DIV_BY_U64_CONSTANT(mTask.stats.totalProxEnabledTime, 1000000000); 374 proxFarSeconds = U64_DIV_BY_U64_CONSTANT(mTask.stats.totalProxFarTime, 1000000000); 375 VERBOSE_PRINT("STATS: enabled %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 376 ", prox enabled %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 377 ", prox far %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 378 ", prox *->f %" PRIu32 379 ", prox *->n %" PRIu32, 380 enabledSeconds / 3600, (enabledSeconds % 3600) / 60, enabledSeconds % 60, 381 proxEnabledSeconds / 3600, (proxEnabledSeconds % 3600) / 60, proxEnabledSeconds % 60, 382 proxFarSeconds / 3600, (proxFarSeconds % 3600) / 60, proxFarSeconds % 60, 383 mTask.stats.totalProxBecomesFar, 384 mTask.stats.totalProxBecomesNear); 385 386 // If the task is disabled, that means the AP is on and has switched the I2C 387 // mux. Therefore, no I2C transactions will succeed so skip them. 388 if (mTask.gestureEnabled) { 389 setGesturePower(false, true /* skipI2c */); 390 } 391 392 mTask.on = on; 393 configProx(on); 394 395 return sensorSignalInternalEvt(mTask.handle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, mTask.on, 0); 396 } 397 398 static bool callbackFirmwareUpload(void *cookie) 399 { 400 return sensorSignalInternalEvt(mTask.handle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0); 401 } 402 403 static bool callbackSetRate(uint32_t rate, uint64_t latency, void *cookie) 404 { 405 return sensorSignalInternalEvt(mTask.handle, SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency); 406 } 407 408 static bool callbackFlush(void *cookie) 409 { 410 return osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_DOUBLE_TOUCH), SENSOR_DATA_EVENT_FLUSH, NULL); 411 } 412 413 static const struct SensorInfo mSensorInfo = { 414 .sensorName = "Double Touch", 415 .sensorType = SENS_TYPE_DOUBLE_TOUCH, 416 .numAxis = NUM_AXIS_EMBEDDED, 417 .interrupt = NANOHUB_INT_WAKEUP, 418 .minSamples = 20 419 }; 420 421 static const struct SensorOps mSensorOps = 422 { 423 .sensorPower = callbackPower, 424 .sensorFirmwareUpload = callbackFirmwareUpload, 425 .sensorSetRate = callbackSetRate, 426 .sensorFlush = callbackFlush, 427 }; 428 429 static void processI2cResponse(struct I2cTransfer *xfer) 430 { 431 struct I2cTransfer *nextXfer; 432 union EmbeddedDataPoint sample; 433 434 switch (xfer->state) { 435 case STATE_ENABLE_0: 436 setSleepEnable(false, STATE_ENABLE_1); 437 break; 438 439 case STATE_ENABLE_1: 440 // HACK: DozeService reactivates pickup gesture before the screen 441 // comes on, so we need to wait for some time after enabling before 442 // trying to talk to touch controller. We may see the touch 443 // controller on the first few samples and then have communication 444 // switched off. So, wait HACK_RETRY_SKIP_COUNT samples before we 445 // consider the transaction. 446 if (mTask.retryCnt < HACK_RETRY_SKIP_COUNT) { 447 setRetryTimer(); 448 } else { 449 setReportingMode(S3708_REPORT_MODE_LPWG, STATE_ENABLE_2); 450 } 451 break; 452 453 case STATE_ENABLE_2: 454 // Poll the GPIO line to see if it is low/active (it might have been 455 // low when we enabled the ISR, e.g. due to a pending touch event). 456 // Only do this after arming the LPWG, so it happens after we know 457 // that we can talk to the touch controller. 458 if (!gpioGet(mTask.pin)) { 459 osEnqueuePrivateEvt(EVT_SENSOR_TOUCH_INTERRUPT, NULL, NULL, mTask.id); 460 } 461 break; 462 463 case STATE_DISABLE_0: 464 setSleepEnable(true, STATE_IDLE); 465 break; 466 467 case STATE_INT_HANDLE_0: 468 // If the interrupt was from the LPWG function, read the function interrupt status register 469 if (xfer->txrxBuf[1] & S3708_INT_STATUS_LPWG) { 470 nextXfer = allocXfer(STATE_INT_HANDLE_1); 471 if (nextXfer != NULL) { 472 nextXfer->txrxBuf[0] = S3708_REG_DATA_BASE + S3708_REG_DATA_4_OFFSET; 473 performXfer(nextXfer, 1, 5); 474 } 475 } 476 break; 477 478 case STATE_INT_HANDLE_1: 479 // Verify the LPWG interrupt status 480 if (xfer->txrxBuf[0] & S3708_INT_STATUS_DOUBLE_TAP) { 481 DEBUG_PRINT("Sending event"); 482 sample.idata = 1; 483 osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_DOUBLE_TOUCH), sample.vptr, NULL); 484 } 485 break; 486 487 default: 488 break; 489 } 490 } 491 492 static void handleI2cEvent(struct I2cTransfer *xfer) 493 { 494 if (xfer->err == 0) { 495 processI2cResponse(xfer); 496 } else if (xfer->state == STATE_ENABLE_0 || xfer->state == STATE_ENABLE_1) { 497 setRetryTimer(); 498 } 499 500 xfer->inUse = false; 501 } 502 503 static void handleEvent(uint32_t evtType, const void* evtData) 504 { 505 struct I2cTransfer *xfer; 506 union EmbeddedDataPoint embeddedSample; 507 enum ProxState lastProxState; 508 int ret; 509 510 switch (evtType) { 511 case EVT_APP_START: 512 osEventUnsubscribe(mTask.id, EVT_APP_START); 513 ret = i2cMasterRequest(I2C_BUS_ID, I2C_SPEED); 514 // Since the i2c bus can be shared with other drivers, it is 515 // possible that one of the other drivers requested the bus first. 516 // Therefore, either 0 or -EBUSY is an acceptable return. 517 if ((ret < 0) && (ret != -EBUSY)) { 518 ERROR_PRINT("i2cMasterRequest() failed!"); 519 } 520 521 sensorFind(SENS_TYPE_PROX, 0, &mTask.proxHandle); 522 523 sensorRegisterInitComplete(mTask.handle); 524 break; 525 526 case EVT_SENSOR_I2C: 527 handleI2cEvent((struct I2cTransfer *)evtData); 528 break; 529 530 case EVT_SENSOR_TOUCH_INTERRUPT: 531 if (mTask.on) { 532 // Read the interrupt status register 533 xfer = allocXfer(STATE_INT_HANDLE_0); 534 if (xfer != NULL) { 535 xfer->txrxBuf[0] = S3708_REG_F01_DATA_BASE; 536 performXfer(xfer, 1, 2); 537 } 538 } 539 break; 540 541 case EVT_SENSOR_PROX: 542 if (mTask.on) { 543 // cast off the const, and cast to union 544 embeddedSample = (union EmbeddedDataPoint)((void*)evtData); 545 lastProxState = mTask.proxState; 546 mTask.proxState = (embeddedSample.fdata < PROXIMITY_THRESH_NEAR) ? PROX_STATE_NEAR : PROX_STATE_FAR; 547 548 if ((lastProxState != PROX_STATE_FAR) && (mTask.proxState == PROX_STATE_FAR)) { 549 ++mTask.stats.totalProxBecomesFar; 550 mTask.stats.lastProxFarTimestamp = sensorGetTime(); 551 setGesturePower(true, false); 552 } else if ((lastProxState != PROX_STATE_NEAR) && (mTask.proxState == PROX_STATE_NEAR)) { 553 ++mTask.stats.totalProxBecomesNear; 554 if (lastProxState == PROX_STATE_FAR) { 555 mTask.stats.totalProxFarTime += sensorGetTime() - mTask.stats.lastProxFarTimestamp; 556 setGesturePower(false, false); 557 } 558 } 559 } 560 break; 561 562 case EVT_SENSOR_RETRY_TIMER: 563 if (mTask.on) { 564 // Set page number to 0x00 565 writeRegister(S3708_REG_PAGE_SELECT, 0x00, STATE_ENABLE_0); 566 } 567 break; 568 } 569 } 570 571 static bool startTask(uint32_t taskId) 572 { 573 mTask.id = taskId; 574 mTask.handle = sensorRegister(&mSensorInfo, &mSensorOps, NULL, false); 575 576 mTask.pin = gpioRequest(TOUCH_PIN); 577 gpioConfigInput(mTask.pin, GPIO_SPEED_LOW, GPIO_PULL_NONE); 578 syscfgSetExtiPort(mTask.pin); 579 mTask.isr.func = touchIsr; 580 581 mTask.stats.totalProxBecomesFar = 0; 582 mTask.stats.totalProxBecomesNear = 0; 583 584 osEventSubscribe(taskId, EVT_APP_START); 585 return true; 586 } 587 588 static void endTask(void) 589 { 590 enableInterrupt(false); 591 extiUnchainIsr(TOUCH_IRQ, &mTask.isr); 592 extiClearPendingGpio(mTask.pin); 593 gpioRelease(mTask.pin); 594 595 i2cMasterRelease(I2C_BUS_ID); 596 597 sensorUnregister(mTask.handle); 598 } 599 600 INTERNAL_APP_INIT(S3708_APP_ID, S3708_APP_VERSION, startTask, endTask, handleEvent); 601