郭泰FT5406觸控式螢幕驅動
1.首先,分析下FT5406的基本電路介面
- External Interface
- I2C/SPI: an interface for data exchange with host
- INT: an interrupt signal to inform the host processor that touch data is ready for read
- WAKE: an interrupt signal for the host to change F5x06 from Hibernate to Active mode
-
/RST: an external low signal reset the chip.
WAKE:主要靠cpu傳送一個喚醒指令給FT5406。
INT:GPIO0_A2。
/RST:復位,先輸出低後輸出高電平。
2.需確認FT5406的從地址,以便於I2C訪問得到。這個可以根據FT5406資料手冊查詢到——0x38
首先配置 i2c_board_info,把從地址提供過去。
i2c_board_info用於構建資訊表來列出存在的I2C裝置。這一資訊用於增長新型I2C驅動的驅動模型樹。對於主機板,它使用i2c_register_board_info()來靜態建立。對於子板,利用已知的介面卡使用i2c_new_device()動態建立。
//I2C 裝置建立模板
-
//mach-rk29/board-rk29-ddr3sdk.c
- struct i2c_board_info {
- char type[I2C_NAME_SIZE]; //晶片型別,用於初始化i2c_client.name
- unsigned short flags; //用於初始化i2c_client.flags
- unsigned short addr; //儲存於i2c_client.addr
- void *platform_data; //儲存於i2c_client.dev.platform_data
-
struct dev_archdata *archdata; //拷貝至i2c_client.dev.archdata
- int irq; //儲存於i2c_client.irq
- };
//使用Linux I2C驅動棧,系統可以在初始化時宣告板載資訊表。這些應該在靠近arch_initcall()時的板子相關的初始化程式碼或同等情況時,在I2C介面卡驅動被註冊之前被執行。例如,主機板初始化程式碼可以定義幾個裝置,也可以在疊板的每個子板初始化程式碼中定義。
//I2C裝置會在相關的匯流排介面卡被註冊後建立。此後,標準驅動模型工具通常繫結新型I2C驅動至I2C裝置。對於使用這一函式宣告的裝置,在動態分配的情況下匯流排號是不可用的。
//傳遞的板子資訊可以安全的是__initdata,但是由於不能拷貝,要小心嵌入式指標(如platform_data,functions等)
//靜態的宣告I2C裝置
在你對應的machine配置裡會執行“i2c_register_board_info”一個函式,它會將一個i2c_board_info的結構體註冊進系統,可以發現,在目錄/sys/bus/i2c/devices下的裝置就是這個i2c_board_info結構體裡所描述的I2C裝置,而/sys/bus/i2c/devices下的裝置名字就是根據i2c_board_info結構體中定義的I2C Address來命名的。
所以新增一個I2C裝置時,除了需要編寫這個I2C裝置的驅動之外,還需要在machine裡面加入I2C裝置的i2c_board_info內容。
- int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len);
- @busnum: 指定這些裝置屬於哪個匯流排
- @info: I2C裝置描述符向量
- @len: 向量中描述符的數量;為了預留特定的匯流排號,可以是0。
- i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
- static struct i2c_board_info __initdata board_i2c0_devices[] = {
- #if defined (CONFIG_TOUCHSCREEN_FT5406)
- {
- .type ="ft5x0x_ts",
- .addr = 0x38, //0x70,
- .flags =0,
- .irq =RK29_PIN0_PA2, // support goodix tp detect, 20110706
- .platform_data = &ft5406_info,
- },
- }
- struct ft5406_platform_data ft5406_info = {
- .init_platform_hw= ft5406_init_platform_hw, // TOUCH_RESET_PIN為輸出,並先置高後置低;TOUCH_INT_PIN為輸入IO。
- .exit_platform_hw= ft5406_exit_platform_hw,
- .platform_sleep = ft5406_platform_sleep,
- .platform_wakeup = ft5406_platform_wakeup,
- };
核心配置項中:
CONFIG_TOUCHSCREEN_FT5406:
\kernel\drivers\input\touchscreen
obj-$(CONFIG_TOUCHSCREEN_FT5406) += ft5x0x_i2c_ts.o
- fts_ts_probe(,)
- pdata->init_platform_hw(); //初始化IO口
- gpio_to_irq(client->irq); //設定IO口為IRQ
- request_irq(_sui_irq_num, fts_ts_irq, GPIOEdgelFalling, client->dev.driver->name, ft5x0x_ts);
- // 中斷號 中斷處理函式 下降沿觸發
- disable_irq(_sui_irq_num); //關中斷
- input_allocate_device(); //分配輸入子系統
- __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); //配置響應的事件型別
- __set_bit(EV_ABS, input_dev->evbit);
- input_set_abs_params(input_dev,
- ABS_MT_POSITION_X, 0, SCREEN_MAX_X/* + SCREEN_BOUNDARY_ADJUST_VALUE*/, 0, 0);
- input_set_abs_params(input_dev,
- ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y/* + SCREEN_BOUNDARY_ADJUST_VALUE*/, 0, 0);
- input_mt_init_slots(input_dev, CFG_MAX_POINT_NUM);
- input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
- input_register_device(input_dev); //註冊輸入裝置
- ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_early_suspend;
- ft5x0x_ts->early_suspend.resume = ft5x0x_ts_late_resume;
- init_timer(&ft5x0x_ts_timer);
- ft5x0x_ts_timer.function = ft5x0x_ts_do_timer; //fts_ts_release();超時未釋放則釋放中斷
- enable_irq(_sui_irq_num);
- irqreturn_t fts_ts_irq(int irq, void *dev_id)
- queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); //具體任務是fts_work_func
- //fts_work_func(,)
- mod_timer(&ft5x0x_ts_timer ,jiffies + 6);
- fts_read_data();
- enable_irq(this_client->irq);