RK3399 android10 移植SiS-USB触摸驱动

一,SiS USB触摸简介

SiS USB 触摸屏通常是一种外接式触摸屏设备,通过 USB 接口连接到计算机或其他设备上。这种触摸屏设备可以提供触摸输入功能,用户可以通过手指或触控笔在屏幕上进行操作,实现点击、拖动、缩放等操作。
SiS USB 触摸屏通常需要安装相应的驱动程序才能正常工作,在计算机系统中被识别为触摸输入设备。驱动程序会将触摸屏输入转换为计算机可识别的信号,从而实现触摸屏在操作系统中的正常使用。


二,驱动文件配置

1. hid_sis内核模块驱动文件

在这里插入图片描述

hid-sis_ctrl.c :在Linux内核中,HID设备驱动程序负责与各种输入设备(如键盘、鼠标、游戏手柄等)进行通信和管理。包含与特定类型的HID设备通信的代码实现,包括设备的初始化、数据传输、事件处理等功能。这个文件可能会被编译到内核中,以便在系统启动时加载并与相应的HID设备进行交互。

/**  Character device driver for SIS multitouch panels control**  Copyright (c) 2023 SIS, Ltd.**//** This program is free software; you can redistribute it and/or modify it* under the terms of the GNU General Public License as published by the Free* Software Foundation; either version 2 of the License, or (at your option)* any later version.*/#include <linux/hid.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "usbhid/usbhid.h"
#include <linux/init.h>//update FW
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>				//copy_from_user() & copy_to_user()#include "hid-ids.h"
#include "hid-sis_ctrl.h"static int sis_char_devs_count = 1;        		/* device count */
static int sis_char_major = 0;
static struct cdev sis_char_cdev;
static struct class *sis_char_class = NULL;static struct hid_device *hid_dev_backup = NULL;	//backup address
static struct urb *backup_urb = NULL;#define	REPORTID_21_LEN	64
#define	REPORTID_25_LEN	320
#define	REPORTID_29_LEN	576
#define	REPORTID_2D_LEN	832#ifdef CONFIG_DEBUG_HID_SIS_UPDATE_FW#define DBG_FW(fmt, arg...)	printk( fmt, ##arg )void sis_dbg_dump_array( u8 *ptr, u32 size){u32 i;for (i=0; i<size; i++)  {DBG_FW ("%02X ", ptr[i]);if( ((i+1)&0xF) == 0)DBG_FW ("\n");}if( size & 0xF)DBG_FW ("\n");}
#else#define DBG_FW(...)#define sis_dbg_dump_array(...)
#endif	// CONFIG_DEBUG_HID_SIS_UPDATE_FWint sis_cdev_open(struct inode *inode, struct file *filp)	//20120306 Yuger ioctl for tool
{struct usbhid_device *usbhid; DBG_FW( "%s\n" , __FUNCTION__ );//20110511, Yuger, kill current urb by method of usbhid_stopif ( !hid_dev_backup ){printk( KERN_INFO "(stop)hid_dev_backup is not initialized yet" );return -1;}usbhid = hid_dev_backup->driver_data;printk( KERN_INFO "sys_sis_HID_stop\n" );//printk( KERN_INFO "hid_dev_backup->vendor, hid_dev_backup->product = %x %x\n", hid_dev_backup->vendor, hid_dev_backup->product );//20110602, Yuger, fix bug: not contact usb cause kernel panicif( !usbhid ){printk( KERN_INFO "(stop)usbhid is not initialized yet" );return -1;}else if ( !usbhid->urbin ){printk( KERN_INFO "(stop)usbhid->urbin is not initialized yet" );return -1;}else if (hid_dev_backup->vendor == USB_VENDOR_ID_SIS_TOUCH){usb_fill_int_urb(backup_urb, usbhid->urbin->dev, usbhid->urbin->pipe,usbhid->urbin->transfer_buffer, usbhid->urbin->transfer_buffer_length,usbhid->urbin->complete, usbhid->urbin->context, usbhid->urbin->interval);clear_bit( HID_STARTED, &usbhid->iofl );set_bit( HID_DISCONNECTED, &usbhid->iofl );usb_kill_urb( usbhid->urbin );usb_free_urb( usbhid->urbin );usbhid->urbin = NULL;return 0;}else	{printk (KERN_INFO "This is not a SiS device");return -801;}
}int sis_cdev_release(struct inode *inode, struct file *filp)
{//20110505, Yuger, rebuild the urb which is at the same urb address, then re-submit itint ret;struct usbhid_device *usbhid;unsigned long flags;DBG_FW( "%s: " , __FUNCTION__ );if ( !hid_dev_backup ){printk( KERN_INFO "(stop)hid_dev_backup is not initialized yet" );return -1;}usbhid = hid_dev_backup->driver_data;printk( KERN_INFO "sys_sis_HID_start" );if( !usbhid ){printk( KERN_INFO "(start)usbhid is not initialized yet" );return -1;}if( !backup_urb ){printk( KERN_INFO "(start)backup_urb is not initialized yet" );return -1;}clear_bit( HID_DISCONNECTED, &usbhid->iofl );usbhid->urbin = usb_alloc_urb( 0, GFP_KERNEL );if( !backup_urb->interval ){printk( KERN_INFO "(start)backup_urb->interval does not exist" );return -1;}usb_fill_int_urb(usbhid->urbin, backup_urb->dev, backup_urb->pipe, backup_urb->transfer_buffer, backup_urb->transfer_buffer_length, backup_urb->complete, backup_urb->context, backup_urb->interval);usbhid->urbin->transfer_dma = usbhid->inbuf_dma;usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;set_bit( HID_STARTED, &usbhid->iofl );//method at hid_start_inspin_lock_irqsave( &usbhid->lock, flags );		ret = usb_submit_urb( usbhid->urbin, GFP_ATOMIC );spin_unlock_irqrestore( &usbhid->lock, flags );//yyDBG_FW( "ret = %d", ret );return ret;
}ssize_t sis_cdev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{int timeout = 0;u8 *rep_data = NULL;u8 *temp_data = NULL;u16 size = 0;long rep_ret;struct usb_interface *intf = to_usb_interface(hid_dev_backup->dev.parent);struct usb_device *dev = interface_to_usbdev(intf);
#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)u16 reportID = 0;
#elseint actual_length = 0;
#endifDBG_FW( "%s\n", __FUNCTION__ );temp_data = kzalloc(count, GFP_KERNEL);if(!temp_data) {printk( KERN_INFO "kzalloc temp_data fail\n");return (-12);}if ( copy_from_user( temp_data, (void*)buf, count) ) {printk( KERN_INFO "copy_from_user(temp_data) fail\n" );//free allocated datakfree( temp_data );temp_data = NULL;return -19;}#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)switch (temp_data[0]) {case 0x21:size = (((u16)(temp_data[REPORTID_21_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_21_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_21_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_21_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_21_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_21_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_21_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_21_LEN + 7] & 0xff);reportID = 0x0321;DBG_FW("%s Report ID : 0x21\n" , __FUNCTION__);break;case 0x25:size = (((u16)(temp_data[REPORTID_25_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_25_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_25_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_25_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_25_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_25_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_25_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_25_LEN + 7] & 0xff);reportID = 0x0325;DBG_FW("%s Report ID : 0x25\n" , __FUNCTION__);break;case 0x29:size = (((u16)(temp_data[REPORTID_29_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_29_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_29_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_29_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_29_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_29_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_29_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_29_LEN + 7] & 0xff);reportID = 0x0329;DBG_FW("%s Report ID : 0x29\n" , __FUNCTION__);break;case 0x2d:size = (((u16)(temp_data[REPORTID_2D_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_2D_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_2D_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_2D_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_2D_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_2D_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_2D_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_2D_LEN + 7] & 0xff);reportID = 0x032d;DBG_FW( "%s Report ID : 0x2d\n" , __FUNCTION__ );break;default:break;}
#elsesize = (((u16)(temp_data[64] & 0xff)) << 24) + (((u16)(temp_data[65] & 0xff)) << 16) + (((u16)(temp_data[66] & 0xff)) << 8) + (u16)(temp_data[67] & 0xff);timeout = (((int)(temp_data[68] & 0xff)) << 24) + (((int)(temp_data[69] & 0xff)) << 16) + (((int)(temp_data[70] & 0xff)) << 8) + (int)(temp_data[71] & 0xff);DBG_FW("%s Report ID : 0x0a\n" , __FUNCTION__);	
#endifkfree(temp_data);temp_data = NULL;DBG_FW("timeout = %d, size %d\n", timeout, size);#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)if (!access_ok(VERIFY_WRITE, buf, size)) {
#elseif (!access_ok(buf, size)) {
#endifprintk(KERN_INFO "cannot access user space memory\n");return -11;}rep_data = kzalloc(size, GFP_KERNEL);if (!rep_data) {printk(KERN_INFO "kzalloc rep_data fail\n");return -12;}if (copy_from_user(rep_data, (void*)buf, size)) {printk(KERN_INFO "copy_to_user fail(rep_data)\n");//free allocated datakfree(rep_data);rep_data = NULL;return -19;}#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)rep_ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x01, (USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE), reportID, 0, rep_data, size, timeout);DBG_FW("%s: rep_data = ", __FUNCTION__);sis_dbg_dump_array(rep_data, 8);if (copy_to_user((void*)buf, rep_data, rep_ret)) {printk(KERN_INFO "copy_to_user fail(buf)\n");//free allocated datakfree(rep_data);rep_data = NULL;return -19;}
#elserep_ret = usb_interrupt_msg(dev, backup_urb->pipe,rep_data, size, &actual_length, timeout);DBG_FW("%s: rep_data = ", __FUNCTION__);sis_dbg_dump_array(rep_data, 8);if (rep_ret == 0) {if (copy_to_user((void*)buf, rep_data, actual_length)) {printk(KERN_INFO "copy_to_user fail(buf)\n");//free allocated datakfree(rep_data);rep_data = NULL;return -19;}}
#endif//free allocated datakfree(rep_data);rep_data = NULL;DBG_FW("%s: rep_ret = %ld\n", __FUNCTION__, rep_ret);return rep_ret;
}ssize_t sis_cdev_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
{int timeout = 0;u8 *rep_data = NULL;u8 *temp_data = NULL;u16 size = 0;long rep_ret;struct usb_interface *intf = to_usb_interface(hid_dev_backup->dev.parent);struct usb_device *dev = interface_to_usbdev(intf);
#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)u16 reportID = 0;
#elseint actual_length = 0;struct usbhid_device *usbhid = hid_dev_backup->driver_data;
#endifDBG_FW( "%s\n", __FUNCTION__ );temp_data = kzalloc(count, GFP_KERNEL);if(!temp_data){printk( KERN_INFO "kzalloc temp_data fail\n");return (-12);}if ( copy_from_user( temp_data, (void*)buf, count) ) {printk( KERN_INFO "copy_from_user(temp_data) fail\n" );//free allocated datakfree( temp_data );temp_data = NULL;return -19;}#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)switch (temp_data[0]) {case 0x21:size = (((u16)(temp_data[REPORTID_21_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_21_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_21_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_21_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_21_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_21_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_21_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_21_LEN + 7] & 0xff);reportID = 0x0321;DBG_FW("%s Report ID : 0x21\n" , __FUNCTION__);break;case 0x25:size = (((u16)(temp_data[REPORTID_25_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_25_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_25_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_25_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_25_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_25_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_25_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_25_LEN + 7] & 0xff);reportID = 0x0325;DBG_FW("%s Report ID : 0x25\n" , __FUNCTION__);break;case 0x29:size = (((u16)(temp_data[REPORTID_29_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_29_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_29_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_29_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_29_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_29_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_29_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_29_LEN + 7] & 0xff);reportID = 0x0329;DBG_FW("%s Report ID : 0x29\n" , __FUNCTION__);break;case 0x2d:size = (((u16)(temp_data[REPORTID_2D_LEN] & 0xff)) << 24)+ (((u16)(temp_data[REPORTID_2D_LEN + 1] & 0xff)) << 16)+ (((u16)(temp_data[REPORTID_2D_LEN + 2] & 0xff)) << 8)+ (u16)(temp_data[REPORTID_2D_LEN + 3] & 0xff);timeout = (((int)(temp_data[REPORTID_2D_LEN + 4] & 0xff)) << 24)+ (((int)(temp_data[REPORTID_2D_LEN + 5] & 0xff)) << 16)+ (((int)(temp_data[REPORTID_2D_LEN + 6 ] & 0xff)) << 8)+ (int)(temp_data[REPORTID_2D_LEN + 7] & 0xff);reportID = 0x032d;DBG_FW("%s Report ID : 0x2d\n" , __FUNCTION__);break;default:break;}
#elsesize = (((u16)(temp_data[64] & 0xff)) << 24) + (((u16)(temp_data[65] & 0xff)) << 16) + (((u16)(temp_data[66] & 0xff)) << 8) + (u16)(temp_data[67] & 0xff);timeout = (((int)(temp_data[68] & 0xff)) << 24) + (((int)(temp_data[69] & 0xff)) << 16) + (((int)(temp_data[70] & 0xff)) << 8) + (int)(temp_data[71] & 0xff);DBG_FW("%s Report ID : 0x09\n" , __FUNCTION__);
#endifDBG_FW("timeout = %d, size %d\n", timeout, size);kfree(temp_data);temp_data = NULL;#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)if (!access_ok(VERIFY_WRITE, buf, size)) {
#elseif (!access_ok(buf, size)) {
#endifprintk(KERN_INFO "cannot access user space memory\n");return -11;}rep_data = kzalloc(size, GFP_KERNEL);if (!rep_data) {printk(KERN_INFO "kzalloc rep_data fail\n");return -12;}if (copy_from_user(rep_data, (void*)buf, size)) {printk(KERN_INFO "copy_to_user fail(rep_data)\n");//free allocated datakfree(rep_data);rep_data = NULL;return -19;}#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)rep_ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x09, (USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE), reportID, 0, rep_data, size, timeout);DBG_FW("%s: rep_data = ", __FUNCTION__);sis_dbg_dump_array(rep_data, 8);if (copy_to_user((void*)buf, rep_data, rep_ret)) {printk(KERN_INFO "copy_to_user fail(buf)\n");//free allocated datakfree(rep_data);rep_data = NULL;return -19;}
#elserep_ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,rep_data, size, &actual_length, timeout);DBG_FW("%s: rep_data = ", __FUNCTION__);sis_dbg_dump_array(rep_data, size);if (rep_ret == 0) {if (copy_to_user((void*)buf, rep_data, actual_length)) {printk(KERN_INFO "copy_to_user fail(buf)\n");//free allocated datakfree(rep_data);rep_data = NULL;return -19;}}
#endif		DBG_FW("%s: rep_ret = %ld\n", __FUNCTION__, rep_ret);//free allocated datakfree(rep_data);rep_data = NULL;DBG_FW("End of sys_sis_HID_IO\n");return rep_ret;
}//for ioctl
static const struct file_operations sis_cdev_fops = {.owner	= THIS_MODULE,.read	= sis_cdev_read,.write	= sis_cdev_write,.open	= sis_cdev_open,.release= sis_cdev_release,
};//for ioctl
int sis_setup_chardev(struct hid_device *hdev)
{dev_t dev = MKDEV(sis_char_major, 0);int alloc_ret = 0;int cdev_err = 0;int input_err = 0;struct device *class_dev = NULL;void *ptr_err;printk("sis_setup_chardev.\n");hid_dev_backup = hdev;backup_urb = usb_alloc_urb(0, GFP_KERNEL); //0721testif (!backup_urb) {dev_err(&hdev->dev, "cannot allocate backup_urb\n");return -ENOMEM;}// dynamic allocate driver handle
#ifdef SIS_BRIDGE_ENABLEDalloc_ret = alloc_chrdev_region(&dev, 0, sis_char_devs_count, SIS_BRIDGE_DEVICE_NAME);
#elsealloc_ret = alloc_chrdev_region(&dev, 0, sis_char_devs_count, SIS_DEVICE_NAME);
#endif		if (alloc_ret)goto error;sis_char_major  = MAJOR(dev);cdev_init(&sis_char_cdev, &sis_cdev_fops);sis_char_cdev.owner = THIS_MODULE;cdev_err = cdev_add(&sis_char_cdev, MKDEV(sis_char_major, 0), sis_char_devs_count);if (cdev_err) goto error;#ifdef SIS_BRIDGE_ENABLEDprintk(KERN_INFO "%s driver(major %d) installed.\n", SIS_BRIDGE_DEVICE_NAME, sis_char_major);
#elseprintk(KERN_INFO "%s driver(major %d) installed.\n", SIS_DEVICE_NAME, sis_char_major);
#endif// register class
#ifdef SIS_BRIDGE_ENABLED
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0)sis_char_class = class_create(THIS_MODULE, SIS_BRIDGE_DEVICE_NAME);
#elsesis_char_class = class_create(SIS_BRIDGE_DEVICE_NAME);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0)
#else
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0)sis_char_class = class_create(THIS_MODULE, SIS_DEVICE_NAME);
#elsesis_char_class = class_create(SIS_DEVICE_NAME);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0)
#endif //SIS_BRIDGE_ENABLEDif (IS_ERR(ptr_err = sis_char_class))goto err2;#ifdef SIS_BRIDGE_ENABLEDclass_dev = device_create(sis_char_class, NULL, MKDEV(sis_char_major, 0), NULL, SIS_BRIDGE_DEVICE_NAME);
#elseclass_dev = device_create(sis_char_class, NULL, MKDEV(sis_char_major, 0), NULL, SIS_DEVICE_NAME);
#endifif (IS_ERR(ptr_err = class_dev)) goto err;return 0;
error:if (cdev_err == 0)cdev_del(&sis_char_cdev);if (alloc_ret == 0)unregister_chrdev_region(MKDEV(sis_char_major, 0), sis_char_devs_count);if (input_err != 0)printk("sis_ts_bak error!\n");
err:device_destroy(sis_char_class, MKDEV(sis_char_major, 0));
err2:class_destroy(sis_char_class);return -1;
}
EXPORT_SYMBOL(sis_setup_chardev);void sis_deinit_chardev(struct hid_device *hdev)
{//for ioctldev_t dev;printk(KERN_INFO "sis_deinit\n");dev = MKDEV(sis_char_major, 0);cdev_del(&sis_char_cdev);unregister_chrdev_region(dev, sis_char_devs_count);device_destroy(sis_char_class, MKDEV(sis_char_major, 0));class_destroy(sis_char_class);usb_kill_urb(backup_urb);usb_free_urb(backup_urb);backup_urb = NULL;hid_dev_backup = NULL;}
EXPORT_SYMBOL(sis_deinit_chardev);MODULE_DESCRIPTION("SiS Touchscreen Control Driver");
MODULE_LICENSE("GPL");

hid-sis_ctrl.h :包含了与 HID 设备通信和控制相关的宏定义、结构体定义、函数声明等内容。这些内容通常用于描述 HID 设备的特性、命令格式、数据结构等,以便在驱动程序中使用。

#ifndef __HID_SIS_CTRL_H__
#define __HID_SIS_CTRL_H__#include <linux/version.h>	//LINUX_VERSION_CODE & KERNEL_VERSION#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)
#include <asm/uaccess.h>	//copy_from_user() & copy_to_user()
#else
#include <linux/uaccess.h>	//copy_from_user() & copy_to_user()
#endif/* ID-table */
#define USB_VENDOR_ID_SIS_TOUCH	0x0457
#define USB_DEVICE_ID_SIS_TOUCH 0x1905/* Device node name */
#define HID_SIS95XX			// ON/OFF: SiS hydra(6596)/SiS aegis(817)
//#define DEBUG_HID_SIS_UPDATE_FW	// ON/OFF
//#define SIS_BRIDGE_ENABLED		// ON/OFF#if IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)			//6596
#define SIS_DEVICE_NAME "sis_hydra_hid_touch_device"
#define SIS_BRIDGE_DEVICE_NAME "sis_hydra_hid_bridge_touch_device"
#else					//817
#define SIS_DEVICE_NAME "sis_aegis_hid_touch_device"
#define SIS_BRIDGE_DEVICE_NAME "sis_aegis_hid_bridge_touch_device"
#endif/* Report id length */
#define	REPORTID_21_LEN	64
#define	REPORTID_25_LEN	320
#define	REPORTID_29_LEN	576
#define	REPORTID_2D_LEN	832#define CTRL 0
#define ENDP_01 1
#define ENDP_02 2
#define DIR_IN 0x1int sis_cdev_open(struct inode *inode, struct file *filp);
int sis_cdev_release(struct inode *inode, struct file *filp);
ssize_t sis_cdev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos);
ssize_t sis_cdev_write( struct file *file, const char __user *buf, size_t count, loff_t *f_pos );
int sis_setup_chardev(struct hid_device *hdev);
void sis_deinit_chardev(struct hid_device *hdev);#endif	// __HID_SIS_CTRL_H__

