tsc2007是个多功能电阻触摸屏, 具有12bit精度的电阻屏A/D装换器, 压力传感器, 温度传感器等功能.
根据不同的触摸屏尺寸,可以支持8bit和12bit精度的转换.
支持I2C接口, 一个中断输出引脚, 中断输出低电平.
内部结构框图如下:
1. tsc2007 结构体定义:
struct tsc2007 {
struct input_dev *input;
char phys[32];
struct delayed_work work;
struct i2c_client *client;
u16 model;
u16 x_plate_ohms;
bool pendown;
int irq;
int (*get_pendown_state)(void);
void (*clear_penirq)(void);
};
因为是input设备,所以肯定会有 input_dev 指针。
这里由于中断使用workqueue 下半部机制,所以才会有 delayed_work。
因为是一个i2c设备,所以肯定会有代表i2c设备的i2c_client.
irq 是该设备的中断输出用的中断号。
不知道 model, x_plate_ohms 和pendown是干啥用的。
2. module init:
static const struct i2c_device_id tsc2007_idtable[] = {
{ "tsc2007", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
static struct i2c_driver tsc2007_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tsc2007"
},
.id_table = tsc2007_idtable,
.probe = tsc2007_probe,
.remove = __devexit_p(tsc2007_remove),
};
static int __init tsc2007_init(void)
{
return i2c_add_driver(&tsc2007_driver);
}
static void __exit tsc2007_exit(void)
{
i2c_del_driver(&tsc2007_driver);
}
module_init(tsc2007_init);
module_exit(tsc2007_exit);
这里用 i2c_add_driver() 来添加tsc2007_driver,就相当于把i2c_driver注册进I2C bus,
还会把tsc2007_idtable 添加进 i2c_device id_table 中。
3. tsc2007_probe:
static int __devinit tsc2007_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tsc2007 *ts;
struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data;
struct input_dev *input_dev;
int err;
void __iomem *cpld_base;
unsigned short reg;
cpld_base = ioremap(CPLD_BASE_ADDR, 64);
if(!cpld_base) {
dev_err(&client->dev, "map cpld base failed!\n");
return -ENOMEM;
}
reg = __raw_readw(cpld_base + CNTL_REG1);
reg &= ~TP_POWER;
__raw_writew(reg, cpld_base + CNTL_REG1);
mdelay(500);
reg |= TP_POWER;
__raw_writew(reg, cpld_base + CNTL_REG1);
if (!pdata) {
dev_err(&client->dev, "platform data is required!\n");
return -EINVAL;
}
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -EIO;
ts = kzalloc(sizeof(stru