diff options
| -rw-r--r-- | drivers/input/mouse/alps.c | 131 |
1 files changed, 67 insertions, 64 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 6ad2cd733a4d..b97832b622cb 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -130,6 +130,22 @@ static const struct alps_model_info alps_model_data[] = { | |||
| 130 | { { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } }, | 130 | { { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } }, |
| 131 | }; | 131 | }; |
| 132 | 132 | ||
| 133 | static const struct alps_protocol_info alps_v3_protocol_data = { | ||
| 134 | ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT | ||
| 135 | }; | ||
| 136 | |||
| 137 | static const struct alps_protocol_info alps_v3_rushmore_data = { | ||
| 138 | ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT | ||
| 139 | }; | ||
| 140 | |||
| 141 | static const struct alps_protocol_info alps_v5_protocol_data = { | ||
| 142 | ALPS_PROTO_V5, 0xc8, 0xd8, 0 | ||
| 143 | }; | ||
| 144 | |||
| 145 | static const struct alps_protocol_info alps_v7_protocol_data = { | ||
| 146 | ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT | ||
| 147 | }; | ||
| 148 | |||
| 133 | static void alps_set_abs_params_st(struct alps_data *priv, | 149 | static void alps_set_abs_params_st(struct alps_data *priv, |
| 134 | struct input_dev *dev1); | 150 | struct input_dev *dev1); |
| 135 | static void alps_set_abs_params_mt(struct alps_data *priv, | 151 | static void alps_set_abs_params_mt(struct alps_data *priv, |
| @@ -2162,11 +2178,18 @@ error: | |||
| 2162 | return ret; | 2178 | return ret; |
| 2163 | } | 2179 | } |
| 2164 | 2180 | ||
| 2165 | static void alps_set_defaults(struct alps_data *priv) | 2181 | static int alps_set_protocol(struct psmouse *psmouse, |
| 2182 | struct alps_data *priv, | ||
| 2183 | const struct alps_protocol_info *protocol) | ||
| 2166 | { | 2184 | { |
| 2167 | priv->byte0 = 0x8f; | 2185 | psmouse->private = priv; |
| 2168 | priv->mask0 = 0x8f; | 2186 | |
| 2169 | priv->flags = ALPS_DUALPOINT; | 2187 | setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); |
| 2188 | |||
| 2189 | priv->proto_version = protocol->version; | ||
| 2190 | priv->byte0 = protocol->byte0; | ||
| 2191 | priv->mask0 = protocol->mask0; | ||
| 2192 | priv->flags = protocol->flags; | ||
| 2170 | 2193 | ||
| 2171 | priv->x_max = 2000; | 2194 | priv->x_max = 2000; |
| 2172 | priv->y_max = 1400; | 2195 | priv->y_max = 1400; |
| @@ -2201,6 +2224,11 @@ static void alps_set_defaults(struct alps_data *priv) | |||
| 2201 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | 2224 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; |
| 2202 | priv->x_bits = 16; | 2225 | priv->x_bits = 16; |
| 2203 | priv->y_bits = 12; | 2226 | priv->y_bits = 12; |
| 2227 | |||
| 2228 | if (alps_probe_trackstick_v3(psmouse, | ||
| 2229 | ALPS_REG_BASE_RUSHMORE) < 0) | ||
| 2230 | priv->flags &= ~ALPS_DUALPOINT; | ||
| 2231 | |||
| 2204 | break; | 2232 | break; |
| 2205 | 2233 | ||
| 2206 | case ALPS_PROTO_V4: | 2234 | case ALPS_PROTO_V4: |
| @@ -2210,6 +2238,7 @@ static void alps_set_defaults(struct alps_data *priv) | |||
| 2210 | priv->nibble_commands = alps_v4_nibble_commands; | 2238 | priv->nibble_commands = alps_v4_nibble_commands; |
| 2211 | priv->addr_command = PSMOUSE_CMD_DISABLE; | 2239 | priv->addr_command = PSMOUSE_CMD_DISABLE; |
| 2212 | break; | 2240 | break; |
| 2241 | |||
| 2213 | case ALPS_PROTO_V5: | 2242 | case ALPS_PROTO_V5: |
| 2214 | priv->hw_init = alps_hw_init_dolphin_v1; | 2243 | priv->hw_init = alps_hw_init_dolphin_v1; |
| 2215 | priv->process_packet = alps_process_touchpad_packet_v3_v5; | 2244 | priv->process_packet = alps_process_touchpad_packet_v3_v5; |
| @@ -2217,14 +2246,12 @@ static void alps_set_defaults(struct alps_data *priv) | |||
| 2217 | priv->set_abs_params = alps_set_abs_params_mt; | 2246 | priv->set_abs_params = alps_set_abs_params_mt; |
| 2218 | priv->nibble_commands = alps_v3_nibble_commands; | 2247 | priv->nibble_commands = alps_v3_nibble_commands; |
| 2219 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | 2248 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; |
| 2220 | priv->byte0 = 0xc8; | ||
| 2221 | priv->mask0 = 0xd8; | ||
| 2222 | priv->flags = 0; | ||
| 2223 | priv->x_max = 1360; | 2249 | priv->x_max = 1360; |
| 2224 | priv->y_max = 660; | 2250 | priv->y_max = 660; |
| 2225 | priv->x_bits = 23; | 2251 | priv->x_bits = 23; |
| 2226 | priv->y_bits = 12; | 2252 | priv->y_bits = 12; |
| 2227 | break; | 2253 | break; |
| 2254 | |||
| 2228 | case ALPS_PROTO_V6: | 2255 | case ALPS_PROTO_V6: |
| 2229 | priv->hw_init = alps_hw_init_v6; | 2256 | priv->hw_init = alps_hw_init_v6; |
| 2230 | priv->process_packet = alps_process_packet_v6; | 2257 | priv->process_packet = alps_process_packet_v6; |
| @@ -2233,6 +2260,7 @@ static void alps_set_defaults(struct alps_data *priv) | |||
| 2233 | priv->x_max = 2047; | 2260 | priv->x_max = 2047; |
| 2234 | priv->y_max = 1535; | 2261 | priv->y_max = 1535; |
| 2235 | break; | 2262 | break; |
| 2263 | |||
| 2236 | case ALPS_PROTO_V7: | 2264 | case ALPS_PROTO_V7: |
| 2237 | priv->hw_init = alps_hw_init_v7; | 2265 | priv->hw_init = alps_hw_init_v7; |
| 2238 | priv->process_packet = alps_process_packet_v7; | 2266 | priv->process_packet = alps_process_packet_v7; |
| @@ -2240,19 +2268,21 @@ static void alps_set_defaults(struct alps_data *priv) | |||
| 2240 | priv->set_abs_params = alps_set_abs_params_mt; | 2268 | priv->set_abs_params = alps_set_abs_params_mt; |
| 2241 | priv->nibble_commands = alps_v3_nibble_commands; | 2269 | priv->nibble_commands = alps_v3_nibble_commands; |
| 2242 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | 2270 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; |
| 2243 | priv->x_max = 0xfff; | 2271 | |
| 2244 | priv->y_max = 0x7ff; | 2272 | if (alps_dolphin_get_device_area(psmouse, priv)) |
| 2245 | priv->byte0 = 0x48; | 2273 | return -EIO; |
| 2246 | priv->mask0 = 0x48; | ||
| 2247 | 2274 | ||
| 2248 | if (priv->fw_ver[1] != 0xba) | 2275 | if (priv->fw_ver[1] != 0xba) |
| 2249 | priv->flags |= ALPS_BUTTONPAD; | 2276 | priv->flags |= ALPS_BUTTONPAD; |
| 2277 | |||
| 2250 | break; | 2278 | break; |
| 2251 | } | 2279 | } |
| 2280 | |||
| 2281 | return 0; | ||
| 2252 | } | 2282 | } |
| 2253 | 2283 | ||
| 2254 | static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, | 2284 | static const struct alps_protocol_info *alps_match_table(unsigned char *e7, |
| 2255 | unsigned char *e7, unsigned char *ec) | 2285 | unsigned char *ec) |
| 2256 | { | 2286 | { |
| 2257 | const struct alps_model_info *model; | 2287 | const struct alps_model_info *model; |
| 2258 | int i; | 2288 | int i; |
| @@ -2264,22 +2294,16 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, | |||
| 2264 | (!model->command_mode_resp || | 2294 | (!model->command_mode_resp || |
| 2265 | model->command_mode_resp == ec[2])) { | 2295 | model->command_mode_resp == ec[2])) { |
| 2266 | 2296 | ||
| 2267 | priv->proto_version = model->protocol_info.version; | 2297 | return &model->protocol_info; |
| 2268 | alps_set_defaults(priv); | ||
| 2269 | |||
| 2270 | priv->flags = model->protocol_info.flags; | ||
| 2271 | priv->byte0 = model->protocol_info.byte0; | ||
| 2272 | priv->mask0 = model->protocol_info.mask0; | ||
| 2273 | |||
| 2274 | return 0; | ||
| 2275 | } | 2298 | } |
| 2276 | } | 2299 | } |
| 2277 | 2300 | ||
| 2278 | return -EINVAL; | 2301 | return NULL; |
| 2279 | } | 2302 | } |
| 2280 | 2303 | ||
| 2281 | static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | 2304 | static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) |
| 2282 | { | 2305 | { |
| 2306 | const struct alps_protocol_info *protocol; | ||
| 2283 | unsigned char e6[4], e7[4], ec[4]; | 2307 | unsigned char e6[4], e7[4], ec[4]; |
| 2284 | 2308 | ||
| 2285 | /* | 2309 | /* |
| @@ -2306,48 +2330,30 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
| 2306 | alps_exit_command_mode(psmouse)) | 2330 | alps_exit_command_mode(psmouse)) |
| 2307 | return -EIO; | 2331 | return -EIO; |
| 2308 | 2332 | ||
| 2309 | /* Save the Firmware version */ | 2333 | protocol = alps_match_table(e7, ec); |
| 2310 | memcpy(priv->fw_ver, ec, 3); | 2334 | if (!protocol) { |
| 2311 | 2335 | if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && | |
| 2312 | if (alps_match_table(psmouse, priv, e7, ec) == 0) { | 2336 | ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { |
| 2313 | return 0; | 2337 | protocol = &alps_v5_protocol_data; |
| 2314 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && | 2338 | } else if (ec[0] == 0x88 && |
| 2315 | ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { | 2339 | ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { |
| 2316 | priv->proto_version = ALPS_PROTO_V5; | 2340 | protocol = &alps_v7_protocol_data; |
| 2317 | alps_set_defaults(priv); | 2341 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { |
| 2318 | if (alps_dolphin_get_device_area(psmouse, priv)) | 2342 | protocol = &alps_v3_rushmore_data; |
| 2319 | return -EIO; | 2343 | } else if (ec[0] == 0x88 && ec[1] == 0x07 && |
| 2320 | else | 2344 | ec[2] >= 0x90 && ec[2] <= 0x9d) { |
| 2321 | return 0; | 2345 | protocol = &alps_v3_protocol_data; |
| 2322 | } else if (ec[0] == 0x88 && | 2346 | } else { |
| 2323 | ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { | 2347 | psmouse_dbg(psmouse, |
| 2324 | priv->proto_version = ALPS_PROTO_V7; | 2348 | "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); |
| 2325 | alps_set_defaults(priv); | 2349 | return -EINVAL; |
| 2326 | 2350 | } | |
| 2327 | return 0; | ||
| 2328 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { | ||
| 2329 | priv->proto_version = ALPS_PROTO_V3_RUSHMORE; | ||
| 2330 | alps_set_defaults(priv); | ||
| 2331 | |||
| 2332 | /* hack to make addr_command, nibble_command available */ | ||
| 2333 | psmouse->private = priv; | ||
| 2334 | |||
| 2335 | if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE)) | ||
| 2336 | priv->flags &= ~ALPS_DUALPOINT; | ||
| 2337 | |||
| 2338 | return 0; | ||
| 2339 | } else if (ec[0] == 0x88 && ec[1] == 0x07 && | ||
| 2340 | ec[2] >= 0x90 && ec[2] <= 0x9d) { | ||
| 2341 | priv->proto_version = ALPS_PROTO_V3; | ||
| 2342 | alps_set_defaults(priv); | ||
| 2343 | |||
| 2344 | return 0; | ||
| 2345 | } | 2351 | } |
| 2346 | 2352 | ||
| 2347 | psmouse_dbg(psmouse, | 2353 | /* Save the Firmware version */ |
| 2348 | "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); | 2354 | memcpy(priv->fw_ver, ec, 3); |
| 2349 | 2355 | ||
| 2350 | return -EINVAL; | 2356 | return alps_set_protocol(psmouse, priv, protocol); |
| 2351 | } | 2357 | } |
| 2352 | 2358 | ||
| 2353 | static int alps_reconnect(struct psmouse *psmouse) | 2359 | static int alps_reconnect(struct psmouse *psmouse) |
| @@ -2410,9 +2416,6 @@ int alps_init(struct psmouse *psmouse) | |||
| 2410 | goto init_fail; | 2416 | goto init_fail; |
| 2411 | 2417 | ||
| 2412 | priv->dev2 = dev2; | 2418 | priv->dev2 = dev2; |
| 2413 | setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); | ||
| 2414 | |||
| 2415 | psmouse->private = priv; | ||
| 2416 | 2419 | ||
| 2417 | psmouse_reset(psmouse); | 2420 | psmouse_reset(psmouse); |
| 2418 | 2421 | ||