2. 修改专用驱动程序列表

kernel version is >= 4.16

a.hid-multitouch.c修改

引用文件,类定义,启动功能,完成功能,添加设备列表

diff --git a/kernel/drivers/hid/hid-multitouch.c b/kernel/drivers/hid/hid-multitouch.c
index 19dfd8acd0..66399569ce 100644
--- a/kernel/drivers/hid/hid-multitouch.c
+++ b/kernel/drivers/hid/hid-multitouch.c
@@ -43,7 +43,9 @@
#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/timer.h>
-
+/* SiSdrv Start */
+#include "hid-sis_ctrl.h"
+/* SiSdrv End */
MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
@@ -207,6 +209,9 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
#define MT_CLS_VTL                0x0110
#define MT_CLS_GOOGLE                0x0111
#define MT_CLS_RAZER_BLADE_STEALTH        0x0112
+/* SiSdrv Start */
+#define MT_CLS_SIS              0x0457
+/* SiSdrv End */
#define MT_DEFAULT_MAXCONTACT    10
#define MT_MAX_MAXCONTACT    250
@@ -357,6 +362,12 @@ static const struct mt_class mt_classes[] = {MT_QUIRK_CONTACT_CNT_ACCURATE |MT_QUIRK_WIN8_PTP_BUTTONS,},
+    /* SiSdrv Start */
+    { .name = MT_CLS_SIS,
+        .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
+            MT_QUIRK_CONTACT_CNT_ACCURATE
+    },
+    /* SiSdrv End */{ }
};
@@ -1716,6 +1727,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID)mt_fix_const_fields(hdev, HID_DG_CONTACTID);
+    /* SiSdrv Start */
+    if (hdev->vendor == USB_VENDOR_ID_SIS_TOUCH) {
+        hdev->quirks |= HID_QUIRK_NOGET;
+        printk(KERN_INFO "sis:sis-probe: quirk = %x\n", hdev->quirks);
+    #ifdef CONFIG_HID_SIS_CTRL
+        ret = sis_setup_chardev(hdev);
+        if (ret)
+            printk( KERN_INFO "sis_setup_chardev fail\n");
+    #endif  //CONFIG_HID_SIS_CTRL
+    }
+    /* SiSdrv End */
+ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);if (ret)return ret;
@@ -1757,6 +1780,13 @@ static void mt_remove(struct hid_device *hdev)del_timer_sync(&td->release_timer);sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
+
+    /* SiSdrv Start */
+    if (hdev->vendor == USB_VENDOR_ID_SIS_TOUCH) {
+        sis_deinit_chardev(hdev);
+    }
+    /* SiSdrv End */
+hid_hw_stop(hdev);
}
@@ -2103,6 +2133,12 @@ static const struct hid_device_id mt_devices[] = {HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,USB_DEVICE_ID_GOOGLE_TOUCH_ROSE) },
+    /* SiSdrv Start */
+    { .driver_data = MT_CLS_SIS,
+        HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_SIS_TOUCH,
+            HID_ANY_ID) },
+    /* SiSdrv End */
+/* Generic MT device */{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },

b.hid-quirks.c修改

将usb触摸vid添加特殊设备列表中

diff --git a/kernel/drivers/hid/hid-quirks.c b/kernel/drivers/hid/hid-quirks.c
index b9529bed4d..c913bfd889 100644
--- a/kernel/drivers/hid/hid-quirks.c
+++ b/kernel/drivers/hid/hid-quirks.c
@@ -720,6 +720,11 @@ static const struct hid_device_id hid_have_special_driver[] = {
#if IS_ENABLED(CONFIG_HID_ZYDACRON){ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
#endif
+/* SiSdrv Start */
+#if IS_ENABLED(CONFIG_HID_SIS92XX) || IS_ENABLED(CONFIG_HID_SIS95XX_SIS98XX)
+    { HID_USB_DEVICE(0x0457, HID_ANY_ID) },
+#endif
+/* SiSdrv End */{ }
};

3. 移植hid_sis驱动

a. 将驱动(hid-sis_ctrl.c,hid-sis_ctrl.h)拷贝到下面的文件夹:

kernel/drivers/hid/

b. 在 Makefile 中添加hid-sis_ctrl设备

kernel/drivers/hid/Makefile:#/  SiSdrv Start    /
obj-$(CONFIG_HID_SIS_CTRL)  += hid-sis_ctrl.o
#/  SiSdrv End  /

