微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 基于DragonBoard 410c开发板的触摸屏驱动编写

基于DragonBoard 410c开发板的触摸屏驱动编写

时间:02-21 来源:互联网 点击:

前言:

让大家初步了解对高通MSM8916平台的输入子系统的实现,给大家提供Dragon Board 410c平台开发输入系统设备的思路。(如:按键设备、触摸屏、轨迹球等)

在高通MSM8916平台中,具有触摸屏、轨迹球和简单按键功能,这些功能是由Android系统内中的驱动程序实现的,并且需要用户空间的内容来协助实现。

一、触摸屏驱动编写

高通MSM8916平台的触摸屏驱动程序的实现文件是drivers/input/touchscreen/synapTIcs_i2c_rmi4.c,此文件的核心是函数synapTIcs_ts_probe(),在该函数中需要进行触摸屏工作模式的初始化,对作为输出设备的触摸屏驱动在Linux平台下的设备名注册,同事初始化触摸时间触发时引起的中断操作。此函数的实现代码如下:

staTIc int synapTIcs_rmi4_probe(

struct i2c_client *client,const struct i2c_device_id *dev_id)

{

int retval = 0;
unsigned char ii;
unsigned char attr_count;
struct synaptics_rmi4_f1a_handle *f1a;
struct synaptics_rmi4_fn *fhandler;
struct synaptics_rmi4_fn *next_fhandler;
struct synaptics_rmi4_data *rmi4_data;
struct synaptics_rmi4_device_info *rmi;
struct synaptics_rmi4_platform_data *platform_data =
client->dev.platform_data;
struct dentry *temp;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev,
"%s: SMBus byte data not supported\n",
__func__);
return -EIO;
}
if (client->dev.of_node) {
platform_data = devm_kzalloc(&client->dev,
sizeof(*platform_data),
GFP_KERNEL);
if (!platform_data) {
dev_err(&client->dev, "Failed to allocate memory\n");
return -ENOMEM;
}
retval = synaptics_rmi4_parse_dt(&client->dev, platform_data);
if (retval)
return retval;
} else {
platform_data = client->dev.platform_data;
}
if (!platform_data) {
dev_err(&client->dev,
"%s: No platform data found\n",
__func__);
return -EINVAL;
}
rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL);
if (!rmi4_data) {
dev_err(&client->dev,
"%s: Failed to alloc mem for rmi4_data\n",
__func__);
return -ENOMEM;
}
rmi = &(rmi4_data->rmi4_mod_info);
rmi4_data->input_dev = input_allocate_device();//创建设备
if (rmi4_data->input_dev == NULL) {
dev_err(&client->dev,
"%s: Failed to allocate input device\n",
__func__);
retval = -ENOMEM;
goto err_input_device;

rmi4_data->i2c_client = client;
rmi4_data->current_page = MASK_8BIT;
rmi4_data->board = platform_data;
rmi4_data->touch_stopped = false;
rmi4_data->sensor_sleep = false;
rmi4_data->irq_enabled = false;
rmi4_data->fw_updating = false;
rmi4_data->suspended = false;
rmi4_data->i2c_read = synaptics_rmi4_i2c_read;
rmi4_data->i2c_write = synaptics_rmi4_i2c_write;
rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
rmi4_data->reset_device = synaptics_rmi4_reset_device;
rmi4_data->flip_x = rmi4_data->board->x_flip;
rmi4_data->flip_y = rmi4_data->board->y_flip;
if (rmi4_data->board->fw_image_name)
snprintf(rmi4_data->fw_image_name, NAME_BUFFER_SIZE, "%s",
rmi4_data->board->fw_image_name);
rmi4_data->input_dev->name = DRIVER_NAME;
rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
rmi4_data->input_dev->id.bustype = BUS_I2C;
rmi4_data->input_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT;
rmi4_data->input_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION;
rmi4_data->input_dev->dev.parent = &client->dev;
input_set_drvdata(rmi4_data->input_dev, rmi4_data);
set_bit(EV_SYN, rmi4_data->input_dev->evbit);
set_bit(EV_KEY, rmi4_data->input_dev->evbit);
set_bit(EV_ABS, rmi4_data->input_dev->evbit);
set_bit(BTN_TOUCH, rmi4_data->input_dev->keybit);
set_bit(BTN_TOOL_FINGER, rmi4_data->input_dev->keybit);
#ifdef INPUT_PROP_DIRECT
set_bit(INPUT_PROP_DIRECT, rmi4_data->input_dev->propbit);
#endif
retval = synaptics_rmi4_regulator_configure(rmi4_data, true);
if (retval < 0) {
dev_err(&client->dev, "Failed to configure regulators\n");
goto err_reg_configure;
}
retval = synaptics_rmi4_power_on(rmi4_data, true);
if (retval < 0) {
dev_err(&client->dev, "Failed to power on\n");
goto err_power_device;
}
retval = synaptics_rmi4_pinctrl_init(rmi4_data);
if (!retval && rmi4_data->ts_pinctrl) {
/*
* Pinctrl handle is optional. If pinctrl handle is found
* let pins to be configured in active state. If not found
* continue further without error
*/
if (pinctrl_select_state(rmi4_data->ts_pinctrl,
rmi4_data->pinctrl_state_active))
dev_err(&rmi4_data->i2c_client->dev,
"Can not select %s pinstate\n",
PINCTRL_STATE_ACTIVE);
}
retval = synaptics_rmi4_gpio_configure(rmi4_data, true);
if (retval < 0) {
dev_err(&client->dev, "Failed to configure gpios\n");
goto err_gpio_config;
}
init_waitqueue_head(&rmi4_data->wait);
mutex_init(&(rmi4_data->rmi4_io_ctrl_mutex));
INIT_LIST_HEAD(&rmi->support_fn_list);
mutex_init(&rmi->support_fn_list_mutex);

retval = synaptics_rmi4_query_device(rmi4_data);
if (retval < 0) {
dev_err(&client->dev,
"%s: Failed to query device\n",
__func__);
goto err_free_gpios;
}

if (platform_data->detect_device) {
retval = synaptics_rmi4_parse_dt_children(&client->dev,
platform_data, rmi4_data);
if (retval < 0)
dev_err(&client->dev,
"%s: Failed to parse device tree property\n",
__func__);
}
if (rmi4_data->board->disp_maxx)
rmi4_data->disp_maxx = rmi4_data->board->disp_maxx;
else
rmi4_data->disp_maxx = rmi4_data->sensor_max_x;
if (rmi4_data->board->disp_maxy)
rmi4_data->disp_maxy = rmi4_data->board->disp_maxy;
else
rmi4_data->disp_maxy = rmi4_data->sensor_max_y;
if (rmi4_data->board->disp_minx)
rmi4_data->disp_minx = rmi4_data->board->disp_minx;
else
rmi4_data->disp_minx = 0;

if (rmi4_data->board->disp_miny)
rmi4_data->disp_miny = rmi4_data->board->disp_miny;
else
rmi4_data->disp_miny = 0;

input_set_abs_params(rmi4_data->input_dev,
ABS_MT_POSITION_X, rmi4_data->disp_minx,
rmi4_data->disp_maxx, 0, 0);
input_set_abs_params(rmi4_data->input_dev,
ABS_MT_POSITION_Y, rmi4_data->disp_miny,
rmi4_data->disp_maxy, 0, 0);
input_set_abs_params(rmi4_data->input_dev,
ABS_PRESSURE, 0, 255, 0, 0);
#ifdef REPORT_2D_W
input_set_abs_params(rmi4_data->input_dev,
ABS_MT_TOUCH_MAJOR, 0,
rmi4_data->max_touch_width, 0, 0);
input_set_abs_params(rmi4_data->input_dev,
ABS_MT_TOUCH_MINOR, 0,
rmi4_data->max_touch_width, 0, 0);
#endif
#ifdef TYPE_B_PROTOCOL
input_mt_init_slots(rmi4_data->input_dev,
rmi4_data->num_of_fingers, 0);
#endif
i2c_set_clientdata(client, rmi4_data);
f1a = NULL;
mutex_lock(&rmi->support_fn_list_mutex);
if (!list_empty(&rmi->support_fn_list)) {
list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
if (fhandler->fn_number == SYNAPTICS_RMI4_F1A)
f1a = fhandler->data;
}
}
mutex_unlock(&rmi->support_fn_list_mutex);
if (f1a) {
for (ii = 0; ii < f1a->valid_button_count; ii++) {
set_bit(f1a->button_map[ii],
rmi4_data->input_dev->keybit);
input_set_capability(rmi4_data->input_dev,
EV_KEY, f1a->button_map[ii]);
}
}
retval =

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top