diff options
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
| -rw-r--r-- | drivers/input/mouse/psmouse-base.c | 132 |
1 files changed, 80 insertions, 52 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 12bdd3eff923..af24313ff5bb 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include "logips2pp.h" | 25 | #include "logips2pp.h" |
| 26 | #include "alps.h" | 26 | #include "alps.h" |
| 27 | #include "lifebook.h" | 27 | #include "lifebook.h" |
| 28 | #include "trackpoint.h" | ||
| 28 | 29 | ||
| 29 | #define DRIVER_DESC "PS/2 mouse driver" | 30 | #define DRIVER_DESC "PS/2 mouse driver" |
| 30 | 31 | ||
| @@ -57,10 +58,30 @@ static unsigned int psmouse_resetafter; | |||
| 57 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); | 58 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); |
| 58 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); | 59 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); |
| 59 | 60 | ||
| 60 | PSMOUSE_DEFINE_ATTR(protocol); | 61 | PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO, |
| 61 | PSMOUSE_DEFINE_ATTR(rate); | 62 | NULL, |
| 62 | PSMOUSE_DEFINE_ATTR(resolution); | 63 | psmouse_attr_show_protocol, psmouse_attr_set_protocol); |
| 63 | PSMOUSE_DEFINE_ATTR(resetafter); | 64 | PSMOUSE_DEFINE_ATTR(rate, S_IWUSR | S_IRUGO, |
| 65 | (void *) offsetof(struct psmouse, rate), | ||
| 66 | psmouse_show_int_attr, psmouse_attr_set_rate); | ||
| 67 | PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO, | ||
| 68 | (void *) offsetof(struct psmouse, resolution), | ||
| 69 | psmouse_show_int_attr, psmouse_attr_set_resolution); | ||
| 70 | PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO, | ||
| 71 | (void *) offsetof(struct psmouse, resetafter), | ||
| 72 | psmouse_show_int_attr, psmouse_set_int_attr); | ||
| 73 | |||
| 74 | static struct attribute *psmouse_attributes[] = { | ||
| 75 | &psmouse_attr_protocol.dattr.attr, | ||
| 76 | &psmouse_attr_rate.dattr.attr, | ||
| 77 | &psmouse_attr_resolution.dattr.attr, | ||
| 78 | &psmouse_attr_resetafter.dattr.attr, | ||
| 79 | NULL | ||
| 80 | }; | ||
| 81 | |||
| 82 | static struct attribute_group psmouse_attribute_group = { | ||
| 83 | .attrs = psmouse_attributes, | ||
| 84 | }; | ||
| 64 | 85 | ||
| 65 | __obsolete_setup("psmouse_noext"); | 86 | __obsolete_setup("psmouse_noext"); |
| 66 | __obsolete_setup("psmouse_resolution="); | 87 | __obsolete_setup("psmouse_resolution="); |
| @@ -520,6 +541,12 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 520 | return PSMOUSE_IMPS; | 541 | return PSMOUSE_IMPS; |
| 521 | 542 | ||
| 522 | /* | 543 | /* |
| 544 | * Try to initialize the IBM TrackPoint | ||
| 545 | */ | ||
| 546 | if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) | ||
| 547 | return PSMOUSE_TRACKPOINT; | ||
| 548 | |||
| 549 | /* | ||
| 523 | * Okay, all failed, we have a standard mouse here. The number of the buttons | 550 | * Okay, all failed, we have a standard mouse here. The number of the buttons |
| 524 | * is still a question, though. We assume 3. | 551 | * is still a question, though. We assume 3. |
| 525 | */ | 552 | */ |
| @@ -600,6 +627,12 @@ static struct psmouse_protocol psmouse_protocols[] = { | |||
| 600 | .init = lifebook_init, | 627 | .init = lifebook_init, |
| 601 | }, | 628 | }, |
| 602 | { | 629 | { |
| 630 | .type = PSMOUSE_TRACKPOINT, | ||
| 631 | .name = "TPPS/2", | ||
| 632 | .alias = "trackpoint", | ||
| 633 | .detect = trackpoint_detect, | ||
| 634 | }, | ||
| 635 | { | ||
| 603 | .type = PSMOUSE_AUTO, | 636 | .type = PSMOUSE_AUTO, |
| 604 | .name = "auto", | 637 | .name = "auto", |
| 605 | .alias = "any", | 638 | .alias = "any", |
| @@ -787,10 +820,7 @@ static void psmouse_disconnect(struct serio *serio) | |||
| 787 | 820 | ||
| 788 | psmouse = serio_get_drvdata(serio); | 821 | psmouse = serio_get_drvdata(serio); |
| 789 | 822 | ||
| 790 | device_remove_file(&serio->dev, &psmouse_attr_protocol); | 823 | sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group); |
| 791 | device_remove_file(&serio->dev, &psmouse_attr_rate); | ||
| 792 | device_remove_file(&serio->dev, &psmouse_attr_resolution); | ||
| 793 | device_remove_file(&serio->dev, &psmouse_attr_resetafter); | ||
| 794 | 824 | ||
| 795 | down(&psmouse_sem); | 825 | down(&psmouse_sem); |
| 796 | 826 | ||
| @@ -927,10 +957,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 927 | if (parent && parent->pt_activate) | 957 | if (parent && parent->pt_activate) |
| 928 | parent->pt_activate(parent); | 958 | parent->pt_activate(parent); |
| 929 | 959 | ||
| 930 | device_create_file(&serio->dev, &psmouse_attr_protocol); | 960 | sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); |
| 931 | device_create_file(&serio->dev, &psmouse_attr_rate); | ||
| 932 | device_create_file(&serio->dev, &psmouse_attr_resolution); | ||
| 933 | device_create_file(&serio->dev, &psmouse_attr_resetafter); | ||
| 934 | 961 | ||
| 935 | psmouse_activate(psmouse); | 962 | psmouse_activate(psmouse); |
| 936 | 963 | ||
| @@ -1027,10 +1054,12 @@ static struct serio_driver psmouse_drv = { | |||
| 1027 | .cleanup = psmouse_cleanup, | 1054 | .cleanup = psmouse_cleanup, |
| 1028 | }; | 1055 | }; |
| 1029 | 1056 | ||
| 1030 | ssize_t psmouse_attr_show_helper(struct device *dev, char *buf, | 1057 | ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *devattr, |
| 1031 | ssize_t (*handler)(struct psmouse *, char *)) | 1058 | char *buf) |
| 1032 | { | 1059 | { |
| 1033 | struct serio *serio = to_serio_port(dev); | 1060 | struct serio *serio = to_serio_port(dev); |
| 1061 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); | ||
| 1062 | struct psmouse *psmouse; | ||
| 1034 | int retval; | 1063 | int retval; |
| 1035 | 1064 | ||
| 1036 | retval = serio_pin_driver(serio); | 1065 | retval = serio_pin_driver(serio); |
| @@ -1042,19 +1071,21 @@ ssize_t psmouse_attr_show_helper(struct device *dev, char *buf, | |||
| 1042 | goto out; | 1071 | goto out; |
| 1043 | } | 1072 | } |
| 1044 | 1073 | ||
| 1045 | retval = handler(serio_get_drvdata(serio), buf); | 1074 | psmouse = serio_get_drvdata(serio); |
| 1075 | |||
| 1076 | retval = attr->show(psmouse, attr->data, buf); | ||
| 1046 | 1077 | ||
| 1047 | out: | 1078 | out: |
| 1048 | serio_unpin_driver(serio); | 1079 | serio_unpin_driver(serio); |
| 1049 | return retval; | 1080 | return retval; |
| 1050 | } | 1081 | } |
| 1051 | 1082 | ||
| 1052 | ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count, | 1083 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, |
| 1053 | ssize_t (*handler)(struct psmouse *, const char *, size_t)) | 1084 | const char *buf, size_t count) |
| 1054 | { | 1085 | { |
| 1055 | struct serio *serio = to_serio_port(dev); | 1086 | struct serio *serio = to_serio_port(dev); |
| 1056 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1087 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); |
| 1057 | struct psmouse *parent = NULL; | 1088 | struct psmouse *psmouse, *parent = NULL; |
| 1058 | int retval; | 1089 | int retval; |
| 1059 | 1090 | ||
| 1060 | retval = serio_pin_driver(serio); | 1091 | retval = serio_pin_driver(serio); |
| @@ -1070,6 +1101,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun | |||
| 1070 | if (retval) | 1101 | if (retval) |
| 1071 | goto out_unpin; | 1102 | goto out_unpin; |
| 1072 | 1103 | ||
| 1104 | psmouse = serio_get_drvdata(serio); | ||
| 1105 | |||
| 1073 | if (psmouse->state == PSMOUSE_IGNORE) { | 1106 | if (psmouse->state == PSMOUSE_IGNORE) { |
| 1074 | retval = -ENODEV; | 1107 | retval = -ENODEV; |
| 1075 | goto out_up; | 1108 | goto out_up; |
| @@ -1082,7 +1115,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun | |||
| 1082 | 1115 | ||
| 1083 | psmouse_deactivate(psmouse); | 1116 | psmouse_deactivate(psmouse); |
| 1084 | 1117 | ||
| 1085 | retval = handler(psmouse, buf, count); | 1118 | retval = attr->set(psmouse, attr->data, buf, count); |
| 1086 | 1119 | ||
| 1087 | if (retval != -ENODEV) | 1120 | if (retval != -ENODEV) |
| 1088 | psmouse_activate(psmouse); | 1121 | psmouse_activate(psmouse); |
| @@ -1097,12 +1130,34 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun | |||
| 1097 | return retval; | 1130 | return retval; |
| 1098 | } | 1131 | } |
| 1099 | 1132 | ||
| 1100 | static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf) | 1133 | static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf) |
| 1134 | { | ||
| 1135 | unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset); | ||
| 1136 | |||
| 1137 | return sprintf(buf, "%lu\n", *field); | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count) | ||
| 1141 | { | ||
| 1142 | unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset); | ||
| 1143 | unsigned long value; | ||
| 1144 | char *rest; | ||
| 1145 | |||
| 1146 | value = simple_strtoul(buf, &rest, 10); | ||
| 1147 | if (*rest) | ||
| 1148 | return -EINVAL; | ||
| 1149 | |||
| 1150 | *field = value; | ||
| 1151 | |||
| 1152 | return count; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, void *data, char *buf) | ||
| 1101 | { | 1156 | { |
| 1102 | return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name); | 1157 | return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name); |
| 1103 | } | 1158 | } |
| 1104 | 1159 | ||
| 1105 | static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count) | 1160 | static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, const char *buf, size_t count) |
| 1106 | { | 1161 | { |
| 1107 | struct serio *serio = psmouse->ps2dev.serio; | 1162 | struct serio *serio = psmouse->ps2dev.serio; |
| 1108 | struct psmouse *parent = NULL; | 1163 | struct psmouse *parent = NULL; |
| @@ -1166,12 +1221,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *bu | |||
| 1166 | return count; | 1221 | return count; |
| 1167 | } | 1222 | } |
| 1168 | 1223 | ||
| 1169 | static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf) | 1224 | static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count) |
| 1170 | { | ||
| 1171 | return sprintf(buf, "%d\n", psmouse->rate); | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, size_t count) | ||
| 1175 | { | 1225 | { |
| 1176 | unsigned long value; | 1226 | unsigned long value; |
| 1177 | char *rest; | 1227 | char *rest; |
| @@ -1184,12 +1234,7 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, s | |||
| 1184 | return count; | 1234 | return count; |
| 1185 | } | 1235 | } |
| 1186 | 1236 | ||
| 1187 | static ssize_t psmouse_attr_show_resolution(struct psmouse *psmouse, char *buf) | 1237 | static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count) |
| 1188 | { | ||
| 1189 | return sprintf(buf, "%d\n", psmouse->resolution); | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *buf, size_t count) | ||
| 1193 | { | 1238 | { |
| 1194 | unsigned long value; | 1239 | unsigned long value; |
| 1195 | char *rest; | 1240 | char *rest; |
| @@ -1202,23 +1247,6 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char * | |||
| 1202 | return count; | 1247 | return count; |
| 1203 | } | 1248 | } |
| 1204 | 1249 | ||
| 1205 | static ssize_t psmouse_attr_show_resetafter(struct psmouse *psmouse, char *buf) | ||
| 1206 | { | ||
| 1207 | return sprintf(buf, "%d\n", psmouse->resetafter); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char *buf, size_t count) | ||
| 1211 | { | ||
| 1212 | unsigned long value; | ||
| 1213 | char *rest; | ||
| 1214 | |||
| 1215 | value = simple_strtoul(buf, &rest, 10); | ||
| 1216 | if (*rest) | ||
| 1217 | return -EINVAL; | ||
| 1218 | |||
| 1219 | psmouse->resetafter = value; | ||
| 1220 | return count; | ||
| 1221 | } | ||
| 1222 | 1250 | ||
| 1223 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | 1251 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) |
| 1224 | { | 1252 | { |
| @@ -1234,7 +1262,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | |||
| 1234 | 1262 | ||
| 1235 | *((unsigned int *)kp->arg) = proto->type; | 1263 | *((unsigned int *)kp->arg) = proto->type; |
| 1236 | 1264 | ||
| 1237 | return 0; \ | 1265 | return 0; |
| 1238 | } | 1266 | } |
| 1239 | 1267 | ||
| 1240 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) | 1268 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) |