c. 在 Kconfig 中添加hid-sis_ctrl

kernel/drivers/hid/Kconfig:#/  SiSdrv Start    /   
config HID_SIS_CTRLtristate "SiS Touch Device Controller"depends on HID_MULTITOUCHdefault yhelpSupport for SiS Touch devices update FW.menu "SiS touchscreen series"
choicedepends on USB_HIDdepends on HID_SIS_CTRLprompt "SiS controller select"config HID_SIS95XX_SIS98XXdepends on HID_SIS_CTRLtristate "SiS 95xx and 98xx series Touch Device"helpSupport for SiS Touch devices that are fully compliant with HID standard.config HID_SIS92XXdepends on HID_SIS_CTRLtristate "SiS 92xx series Touch Device"helpSupport for SiS Touch devices that are fully compliant with HID standard.endchoiceconfig DEBUG_HID_SIS_UPDATE_FWbool "SiS Touch device update firmware support debug message enable"depends on HID_SIS_CTRLdefault nhelpSay Y here if you want to enable debug message offirmware updating for SiS Touchdevices.endmenu
#/  SiSdrv End  /

d. 内核中加载驱动

kernel/arch/arm64/configs/rockchip_defconfig:CONFIG_HID_SIS95XX_SIS98XX=m

三,系统配置

