233 lines
4.7 KiB
C
233 lines
4.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/interrupt.h>
|
|
|
|
#include "vtl_ts.h"
|
|
#include "chip.h"
|
|
|
|
#define APK_ITOUCH 0x01
|
|
|
|
#define INVALID 0x00
|
|
#define HW_RESET_CMD 0x01
|
|
#define CHIP_INFO_CMD 0x02
|
|
#define DRIVER_INFO_CMD 0x03
|
|
#define CHIP_ID_CMD 0x04
|
|
#define WRITE_CHIP_CMD 0x05
|
|
#define READ_CHIP_CMD 0x06
|
|
#define RECOVERY_CMD 0x07
|
|
#define INTERRUPT_CMD 0x08
|
|
#define READ_CHECKSUM_CMD 0x09
|
|
#define READ_FWCHECKSUM_CMD 0x0a
|
|
#define XY_DEBUG_CMD 0x0b
|
|
|
|
|
|
#define LINUX_SHELL 'c'
|
|
#define SHELL_CHECKSUM_CMD '1'
|
|
#define SHELL_UPDATE_CMD '2'
|
|
#define SHELL_DEBUG_CMD '3'
|
|
|
|
|
|
|
|
static struct ts_info * ts_object = NULL;
|
|
|
|
/*****************************************************************************
|
|
** Function define
|
|
*****************************************************************************/
|
|
static int apk_i2c_transfer(struct i2c_client *client,unsigned char i2c_addr,unsigned char len,unsigned char *buf,unsigned char rw)
|
|
{
|
|
struct i2c_msg msgs[1];
|
|
|
|
DEBUG();
|
|
|
|
msgs[0].flags = rw;
|
|
msgs[0].addr = i2c_addr;
|
|
msgs[0].len = len;
|
|
msgs[0].buf = buf;
|
|
//msgs[0].scl_rate = TS_I2C_SPEED; //only for rockchip
|
|
|
|
if(i2c_transfer(client->adapter, msgs, 1)!= 1)
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static int apk_open(struct inode *inode, struct file *file)
|
|
{
|
|
printk("___%s___\n",__func__);
|
|
DEBUG();
|
|
|
|
ts_object = vtl_ts_get_object();
|
|
if(ts_object == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int apk_close(struct inode *inode, struct file *file)
|
|
{
|
|
printk("___%s___\n",__func__);
|
|
DEBUG();
|
|
|
|
return 0;
|
|
}
|
|
static ssize_t apk_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
|
|
{
|
|
struct i2c_client *client = ts_object->driver->client;
|
|
unsigned char frame_data[255] = {0};
|
|
int bin_checksum = 0;
|
|
int fw_checksum = 0;
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
if(copy_from_user(frame_data, buff, count)){
|
|
return -EFAULT;
|
|
}
|
|
|
|
if(frame_data[0]==APK_ITOUCH){
|
|
|
|
switch(frame_data[1]){
|
|
|
|
case HW_RESET_CMD :{
|
|
vtl_ts_hw_reset();
|
|
}break;
|
|
|
|
case INTERRUPT_CMD :{
|
|
if(frame_data[4]){
|
|
enable_irq(ts_object->config_info.irq_number);
|
|
}else{
|
|
disable_irq(ts_object->config_info.irq_number);
|
|
}
|
|
}break;
|
|
|
|
case RECOVERY_CMD :{
|
|
ret = update(client);
|
|
}break;
|
|
|
|
case WRITE_CHIP_CMD:{
|
|
ret = apk_i2c_transfer(client,frame_data[2],frame_data[3],&frame_data[4],0);
|
|
}break;
|
|
|
|
case XY_DEBUG_CMD :{
|
|
if(ts_object->debug){
|
|
ts_object->debug = 0x00;
|
|
}else{
|
|
ts_object->debug = 0x01;
|
|
}
|
|
}break;
|
|
|
|
default :{
|
|
|
|
}break;
|
|
}
|
|
}else if(frame_data[0]==LINUX_SHELL){
|
|
printk("CMD: %s,count = %zu\n",frame_data,count);
|
|
switch(frame_data[1]){
|
|
case SHELL_CHECKSUM_CMD :{
|
|
chip_get_checksum(client,&bin_checksum,&fw_checksum);
|
|
printk("bin_checksum = 0x%x,fw_checksum = 0x%x\n",bin_checksum,fw_checksum);
|
|
}break;
|
|
|
|
case SHELL_UPDATE_CMD :{
|
|
chip_update(client);
|
|
}break;
|
|
|
|
case SHELL_DEBUG_CMD :{
|
|
if(ts_object->debug){
|
|
ts_object->debug = 0x00;
|
|
}else{
|
|
ts_object->debug = 0x01;
|
|
}
|
|
|
|
}break;
|
|
|
|
default :{
|
|
|
|
}break;
|
|
}
|
|
}else{
|
|
return -1;
|
|
}
|
|
if(ret<0){
|
|
return -1;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
static ssize_t apk_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
|
|
{
|
|
struct i2c_client *client = ts_object->driver->client;
|
|
unsigned char frame_data[255];
|
|
int bin_checksum = 0;
|
|
int fw_checksum = 0;
|
|
int len = 0;
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
if(copy_from_user(frame_data, buff, count))
|
|
{
|
|
return -EFAULT;
|
|
}
|
|
|
|
len = frame_data[3];
|
|
if(frame_data[0]==APK_ITOUCH){
|
|
|
|
switch(frame_data[1]){
|
|
case DRIVER_INFO_CMD :{
|
|
frame_data[0] = client->addr;
|
|
}break;
|
|
|
|
case READ_CHIP_CMD :{
|
|
|
|
ret = apk_i2c_transfer(client,frame_data[2],frame_data[3],frame_data,1);
|
|
}break;
|
|
|
|
case READ_CHECKSUM_CMD :{
|
|
ret = chip_get_checksum(client,&bin_checksum,&fw_checksum);
|
|
frame_data[0] = bin_checksum & 0x00ff;
|
|
frame_data[1] = bin_checksum >> 8;
|
|
frame_data[2] = fw_checksum & 0x00ff;
|
|
frame_data[3] = fw_checksum >> 8;
|
|
}break;
|
|
case READ_FWCHECKSUM_CMD :{
|
|
ret = chip_get_fwchksum(client,&fw_checksum);
|
|
frame_data[0] = fw_checksum & 0x00ff;
|
|
frame_data[1] = fw_checksum >> 8;
|
|
}break;
|
|
|
|
default :{
|
|
|
|
}break;
|
|
}
|
|
}
|
|
|
|
if(copy_to_user(buff, frame_data,len)){
|
|
return -EFAULT;
|
|
}
|
|
if(ret<0){
|
|
return -1;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
struct file_operations apk_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = apk_open,
|
|
.release = apk_close,
|
|
.write = apk_write,
|
|
.read = apk_read,
|
|
};
|
|
|