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