1.授予sis节点权限

diff --git a/system/core/rootdir/ueventd.rc b/system/core/rootdir/ueventd.rc
index 451f5adf33..28c3d83eb7 100644
--- a/system/core/rootdir/ueventd.rc
+++ b/system/core/rootdir/ueventd.rc
@@ -40,6 +40,10 @@ subsystem sound
/dev/pmsg0                0222   root       log
+#sis device SiS95xx
+/dev/sis_hydra_hid_touch_device 0666 root root
+/dev/sis_hydra_hid_bridge_touch_device 0666 root root
+
# kms driver for drm based gpu
/dev/dri/*                0666   root       graphics

2. idc文件拷贝到 系统system/usr/idc/目录

rc文件中添加:

PRODUCT_COPY_FILES += \device/rockchip/rk3399/Vendor_0457_Product_0819.idc:system/usr/idc/Vendor_0457_Product_0819.idc
Vendor_0457_Product_0819.idc:# Basic Parameters
touch.deviceType = touchScreen
touch.orientationAware = 1
device.internal = 1

四,调试

1.dmesg日志

dmesg | grep sis //检查sis驱动程序加载

在这里插入图片描述

2.设备节点

ls -l /dev/sis*

在这里插入图片描述

cat /proc/bus/input/devices

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/759279.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练

这里写目录标题 一、colmap解算数据放入高斯1. 将稀疏重建的文件放入高斯2. 将稠密重建的文件放入高斯 二、vkitti数据放入高斯 一、colmap解算数据放入高斯 运行Colmap.bat文件之后&#xff0c;进行稀疏重建和稠密重建之后可以得到如下文件结构。 1. 将稀疏重建的文件放入高…

线段树优化dp

abc339 E - Smooth Subsequence 思路&#xff1a;我们很容想到一个 n n n方的的状态转移方程&#xff0c;即对于每个i&#xff0c;我们去枚举 1 1 1到 i − 1 i-1 i−1的状态&#xff0c;即 d p [ i ] m a x ( d p [ i ] , d p [ j ] 1 ) ; dp[i]max(dp[i],dp[j]1); dp[i]ma…

异常:程序出现的问题

目的&#xff1a;为了以后发现异常后怎么去处理 异常的作用

(css)步骤条el-steps区分等待、进行中、完成三种状态的图片

(css)步骤条el-steps区分等待、进行中、完成三种状态的图片 效果&#xff1a; <el-steps :active"active" finish-status"success" class"steps"><el-step title"选择.."></el-step><el-step title"..规则&…

Photoshop 2024让图像处理更智能、更高效@

Photoshop 2024是一款功能强大的图像处理软件&#xff0c;广泛应用于创意设计和图像处理领域。它提供了丰富的绘画和编辑工具&#xff0c;包括画笔、铅笔、颜色替换、混合器画笔等&#xff0c;使用户能够轻松进行图片编辑、合成、校色、抠图等操作&#xff0c;实现各种视觉效果…

「数据分析」之零基础入门数据挖掘

摘要&#xff1a;对于数据挖掘项目&#xff0c;本文将学习应该从哪些角度分析数据&#xff1f;如何对数据进行整体把握&#xff0c;如何处理异常值与缺失值&#xff0c;从哪些维度进行特征及预测值分析&#xff1f; 探索性数据分析&#xff08;Exploratory Data Analysis&#…

Mysql——基础命令集合

目录 前期准备 先登录数据库 一、管理数据库 1.数据表结构解析 2.常用数据类型 3.适用所有类型的修饰符 4.使用数值型的修饰符 二、SQL语句 1.SQL语言分类 三、Mysql——Create,Show,Describe,Drop 1.创建数据库 2.查看数据库 3.切换数据库 4.创建数据表 5.查看…

模型部署 - onnx的导出和分析 - onnx 的架构和 onnx helper 的使用 - 学习记录

onnx 的架构和 onnx helper 的使用 简介一、onnx 的架构二、onnx 实践2.1、 create - linear.onnx2.1.1、要点一&#xff1a;创建节点2.1.2、要点二&#xff1a;创建张量2.1.3、要点三&#xff1a;创建图 2.2、 create - onnx.convnet2.3、使用 onnx helper 导出的基本流程总结…

理解数据库习题

1.选择 &#xff08;1&#xff09;现实世界中客观存在并能相互区别的事物称为&#xff08; &#xff09;。 A.实体 B.实体集 C字段 D 记录 &#xff08;2&#xff09;下列实体类型的联系中&#xff0c;属于一对一联系的是&#xff08; &#xff09;A.教研室对教师的所属联系 …

[BT]BUUCTF刷题第2天(3.20)

第2天&#xff08;共5题&#xff09; Web [ACTF2020 新生赛]Exec Payload&#xff1a;target127.0.0.1;cat /flag 分号;在许多shell中用作命令分隔符&#xff0c;意味着在执行完前一个命令&#xff08;这里是设置target变量&#xff09;后&#xff0c;接着执行cat /flag命令…

企业工商年报注册注销商标注册异常处理小程序开源版开发

企业工商年报注册注销商标注册异常处理小程序开源版开发 1、独立业务模型包括&#xff1a;企业工商年报、企业工商登记注册、企业注销登记、企业异常处理。 2、通用业务模型适合各种业务&#xff0c;比如&#xff1a;商标注册代理、财务会计服务、企业版权登记登。 当然&…

从深度伪造到恶意软件:网络安全迎来AI新挑战

如今&#xff0c;有越来越多的恶意行为者开始利用AI大语言模型开发能够绕过 YARA 规则的自我增强型恶意软件。 根据近日Recorded Future 发布的一份新报告&#xff1a;AI可以通过增强小型恶意软件变种的源代码来规避基于字符串的 YARA 规则&#xff0c;从而有效降低检测率。 …

这里是一本关于 DevOps 企业级 CI/CD 实战的书籍...

文章目录 &#x1f4cb; 前言&#x1f3af; 什么是 DevOps&#x1f3af; 什么是 CI/CD&#x1f3af;什么是 Jenkins&#x1f9e9; Jenkins 简单案例 &#x1f3af; DevOps 企业级实战书籍推荐&#x1f525; 参与方式 &#x1f4cb; 前言 企业级 CI/CD 实战是一个涉及到软件开发…

Linux CentOS 7.6安装Redis 6.2.6 详细保姆级教程

1、安装依赖 //检查是否有依赖 gcc -v //没有则安装 yum install -y gcc2、下载redis安装包 //进入home目录 cd /home //通过wget下载redis安装包 wget https://download.redis.io/releases/redis-6.2.6.tar.gz //解压安装包 tar -zxvf redis-6.2.6.tar.gz3、编译 //进入解压…

【Linux】如何使用git命令行与远程仓库建立连接(以Gitee为例)

目录 01.创建仓库 开源 初始化​编辑 设置模版 ​编辑 02.下载仓库到本地 03.提交贡献到远程仓库 01.创建仓库 首先在Gitee网站上登录你的账户&#xff0c;并创建一个新的仓库&#xff0c;输入仓库名称后就会自动生成仓库路径 开源 可以选择你的仓库是否开源。 开源仓…

企业如何选择一个开源「好」项目?

开源 三句半 oss-roast 需求明确是关键 风险考量要周全 开源虽好不白捡 别忘合规&#xff01; 显然&#xff0c;开源已成为一股不可阻挡的洪流&#xff0c;企业拥抱开源&#xff0c;积极参与开源项目不仅是响应技术潮流的必然选择&#xff0c;更是实现自身技术创新、市场拓展等…

AI开源概览及工具使用

一、前言 随着ChatGPT热度的攀升&#xff0c;越来越多的公司也相继推出了自己的AI大模型&#xff0c;如文心一言、通义千问等。各大应用也开始内置AI玩法&#xff0c;如抖音的AI特效&#xff1b; 关联资源&#xff1a;代码 GitHub、相关论文、项目Demo、产品文档、Grok Ai、gr…

【算法】雪花算法生成分布式 ID

SueWakeup 个人中心&#xff1a;SueWakeup 系列专栏&#xff1a;学习Java框架 个性签名&#xff1a;人生乏味啊&#xff0c;我欲令之光怪陆离 本文封面由 凯楠&#x1f4f7; 友情赞助播出! 目录 1. 什么是分布式 ID 2. 分布式 ID 基本要求 3. 数据库主键自增 4. UUID 5. S…

【高频SQL (进阶版)】1398.购买了产品A和产品B却没有购买产品C的顾客Plus

思路&#xff1a; 思路1&#xff1a;买了A&#xff0c;买了B&#xff0c;没有买C。 按人分组统计&#xff0c;A的数>0, B的数>0 ,C的数 0。 思路2&#xff1a;反过来查&#xff0c;用户id。在产品表里,产品名为A&#xff0c;为B的用户列表里&#xff0c;但是不在产品…

ab (Apache benchmark) - 压力/性能测试工具

Apache benchmark&#xff08;ab&#xff09; 安装window安装使用方法 - bin目录运行使用方法 - 任意目录运行 linux安装 基本命令介绍常用参数:输出结果分析&#xff1a; ab的man手册 安装 window安装 官网下载链接&#xff1a;https://www.apachehaus.com/cgi-bin/download…