最近接手了一块电阻屏,用了TI的TSC2007进行信号转换。
接口是 I2C, 还有一个中断屏,工作原理比较简单:发送一个8BIT命令(例如读X),然后接收16BIT的返回值。
整个驱动参考了TI的源码 以及 TI社区的讨论。
/*
* drivers/input/touchscreen/tsc2007.c
*
* Copyright (c) 2018 Melo
* Melo Fang <melo.fang@mic.com.tw>
*
* Modified the TSC2007 driver from:
* Copyright (c) 2014 Aprilaire (Research Products Corporation)
* Santhosh Ramani <sr@aprilaire.com>
*
* Using code from:
* - ads7846.c
* Copyright (c) 2005 David Brownell
* Copyright (c) 2006 Nokia Corporation
* - corgi_ts.c
* Copyright (C) 2004-2005 Richard Purdie
* - omap_ts.[hc], ads7846.h, ts_osk.c
* Copyright (C) 2002 MontaVista Software
* Copyright (C) 2004 Texas Instruments
* Copyright (C) 2005 Dirk Behme
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/*
* This code has been modified to pickup falling and rising edge of
* the PENIRQ. Once the falling edge is detected,
* Interrupt is disabled
* Touch is sampled
* And upon PENIRQ release (high) interrupt is re-enabled
tsc2007_xfer(ts, PWRDOWN);
*
* Modified poll-period: to sample delay (because is delays sampling)
*
* Added report-delay: this prevents reporting incorrect touch events
* (picked up during the pen-up event at the time of sampling)
*
* Added initial-delay: adds some delay before the first sample
*
* Technically, polling period is now (report_delay + sample_delay)
*/
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/regulator/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_wakeup.h>
#include <linux/notifier.h>
#include <linux/fb.h>
#include <linux/err.h>
#define PINCTRL_STATE_ACTIVE "pmx_rtp_active"
#define PINCTRL_STATE_SUSPEND "pmx_rtp_suspend"
#define I2C_VTG_MIN_UV **00000
#define I2C_VTG_MAX_UV **00000
#define VDD_MIN_UV **00000
#define VDD_MAX_UV **00000
#define TSC_DRIVER_NAME "tsc2007"
extern struct kobject *rtp_kobj;
static int rtp_cal[7] = {1,0,0,0,1,0,1};
struct tsc2007_dev *misc_ts = NULL;
static bool vcci2c_enabled = false;
static bool vdd_enabled = false;
static bool isSuspend = 0;
static bool cal_mode = 1;
enum _tsc2007_power_control {
POWER_OFF,
POWER_ON,
};
static unsigned int pointx[5] = {*, **, **, **, **};
static unsigned int pointy[12] = {*, ..};
//Use pointx pointy to convert the coord to the key
static int old_key = 0;
#define MAX_RTP_BUTTON_NUM 60
static u32 RTP_BUTTON_MAPPING_KEY[MAX_RTP_BUTTON_NUM] = {
60 个 KEY
};
#define RTP_DEBUG 1
static int m_rtp_debug_mode = RTP_DEBUG;
#define tsc2007_debug_msg(fmt, args...) \
if (m_rtp_debug_mode) \
printk(KERN_WARNING "tsc2007 : [%-18s:%5d]" fmt, \
__func__, __LINE__, ## args);
#define tsc2007_printk(fmt, args...) \
printk(KERN_WARNING "tsc2007 : [%-18s:%5d]" fmt, \
__func__, __LINE__, ## args);
#define tsc2007_err(fmt, args...) \
printk(KERN_ERR "tsc2007 : [%-18s:%5d]" fmt, \
__func__, __LINE__, ## args);
static ssize_t tsc2007_vendor_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_chipvendor_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_chip_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_interface_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_power_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_calibration_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_enable_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_enable_store(struct device *dev, struct device_attribute *attr,const char *buf,size_t count);
static ssize_t tsc2007_calmode_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_calmode_store(struct device *dev, struct device_attribute *attr,const char *buf,size_t count);
static ssize_t tsc2007_debug_show(struct device *dev, struct device_attribute *attr,char *buf);
static ssize_t tsc2007_debug_store(struct device *dev, struct device_attribute *attr,const char *buf,size_t count);
static DEVICE_ATTR(vendor, S_IRUGO, tsc2007_vendor_show, NULL);
static DEVICE_ATTR(chipvendor, S_IRUGO, tsc2007_chipvendor_show, NULL);
static DEVICE_ATTR(chip, S_IRUGO, tsc2007_chip_show, NULL);
static DEVICE_ATTR(interface, S_IRUGO, tsc2007_interface_show, NULL);
static DEVICE_ATTR(power, S_IRUGO, tsc2007_power_show, NULL);
static DEVICE_ATTR(calibration, S_IRUGO, tsc2007_calibration_show, NULL);
static DEVICE_ATTR(enable, S_IRUGO|S_IWUGO, tsc2007_enable_show, tsc2007_enable_store);
static DEVICE_ATTR(calmode, S_IRUGO|S_IWUGO, tsc2007_calmode_show, tsc2007_calmode_store);
static DEVICE_ATTR(debug, S_IRUGO|S_IWUGO, tsc2007_debug_show, tsc2007_debug_store);
static struct attribute * tsc2007_touch_prop_attrs[] = {
&dev_attr_vendor.attr,
&dev_attr_chipvendor.attr,
&dev_attr_chip.attr,
&dev_attr_interface.attr,
&dev_attr_power.attr,
&dev_attr_calibration.attr,
&dev_attr_enable.attr,
&dev_attr_calmode.attr,
&dev_attr_debug.attr,
NULL
};
static struct attribute_group tsc2007_touch_prop_attr_group = {
.attrs = tsc2007_touch_prop_attrs,
};
struct ts_event {
u16 x;
u16 y;
u16 z1, z2;
};
struct tsc2007_dev {
struct input_dev *input;
char phys[32];
struct i2c_client *client;
u16 model;
u16 x_plate_ohms;
u16 max_rt;
unsigned long sample_delay;
unsigned long report_delay;
unsigned long initial_delay;
int fuzzx;
int fuzzy;
int fuzzz;
unsigned gpio;
int irq;
wait_queue_head_t wait;
bool stopped;
int (*get_pendown_state)(struct device *);
void (*clear_penirq)(void);
struct notifier_block fb_notif;
struct regulator *vcc_i2c;
struct regulator *vdd;
struct pinctrl *rtp_pinctrl;
struct pinctrl_state *pinctrl_state_active;
struct pinctrl_state *pinctrl_state_suspend;
};
/*
//
// _ooOoo_
// o8888888o
// 88" . "88
//