aboutsummaryrefslogtreecommitdiff
path: root/rmidevice/hiddevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rmidevice/hiddevice.cpp')
-rwxr-xr-xrmidevice/hiddevice.cpp130
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);