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) |