diff options
Diffstat (limited to 'rmidevice/hiddevice.cpp')
-rwxr-xr-x | rmidevice/hiddevice.cpp | 130 |
1 files changed, 113 insertions, 17 deletions
diff --git a/rmidevice/hiddevice.cpp b/rmidevice/hiddevice.cpp index 709559d..b81d70a 100755 --- a/rmidevice/hiddevice.cpp +++ b/rmidevice/hiddevice.cpp @@ -40,6 +40,8 @@ #define RMI_READ_DATA_REPORT_ID 0xb // Input Report #define RMI_ATTN_REPORT_ID 0xc // Input Report #define RMI_SET_RMI_MODE_REPORT_ID 0xf // Feature Report +#define RMI_SET_LID_MODE_REPORT_ID 0xe // Feature Report + enum hid_report_type { HID_REPORT_TYPE_UNKNOWN = 0x0, @@ -218,6 +220,10 @@ void HIDDevice::ParseReportDescriptor() continue; } + if (m_rptDesc.value[i] == RMI_SET_LID_MODE_REPORT_ID) { + hasVendorDefineLIDMode = true; + } + if (m_rptDesc.value[i] == HID_REPORT_TYPE_INPUT) hidReportType = HID_REPORT_TYPE_INPUT; @@ -291,16 +297,32 @@ int HIDDevice::Read(unsigned short addr, unsigned char *buf, unsigned short len) size_t bytesToRequest; int reportId; int rc; + struct timeval tv; + int resendCount = 0; + tv.tv_sec = 10 / 1000; + tv.tv_usec = (10 % 1000) * 1000; + if (!m_deviceOpen) return -1; + if (m_hasDebug) { + fprintf(stdout, "R %02x : ", addr); + } + if (m_bytesPerReadRequest) bytesPerRequest = m_bytesPerReadRequest; else bytesPerRequest = len; for (totalBytesRead = 0; totalBytesRead < len; totalBytesRead += bytesReadPerRequest) { +Resend: + if (GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + if (resendCount == 3) { + fprintf(stderr, "resend count exceed, return as failure\n"); + return -1; + } + } count = 0; if ((len - totalBytesRead) < bytesPerRequest) bytesToRequest = len % bytesPerRequest; @@ -334,7 +356,13 @@ int HIDDevice::Read(unsigned short addr, unsigned char *buf, unsigned short len) bytesReadPerRequest = 0; while (bytesReadPerRequest < bytesToRequest) { - rc = GetReport(&reportId); + if (GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Add timeout 10 ms for select() called in GetReport(). + rc = GetReport(&reportId, &tv); + } else { + // Touch Screen + rc = GetReport(&reportId); + } if (rc > 0 && reportId == RMI_READ_DATA_REPORT_ID) { if (static_cast<ssize_t>(m_inputReportSize) < std::max(HID_RMI4_READ_INPUT_COUNT, @@ -350,10 +378,24 @@ int HIDDevice::Read(unsigned short addr, unsigned char *buf, unsigned short len) bytesInDataReport); bytesReadPerRequest += bytesInDataReport; m_dataBytesRead = 0; + if (GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Resend sheme is supported on TP only. + resendCount = 0; + } + } else if (GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + fprintf(stderr, "Some error with GetReport : rc(%d), reportID(0x%x)\n", rc, reportId); + resendCount += 1; + goto Resend; } } addr += bytesPerRequest; } + if (m_hasDebug) { + for (int i=0 ; i<len ; i++) { + fprintf(stdout, "%02x ", buf[i]); + } + fprintf(stdout, "\n"); + } return totalBytesRead; } @@ -374,6 +416,14 @@ int HIDDevice::Write(unsigned short addr, const unsigned char *buf, unsigned sho m_outputReport[HID_RMI4_WRITE_OUTPUT_ADDR + 1] = (addr >> 8) & 0xFF; memcpy(&m_outputReport[HID_RMI4_WRITE_OUTPUT_DATA], buf, len); + if (m_hasDebug) { + fprintf(stdout, "W %02x : ", addr); + for (int i=0 ; i<len ; i++) { + fprintf(stdout, "%02x ", buf[i]); + } + fprintf(stdout, "\n"); + } + for (;;) { m_bCancel = false; count = write(m_fd, m_outputReport, m_outputReportSize); @@ -391,11 +441,11 @@ int HIDDevice::SetMode(int mode) { int rc; char buf[2]; - + if (!m_deviceOpen) return -1; - buf[0] = 0xF; + buf[0] = RMI_SET_RMI_MODE_REPORT_ID; buf[1] = mode; rc = ioctl(m_fd, HIDIOCSFEATURE(2), buf); if (rc < 0) { @@ -406,6 +456,44 @@ int HIDDevice::SetMode(int mode) return 0; } +int HIDDevice::ToggleInterruptMask(bool enable) +{ + int rc; + char buf[2]; + + if (GetDeviceType() != RMI_DEVICE_TYPE_TOUCHPAD) { + fprintf(stdout, "Not TP, skip toggle interrupts mask\n"); + return 0; + } + + // We can have information to see whether it exists this feature report currentlt. + // However, it might have no action even we set this feature with specific value. + // Need FW team's help to query more information about the existence of functions. + if (!hasVendorDefineLIDMode) { + if (m_hasDebug) { + fprintf(stdout, "no LID mode feature, return\n"); + } + return 0; + } + + if (!m_deviceOpen) + return -1; + + buf[0] = RMI_SET_LID_MODE_REPORT_ID; + if (enable) { + buf[1] = 0; + } else { + buf[1] = 8; + } + rc = ioctl(m_fd, HIDIOCSFEATURE(2), buf); + if (rc < 0) { + perror("HIDIOCSFEATURE"); + return rc; + } + Sleep(10); + return 0; +} + void HIDDevice::Close() { RMIDevice::Close(); @@ -655,11 +743,9 @@ bool HIDDevice::CheckABSEvent() int fd=-1; unsigned int type; int abs[6] = {0}; - int k; struct dirent **namelist; - int i, ndev, devnum, match; - char *filename; - int max_device = 0; + int i, ndev; + char input_event_name[PATH_MAX]; unsigned long bit[EV_MAX][NBITS(KEY_MAX)]; @@ -793,15 +879,8 @@ bool HIDDevice::FindTransportDevice(uint32_t bus, std::string & hidDeviceName, if (bus == BUS_I2C) { devicePrefix += "i2c/"; - // From new patch released on 2020/11, i2c_hid would be renamed as i2c_hid_acpi, - // and also need backward compatible. - std::string driverPathTemp = devicePrefix + "drivers/i2c_hid/"; - DIR *driverPathtest = opendir(driverPathTemp.c_str()); - if(!driverPathtest) { - driverPath = devicePrefix + "drivers/i2c_hid_acpi/"; - } else { - driverPath = devicePrefix + "drivers/i2c_hid/"; - } + // The i2c driver module installed on system is vary (i2c_hid, i2c_hid_acpi, i2c_hid_of), + // so we will assign driver path until we get device name later. } else { devicePrefix += "usb/"; driverPath = devicePrefix + "drivers/usbhid/"; @@ -840,8 +919,25 @@ bool HIDDevice::FindTransportDevice(uint32_t bus, std::string & hidDeviceName, } closedir(devDir); - if (deviceFound) + if (deviceFound) { + if (bus == BUS_I2C) { + std::fstream ueventfile; + std::string ueventfilepath = fullLinkPath + "/uevent"; + std::string uevent; + std::string modulename; + ueventfile.open(ueventfilepath.c_str(), std::ios::in); + if(ueventfile.is_open()) { + getline(ueventfile, uevent); + modulename = uevent.substr(uevent.find("=") + 1, std::string::npos); + driverPath = devicePrefix + "drivers/"; + driverPath += modulename; + driverPath += "/"; + } + ueventfile.close(); + } break; + } + } closedir(devicesDir); |