How does the Trackpoint on my Lenovo R400 worked?

Firstly, “dmesg” shows that Ubuntu detected the trackpoint thus:

[ 45.219976] input: TPPS/2 IBM TrackPoint as /devices/platform/i8042/serio1/input/input6

drivers/input/mouse/psmouse-base.c:

First the module and related structure is defined here:

MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);

static struct serio_driver psmouse_drv = {
.driver = {
.name = “psmouse”,
},
.description = DRIVER_DESC,
.id_table = psmouse_serio_ids,
.interrupt = psmouse_interrupt,
.connect = psmouse_connect,
.reconnect = psmouse_reconnect,
.disconnect = psmouse_disconnect,
.cleanup = psmouse_cleanup,
};

static const struct psmouse_protocol psmouse_protocols[] = {
{
.type = PSMOUSE_TRACKPOINT,
.name = “TPPS/2”,
.alias = “trackpoint”,
.detect = trackpoint_detect,
},

And then during psmouse_connection() other registration are done here:

/*
* psmouse_connect() is a callback from the serio module when
* an unhandled serio port is found.
*/
static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
{

/*
* If this is a pass-through port deactivate parent so the device
* connected to this port can be successfully identified
*/
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
parent = serio_get_drvdata(serio->parent);
psmouse_deactivate(parent);
}

psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
input_dev = input_allocate_device();
if (!psmouse || !input_dev)
goto err_free;

ps2_init(&psmouse->ps2dev, serio);
INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), “%s/input0”, serio->phys);

psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);

……..

psmouse->rate = psmouse_rate;
psmouse->resolution = psmouse_resolution;
psmouse->resetafter = psmouse_resetafter;
psmouse->resync_time = parent ? 0 : psmouse_resync_time;
psmouse->smartscroll = psmouse_smartscroll;

psmouse_switch_protocol(psmouse, NULL);

psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
psmouse_initialize(psmouse);

error = input_register_device(psmouse->dev);

and during psmouse_connect() callback, the trackpoint is detected:

if (trackpoint_detect(psmouse, set_properties) == 0)

And the detection logic is in:

drivers/input/mouse/trackpoint.c:
int trackpoint_detect(struct psmouse *psmouse, bool set_properties)

Other defined APIs for interaction with external application:

PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
NULL,
psmouse_attr_show_protocol, psmouse_attr_set_protocol);
PSMOUSE_DEFINE_ATTR(rate, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, rate),
psmouse_show_int_attr, psmouse_attr_set_rate);
PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, resolution),
psmouse_show_int_attr, psmouse_attr_set_resolution);
PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, resetafter),
psmouse_show_int_attr, psmouse_set_int_attr);
PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, resync_time),
psmouse_show_int_attr, psmouse_set_int_attr);

/*
* Device IO: read, write and toggle bit
*/
static int trackpoint_read(struct ps2dev *ps2dev, unsigned char loc, unsigned char *results)
{
if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) {
return -1;
}

return 0;
}

static int trackpoint_write(struct ps2dev *ps2dev, unsigned char loc, unsigned char val)

……

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: