Transferred from http://m.blog.csdn.net/article/details?id=51362009
This blog post will explain the TP driver based on the Goodix touch chip. If there are deficiencies, please point out. Initialization of
static int __init tpd_driver_init (void)
{
gtp_info ("MediaTek gt91xx touch Panel driver init\n");
#if defined (tpd_i2c_number)
i2c_register_board_info (Tpd_i2c_number, &I2C_TPD, 1);
#else
i2c_register_board_info (0, &I2C_TPD, 1);
#endif
if (Tpd_driver_add (&tpd_device_driver) < 0)
gtp_info ("Add generic Driver failed\n");
return 0;
}
There are two main things to do in Tpd_driver_init:
1, register a I2C equipment
I2c_register_board_info is defined in KERNEL\DRIVERS\I2C\I2C-BOARDINFO.C.
The corresponding function describes the following:
I2c_register_board_info-statically Declare I2C devices
* @busnum: Identifies to which devices belong
* @info: Vector of I2C device descriptors
* @len: How many descriptors in the vector; May is zero to reserve
* The specified bus number.
So we can know:
Tpd_i2c_number represents the current registered I2C device is on which bus, you need to see the hardware connection diagram;
I2C_TPD represents the description of the I2C device, including the device name "gt9xx" and I2C's device Address "(0xBA >> 1)"
static struct I2c_board_info __initdata i2c_tpd = {i2c_board_info ("gt9xx", (0xBA >> 1)};
1
2, add a driver to the static array tpd_driver_list array
if (Tpd_driver_add (&tpd_device_driver) < 0)
gtp_info ("Add generic Driver failed\n");
1 2
Where tpd_device_driver is defined as:
static struct tpd_driver_t Tpd_device_driver =
{
. tpd_device_name = "gt9xx",
. Tpd_local_init = Tpd_local_ Init,
. Suspend = Tpd_suspend,
. Resume = Tpd_resume,
#ifdef tpd_have_button
. Tpd_have_button = 1,
#else
. Tpd_have_button = 0,
#endif
};
All of these options are required.
The tpd_device_name cannot be "generic", which would be recognized as R-touch (presumably as a resistive screen) and saved to Tpd_driver_li
St[0]. Otherwise, the C-touch (presumably shown here as a capacitive screen) is saved to the Tpd_driver_list 0 position. All of these functions are implemented by themselves in the TP driver
Content. Tpd_local_init ()
static int tpd_local_init (void) {#if Gtp_esd_protect clk_tick_cnt = 2 * HZ;
Hz:clock ticks in 1 second generated by system Gtp_debug ("clock ticks to an ESD cycle:%d", clk_tick_cnt);
Init_delayed_work (>p_esd_check_work, Gtp_esd_check_func);
Gtp_esd_check_workqueue = Create_workqueue ("Gtp_esd_check"); Spin_lock_init (&esd_lock); 2.6.39 & later//Esd_lock = spin_lock_unlocked;
2.6.39 & before #endif #if gtp_support_i2c_dma tpd->dev->dev.coherent_dma_mask = Dma_bit_mask (32); Gpdmabuf_va = (U8 *) dma_alloc_coherent (&tpd->dev->dev, Gtp_dma_max_transaction_length, &GPDMABUF_PA,
Gfp_kernel);
if (!gpdmabuf_va) {gtp_info ("[Error] Allocate DMA i2c Buffer failed!\n");
} memset (Gpdmabuf_va, 0, gtp_dma_max_transaction_length);
#endif if (I2c_add_driver (&tpd_i2c_driver)!= 0) {gtp_info ("Unable to add I2C driver.\n");
return-1; } if (Tpd_load_status = = 0)//if (tpd_load_status = 0)//disable auto Load Touch driver for linux3.0 porting {gtp_info ("Add Erro
R Touch Panel driver.\n ");
I2c_del_driver (&tpd_i2c_driver);
return-1;
Input_set_abs_params (Tpd->dev, abs_mt_tracking_id, 0, (gtp_max_touch-1), 0, 0); #ifdef Tpd_have_button if (factory_boot = = Get_boot_mode () | | Recovery_boot = = Get_boot_mode ())//Cty 2014-08-14 {tpd_button_setting Tpd_key_count ry, tpd_keys_dim_local);//Initialize TPD button data} else {tpd_button_setting (tpd_key_count, TP D_keys_local, tpd_keys_dim_local)///Initialize TPD button data #endif #if defined (tpd_warp_start) && Defi
Ned (tpd_warp_end)) Tpd_do_warp = 1;
memcpy (Tpd_wb_start, Tpd_wb_start_local, tpd_warp_cnt * 4);
memcpy (Tpd_wb_end, Tpd_wb_start_local, tpd_warp_cnt * 4); #endif #if (defined (tpd_have_calibration) &&!defined (tpd_custom_calibration)) memCPY (Tpd_calmat, tpd_def_calmat_local, 8 * 4);
memcpy (Tpd_def_calmat, tpd_def_calmat_local, 8 * 4);
#endif//Set vendor string Tpd->dev->id.vendor = 0x00;
Tpd->dev->id.product = Tpd_info.pid;
Tpd->dev->id.version = Tpd_info.vid;
Gtp_info ("End%s,%d\n", __function__, __line__);
Tpd_type_cap = 1;
return 0; }
This function mainly does the following work: 1, Gtp_esd_protect
For ESD protection mechanisms. 2, Gtp_support_i2c_dma
The main is to apply for I2C DMA space, directed by Gpdmabuf_va.
Tpd->dev->dev.coherent_dma_mask = Dma_bit_mask (32); Van that represents the physical address that this device addresses
Surround for Dma_bit_mask (32), this value is equivalent to 0xffffffffUL. For an explanation of this member, see Dma_mask and Co in linux Platform_device
Herent_dma_mask. The next dma_alloc_coherent () requests DMA space. The return value is Gpdmabuf_va representing the virtual address, and returning GP
DMABUF_PA represents the actual physical address of the DMA. As for the two how to use is not very understand. See: Dynamic DMA Mapping using the generic device
3, Registered I2C device driver
if (I2c_add_driver (&tpd_i2c_driver)!= 0)
{
gtp_info ("Unable to add I2C driver.\n");
return-1;
}
if (tpd_load_status = 0)//if (tpd_load_status = = 0)//disable auto Load Touch driver for linux3.0 porting
{
gtp_ INFO ("Add Error Touch panel driver.\n");
I2c_del_driver (&tpd_i2c_driver);
return-1;
}
Probe detects the device on the bus and establishes a connection between the device and the driver to complete the initialization of the device. The middle will call the Tpd_i2c_probe () in Tpd_i2c_driver to complete the initialization work.
static struct I2c_driver Tpd_i2c_driver =
{
. Probe = Tpd_i2c_probe,
. remove = Tpd_i2c_remove,
. Detect = Tpd_i2c_detect,
. Driver.name = "B_gt9xx_hotknot",
. id_table = tpd_i2c_id,
. address_list = (const unsigned Short *) forces,
};
The contents of this are to be achieved by themselves, especially Tpd_i2c_probe (). If the device is initialized in Tpd_i2c_probe (), the bit global variable T
The Pd_load_status is successfully initialized for the 1 tag, otherwise the matching failure requires calling I2c_del_driver () to delete the registered driver. 4, set the input device Tpd->dev support the maximum number of finger touch
Input_set_abs_params (Tpd->dev, abs_mt_tracking_id, 0, (gtp_max_touch-1), 0, 0);
1
The input device Tpd->dev application, as well as the definition and initialization content, is implemented in the Tpd_probe () function of the mtk_tpd.c file. The reason why abs_mt_tracking_id is not initialized together is that the original software of each touch IC achieves the greatest number of touches, so it needs to be set according to the circumstances. 5. Initialization of key
#ifdef Tpd_have_button
if (factory_boot = = Get_boot_mode () | | Recovery_boot = = Get_boot_mode ()) //Cty 2014-08-14
{
tpd_button_setting tpd_key_count Factory, tpd_keys_dim_local);//Initialize TPD button data
}
else
{
tpd_button_setting (tpd_key_ COUNT, tpd_keys_local, tpd_keys_dim_local);//Initialize TPD button data
}
#endif
The contents of the tpd_button_setting () function are very simple, that is, the array tpd_keys_local[tpd_key_count] and T
Pd_keys_dim_local[tpd_key_count][4] copies to Tpd_keys and Tpd_keys_dim. These two variables
Initialization for Tpd_button_init () creates the virtual keys. The contents of the array are based on the resolution of the TP to determine the position of the key. Need to determine the number of keys, key names according to different resolutions
The coordinate range of the key.
#define TPD_KEY_COUNT 3
#define Tpd_keys {key_back, key_homepage,key_menu}
#define Tpd_keys_ FACTORY {key_back, key_home,key_menu}
#define Tpd_keys_dim {{100,1500,50,30},{270,1500,50,30},{ 450,1500,50,30}}
#ifdef tpd_have_button
static int Tpd_keys_local[tpd_key_count] = Tpd_keys;
static int Tpd_keys_local_factory[tpd_key_count] = tpd_keys_factory;
static int tpd_keys_dim_local[tpd_key_count][4] = Tpd_keys_dim;
#endif
The TP button is also reported as a input_event in a coordinate form, as is the case with other touch events. The tpd_button_setting () function is used to write the coordinate information of the virtual key in/sys/board_properties/according to the configuration information defined in the Tpd_custom_xxx.h file during initialization. In VIRTUALKEYS.MTK-TPD. Work, TP driver will press the coordinates of the point to report, the Android upper level will read the key configuration information in the SYS, and then determine whether the coordinates of the escalation of a key to the coordinates of the range, so that the coordinate information into the specific key value. See what kind of mechanism the Android virtual key is reported through.
MTK virtual key implementation in the TPD_BUTTON.C, the specific contents of the Android TP virtual key (dummy key) processing 6, set input device Tpd->dev information
Set Vendor string
Tpd->dev->id.vendor = 0x00;
Tpd->dev->id.product = Tpd_info.pid;
Tpd->dev->id.version = Tpd_info.vid;
Where the Tpd_info information is obtained by calling Gtp_read_version () in Tpd_i2c_probe ().
7. Set TP type as capacitive screen
Tpd_type_cap = 1;
1
From the literal meaning of the variable is set labeled TP as a capacitive screen, as to what the role is still unknown. Tpd_i2c_probe ()
Static S32 tpd_i2c_probe (struct i2c_client *client, const struct I2C_DEVICE_ID *id)
{
S32 err = 0;
S32 ret = 0;
U16 Version_info;
#if GT