敦泰电容屏芯片FT5X06 IIC参考驱动(1)发布时间:2012-04-18 10:29:43
[cpp] view plaincopyprint?
static void ft5x0x_ts_release(void)
{
struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);
#ifdef FT5X0X_MULTI_TOUCH
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_key(data->input_dev, BTN_TOUCH, 0);
#else
input_report_abs(data->input_dev, ABS_PRESSURE, 0);
input_report_key(data->input_dev, BTN_TOUCH, 0);
#endif
input_sync(data->input_dev);
}
static int ft5x0x_read_data(void)
{
struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);
struct ts_event *event = &data->event;
u32 buf[32] = {0};
int ret = -1;
#ifdef FT5X0X_MULTI_TOUCH
ret = ft5x0x_i2c_rxdata(buf, 31);
#else
ret = ft5x0x_i2c_rxdata(buf, 7);
#endif
if (ret < 0) {
printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
}
memset(event, 0, sizeof(struct ts_event));
event->touch_point = buf[2] & 0x07;
if (event->touch_point == 0) {
ft5x0x_ts_release();
return 1;
}
#ifdef FT5X0X_MULTI_TOUCH
switch (event->touch_point) {
case 5:
event->x5 = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c];
event->y5 = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e];
case 4:
event->x4 = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16];
event->y4 = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18];
case 3:
event->x3 = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10];
event->y3 = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12];
case 2:
event->x2 = (s16)(buf[9] & 0x0F)<<8 | (s16)buf[10];
event->y2 = (s16)(buf[11] & 0x0F)<<8 | (s16)buf[12];
case 1:
event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
break;
default:
return -1;
}
#else
if (event->touch_point == 1) {
event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
}
#endif
event->pressure = 200;
return 0;
}
static void ft5x0x_reprot_value(void)
{
struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);
struct ts_event *event = &data->event;
#ifdef FT5X0X_MULTI_TOUCH
switch(event->touch_point) {
case 5:
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x5);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y5);
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, event->pressure);
input_mt_sync(data->input_dev);
case 4:
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x4);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y4);
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, event->pressure);
input_mt_sync(data->input_dev);
case 3:
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x3);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y3);
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, event->pressure);
input_mt_sync(data->input_dev);
case 2:
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x2);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y2);
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, event->pressure);
input_mt_sync(data->input_dev);
case 1:
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1);
input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, event->pressure);
input_mt_sync(data->input_dev);
break;
default:
break;
}
#else
if (event->touch_point == 1) {
input_report_abs(data->input_dev, ABS_X, event->x1);
input_report_abs(data->input_dev, ABS_Y, event->y1);
input_report_abs(data->input_dev, ABS_PRESSURE, event->pressure);
}
input_report_key(data->input_dev, BTN_TOUCH, 1);
#endif
input_sync(data->input_dev);
//摘自:http://blog.csdn.net/sunsea1026/article/details/7415803
static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
{
int ret = -1;
ret = ft5x0x_read_data();
if (ret == 0)
ft5x0x_report_value();
}
static interrupt_r ft5x0x_ts_interrupt(int irq, void *dev_id)
{
struct ft5x0x_ts_data *ft5x0x_ts = dev_id;
if (!work_pending(&ft5x0x_ts->pen_irq_work))
queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_irq_work);
return IRQ_HANDLED;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ft5x0x_ts_suspend(struct early_suspend *handler)
{
struct ft5x0x_ts_data *ft5x0x_ts;
ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);
disable_irq(this_client->irq);
cancel_workqueue(ft5x0x_ts->pen_irq_work);
flush_workqueue(ft5x0x_ts->ts_workqueue);
ft5x0x_write_reg(FT5X0X_REG_PMODE, PMODE_MONITOR);
printk("[FST] %s\n", __func__);
}
static void ft5x0x_ts_resume(struct early_suspend *handler)
{
ventana_touchscreen_reset();
enable_irq(this_client->irq);
ft5x0x_write_reg(FT5X0X_REG_PMODE, PMODE_ACTIVE);
printk("[FST] %s\n", __func__);
}
#endif
static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id, *id)
{
int err = 0;
struct ft5x0x_ts_data *ft5x0x_ts;
struct input_dev *input_dev;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
err = -ENODEV;
goto exit_i2c_check_functionality;
}
ft5x0x_ts = kzalloc(sizeof(ft5x0x_ts_data), GPL_KERNEL);
if (!ft5x0x_ts) {
err = -ENOMEM;
goto exit_alloc_data;
}
this_client = client;
i2c_set_clientdata(client, ft5x0x_ts);
INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
ft5x0x_ts->ts_workqueue = create_siglethread_workqueue(dev_name(&client->dev));
if (!ft5x0x_ts->ts_workqueue) {
err = -ESRCH;
goto exit_create_siglethread;
}
err = request_irq(client->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING, "ft5x0x-irq", ft5x0x_ts);
if (err < 0) {
dev_err(&client->dev, "ft5x0x_ts_probe: request irq failed\n");
goto exit_irq_request;
}
disable_irq(this_client-irq);
input_dev = input_allocate_device();
if (!input_dev) {
err = -ENOMEM;
dev_err(&client-dev, "ft5x0x_ts_probe: failed alloc input device\n");
}
ft5x0x_ts->input_dev = input_dev;
input_dev->name = FT5X0X_NAME;
set_bit(EV_ABS, input_dev->evbit);
set_bit(EV_KEY, input_dev->evbit);
set_bit(BTN_TOUCH, input_dev->keybit);
#ifdef FT5X0X_MULTI_TOUCH
set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
set_bit(ABS_MT_POSITION_X, input_dev->absbit);
set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
#else
set_bit(ABS_X, input_dev->absbit);
set_bit(ABS_Y, input_dev->absbit);
set_bit(ABS_PRESSURE, input_dev->absbit);
set_bit(BTN_TOUCH, input_dev->keybit);
input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);
err = input_register_device(input_dev);
if (err) {
dev_err(&client->dev, "ft5x0x_ts_probe: failed to register input device: %s\n",
dev_name(&client->dev));
goto exit_input_register_device;
}
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_suspend;
ft5x0x_ts->early_suspend.resume = ft5x0x_ts_resume;
register_early_suspend(ft5x0x_ts->early_suspend);
#endif
msleep(50);
//Get some register information
uc_reg_value = ft5x0x_read_fw_ver();
printk("[FST] Firmware version = 0x%sx\n", uc_reg_value);
//Auto calibration
err = ft5x0x_write_reg(CALIBRATION_REG, 0x00);
if (err)
printk("[FST] Auto calibration failed.\n");
else
printk("[FST] Auto calibration successfully.\n");
//Config the run mode of TPM, reg - 0xa7 : auto calibration - 0x04
ft5x0x_write_reg(FT5X0X_REG_STATE, 0x00);
printk("[FST] Auto calibration during running.\n");
enable_irq(this_client->irq);
return 0;
exit_input_register_device:
input_free_device(input_dev);
exit_alloc_data:
free_irq(client->irq, ft5x0x_ts);
exit_irq_request:
exit_create_siglethread:
i2c_set_clientdata(client, NULL);
exit_alloc_data:
exit_i2c_check_functionality:
return err;
}
static int __devexit ft5x0x_ts_remove(struct i2c_client *client)
{
struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&ft5x0x_ts->early_suspend);
#endif
free_irq(client->irq, ft5x0x_ts);
input_unregister_device(ft5x0x_ts->input_dev);
kfree(ft5x0x_ts);
cancel_work_sync(&ft5x0x_ts->pen_event_work);
destroy_workqueue(ft5x0x_ts->ts_workqueue);
i2c_set_cleintdata(client, NULL);
return 0;
}
static const struct i2c_device_id ft5x0x_ts_id[] = {
{FT5X0X_NAME, 0}
};
MODULE_DEVICE_TABLE(i2c, ft5x0x_id);
static struct i2c_driver ft5x0x_ts_driver = {
.probe = ft5x0x_ts_probe,
.remove = __devexit_p(ft5x0x_ts_remove),
.id_table = ft5x0x_ts_id,
.driver = {
.name = FT5X0X_TS,
.owner = THIS_MODULE,
},
};
static int __init ft5x0x_ts_init(void)
{
int ret;
ret = i2c_add_driver(&ft5x0x_ts_driver);
return ret;
}
static void __exit ft5x0x_ts_exit(void)
{
i2c_delete_driver(&ft5x0x_ts_driver);
}
module_init(ft5x0x_ts_init);
module_exit(ft5x0x_ts_exit);
/* drivers/input/touchscreen/ft5x06_i2c_ts.c
*
* Copyright (C) 2010 Pixcir, Inc.
*
* ft5x06_i2c_ts.c V1.0 support multi touch
* ft5x06_i2c_ts.c V1.5 add Calibration function:
*
* CALIBRATION_FLAG 1
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "ft5x06_i2c_ts.h"
#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "Sunyard"
#define DRIVER_DESC "Ft5x06 I2C Touchscreen Driver with tune fuction"
#define DRIVER_LICENSE "GPL"
struct input_dev *keyboard = NULL;
EXPORT_SYMBOL(keyboard);
#define FT5X06_DEBUG 0
#define SLAVE_ADDR 0x38
#ifndef I2C_MAJOR
#define I2C_MAJOR 125
#endif
#define I2C_MINORS 256
#define CALIBRATION_FLAG 1
int tsp_keycodes[4] ={
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7
};
static unsigned char status_reg = 0;
struct i2c_dev
{
struct list_head list;
struct i2c_adapter *adap;
struct device *dev;
};
static struct i2c_driver ft5x06_i2c_ts_driver;
static struct class *i2c_dev_class;
static LIST_HEAD( i2c_dev_list);
static DEFINE_SPINLOCK( i2c_dev_list_lock);
static void return_i2c_dev(struct i2c_dev *i2c_dev)
{
spin_lock(&i2c_dev_list_lock);
list_del(&i2c_dev->list);
spin_unlock(&i2c_dev_list_lock);
kfree(i2c_dev);
}
static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
{
struct i2c_dev *i2c_dev;
i2c_dev = NULL;
spin_lock(&i2c_dev_list_lock);
list_for_each_entry(i2c_dev, &i2c_dev_list, list)
{
if (i2c_dev->adap->nr == index)
goto found;
}
i2c_dev = NULL;
found: spin_unlock(&i2c_dev_list_lock);
return i2c_dev;
}
static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev;
if (adap->nr >= I2C_MINORS)
{
printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n",
adap->nr);
return ERR_PTR(-ENODEV);
}
i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return ERR_PTR(-ENOMEM);
i2c_dev->adap = adap;
spin_lock(&i2c_dev_list_lock);
list_add_tail(&i2c_dev->list, &i2c_dev_list);
spin_unlock(&i2c_dev_list_lock);
return i2c_dev;
}
/*********************************V2.0-Bee-0928-BOTTOM****************************************/
static struct workqueue_struct *ft5x06_wq;
struct ft5x06_i2c_ts_data
{
struct i2c_client *client;
struct input_dev *input;
struct delayed_work work;
int irq;
};
static void ft5x06_ts_poscheck(struct work_struct *work)
{
struct ft5x06_i2c_ts_data *tsdata = container_of(work,
struct ft5x06_i2c_ts_data,
work.work);
int touch_event;
int posx1, posy1;
unsigned char Rdbuf[7],auotpnum[1],Wrbuf[1];
static int key_id=0x80;
int i,ret;
Wrbuf[0] = 0;
ret = i2c_master_send(tsdata->client, Wrbuf, 1);
#if FT5X06_DEBUG
printk("master send ret:%d\n",ret);
#endif
if (ret != 1)
{
#if FT5X06_DEBUG
dev_err(&tsdata->client->dev, "Unable to write to i2c touchscreen!\n");
#endif
goto out;
}
ret = i2c_master_recv(tsdata->client, Rdbuf, sizeof(Rdbuf));
if (ret != sizeof(Rdbuf))
{
dev_err(&tsdata->client->dev, "Unable to read i2c page!\n");
goto out;
}
posx1 = (( (Rdbuf[3] & 0x0f )<< 8) | Rdbuf[4]);
posy1 = (( (Rdbuf[5] & 0x0f )<< 8) | Rdbuf[6]);
touch_event = Rdbuf[3] & 0xc0;
if (touch_event == 0x80)
{
if (posy1 > 0 && posy1 < 800)
{
input_report_abs(tsdata->input, ABS_X, posx1);
input_report_abs(tsdata->input, ABS_Y, posy1);
input_report_key(tsdata->input, BTN_TOUCH, 1);
input_report_abs(tsdata->input, ABS_PRESSURE, 1);
}
else if(posy1>=840 && posy1<=850 && keyboard)
{
if (posx1 > 45 && posx1 < 51)
{
key_id = 0;
}
else if ( posx1 > 205 && posx1 < 211)
{
key_id = 1;
}
else if (posx1 > 269 && posx1 < 275 )
{
key_id = 2;
}
else if ( posx1 > 397 && posx1 < 403)
{
key_id = 3;
}
input_report_key(keyboard, tsp_keycodes[key_id], 1);
}
}
else if (touch_event == 0x40)
{
if(key_id !=0x80 && keyboard)
{
i=key_id;
for(i=0;i<4;i++);
input_report_key(keyboard, tsp_keycodes[key_id], 0);
key_id=0x80;
}
input_report_key(tsdata->input, BTN_TOUCH, 0);
input_report_abs(tsdata->input, ABS_PRESSURE, 0);
}
input_sync(tsdata->input);
out: enable_irq(tsdata->irq);
}
static irqreturn_t ft5x06_ts_isr(int irq, void *dev_id)
{
struct ft5x06_i2c_ts_data *tsdata = dev_id;
disable_irq_nosync(irq);
queue_work(ft5x06_wq, &tsdata->work.work);
return IRQ_HANDLED;
}
static int ft5x06_i2c_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ft5x06_i2c_ts_data *tsdata;
struct input_dev *input;
struct device *dev;
struct i2c_dev *i2c_dev;
int error;
int ret;
s3c_gpio_cfgpin(S3C64XX_GPK(15), S3C_GPIO_SFN(1));
s3c_gpio_setpull(S3C64XX_GPK(15), S3C_GPIO_PULL_UP);
ret = s3c_gpio_setpin(S3C64XX_GPK(15),1);
udelay(1000);
ret = s3c_gpio_setpin(S3C64XX_GPK(15),0);
udelay(1000);
s3c_gpio_setpin(S3C64XX_GPK(15),1);
tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
if (!tsdata)
{
dev_err(&client->dev, "failed to allocate driver data!\n");
error = -ENOMEM;
goto exit_alloc_data_failed;
}
dev_set_drvdata(&client->dev, tsdata);
input = input_allocate_device();
if (!input)
{
dev_err(&client->dev, "failed to allocate input device!\n");
error = -ENOMEM;
goto exit_input_dev_alloc_failed;
}
set_bit(EV_SYN, input->evbit);
set_bit(EV_KEY, input->evbit);
set_bit(EV_ABS, input->evbit);
set_bit(BTN_TOUCH, input->keybit);
input_set_abs_params(input, ABS_X, TOUCHSCREEN_MINX, TOUCHSCREEN_MAXX, 0, 0);
input_set_abs_params(input, ABS_Y, TOUCHSCREEN_MINY, TOUCHSCREEN_MAXY, 0, 0);
input_set_abs_params(input,ABS_PRESSURE,0,1,0,0);
input->name = client->name;
input->id.bustype = BUS_I2C;
input->dev.parent = &client->dev;
input_set_drvdata(input, tsdata);
tsdata->client = client;
tsdata->input = input;
INIT_WORK(&tsdata->work.work, ft5x06_ts_poscheck);
tsdata->irq = client->irq;
error = input_register_device(input);
if (error){
dev_err(&client->dev, "failed to register input device!\n");
goto exit_input_register_device_failed;
}
error = request_irq(tsdata->irq, ft5x06_ts_isr, IRQF_TRIGGER_FALLING,client->name, tsdata);
if (error)
{
dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
goto exit_irq_request_failed;
}
device_init_wakeup(&client->dev, 1);
/*********************************V2.0-Bee-0928-TOP****************************************/
i2c_dev = get_free_i2c_dev(client->adapter);
if (IS_ERR(i2c_dev))
{
error = PTR_ERR(i2c_dev);
goto out;
}
/*********************************V2.0-Bee-0928-BOTTOM****************************************/
dev_err(&tsdata->client->dev, "insmod successfully!\n");
return 0;
out:
free_irq(tsdata->irq, tsdata);
exit_irq_request_failed:
exit_input_register_device_failed:
input_free_device(input);
exit_input_dev_alloc_failed:
kfree(tsdata);
exit_alloc_data_failed:
return error;
}
static int ft5x06_i2c_ts_remove(struct i2c_client *client)
{
int error;
struct i2c_dev *i2c_dev;
struct ft5x06_i2c_ts_data *tsdata = dev_get_drvdata(&client->dev);
free_irq(tsdata->irq, tsdata);
/*********************************V2.0-Bee-0928-TOP****************************************/
i2c_dev = get_free_i2c_dev(client->adapter);
if (IS_ERR(i2c_dev))
{
error = PTR_ERR(i2c_dev);
return error;
}
return_i2c_dev(i2c_dev);
device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, client->adapter->nr));
/*********************************V2.0-Bee-0928-BOTTOM****************************************/
input_unregister_device(tsdata->input);
kfree(tsdata);
dev_set_drvdata(&client->dev, NULL);
return 0;
}
static int ft5x06_i2c_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
struct ft5x06_i2c_ts_data *tsdata = dev_get_drvdata(&client->dev);
disable_irq(tsdata->irq);
return 0;
}
static int ft5x06_i2c_ts_resume(struct i2c_client *client)
{
struct ft5x06_i2c_ts_data *tsdata = dev_get_drvdata(&client->dev);
enable_irq(tsdata->irq);
return 0;
}
static const struct i2c_device_id ft5x06_i2c_ts_id[] =
{
{ "ft5x06", 0 },
{ }
};
MODULE_DEVICE_TABLE( i2c, ft5x06_i2c_ts_id);
static struct i2c_driver ft5x06_i2c_ts_driver =
{ .driver =
{
.owner = THIS_MODULE,
.name = "ft5x06_i2c_ts_driver",
},
.probe = ft5x06_i2c_ts_probe,
.remove = ft5x06_i2c_ts_remove,
.suspend = ft5x06_i2c_ts_suspend,
.resume = ft5x06_i2c_ts_resume,
.id_table = ft5x06_i2c_ts_id,
};
static int __init ft5x06_i2c_ts_init(void)
{
int ret;
ft5x06_wq = create_singlethread_workqueue("ft5x06_wq");
if(!ft5x06_wq)
return -ENOMEM;
i2c_dev_class = class_create(THIS_MODULE, "ft5x06_i2c_dev");
if (IS_ERR(i2c_dev_class))
{
ret = PTR_ERR(i2c_dev_class);
class_destroy(i2c_dev_class);
}
/********************************V2.0-Bee-0928-BOTTOM******************************************/
return i2c_add_driver(&ft5x06_i2c_ts_driver);
}
static void __exit ft5x06_i2c_ts_exit(void)
{
i2c_del_driver(&ft5x06_i2c_ts_driver);
/********************************V2.0-Bee-0928-TOP******************************************/
class_destroy(i2c_dev_class);
unregister_chrdev(I2C_MAJOR,"ft5x06_i2c_ts");
/********************************V2.0-Bee-0928-BOTTOM******************************************/
if(ft5x06_wq)
destroy_workqueue(ft5x06_wq);
}
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
module_init( ft5x06_i2c_ts_init);
module_exit( ft5x06_i2c_ts_exit);
/*****************touchscreen resolution setting*************/
#define R8C_3GA_2TG
//#define R8C_AUO_I2C
#ifdef R8C_AUO_I2C
#ifndef R8C_3GA_2TG
#define R8C_3GA_2TG
#endif
#endif
#define TOUCHSCREEN_MINX 0
#define TOUCHSCREEN_MAXX 800
#define TOUCHSCREEN_MINY 0
#define TOUCHSCREEN_MAXY 480
本文来源:https://www.2haoxitong.net/k/doc/d5b31bdfce2f0066f53322bd.html
文档为doc格式