View | Details | Raw Unified | Return to bug 231058 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/dev/atkbdc/atkbdc.c (-1 / +75 lines)
Lines 296-301 atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, Link Here
296
	    sc->lock = FALSE;
296
	    sc->lock = FALSE;
297
	    sc->kbd.head = sc->kbd.tail = 0;
297
	    sc->kbd.head = sc->kbd.tail = 0;
298
	    sc->aux.head = sc->aux.tail = 0;
298
	    sc->aux.head = sc->aux.tail = 0;
299
	    sc->aux_mux_enabled = 0;
299
#if KBDIO_DEBUG >= 2
300
#if KBDIO_DEBUG >= 2
300
	    sc->kbd.call_count = 0;
301
	    sc->kbd.call_count = 0;
301
	    sc->kbd.qcount = sc->kbd.max_qcount = 0;
302
	    sc->kbd.qcount = sc->kbd.max_qcount = 0;
Lines 570-575 wait_for_aux_data(struct atkbdc_softc *kbdc) Link Here
570
    	    return 0;
571
    	    return 0;
571
    }
572
    }
572
    DELAY(KBDD_DELAYTIME);
573
    DELAY(KBDD_DELAYTIME);
574
573
    return f;
575
    return f;
574
}
576
}
575
577
Lines 639-645 write_kbd_command(KBDC p, int c) Link Here
639
int
641
int
640
write_aux_command(KBDC p, int c)
642
write_aux_command(KBDC p, int c)
641
{
643
{
642
    if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
644
    int f;
645
646
    f = kbdcp(p)->aux_mux_enabled ?
647
        KBDC_WRITE_TO_AUX_MUX + kbdcp(p)->aux_mux_port : KBDC_WRITE_TO_AUX;
648
649
    if (!write_controller_command(p, f))
643
	return FALSE;
650
	return FALSE;
644
    return write_controller_data(p, c);
651
    return write_controller_data(p, c);
645
}
652
}
Lines 1201-1203 set_controller_command_byte(KBDC p, int mask, int command) Link Here
1201
1208
1202
    return TRUE;
1209
    return TRUE;
1203
}
1210
}
1211
1212
/*
1213
 * Rudimentary support for active PS/2 multiplexing
1214
 */
1215
static int
1216
set_aux_mux_state(KBDC p, int enabled)
1217
{
1218
    int command, version;
1219
1220
    if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
1221
        write_controller_data(p, 0xF0) == 0 ||
1222
        read_controller_data(p) != 0xF0)
1223
        return -1;
1224
1225
    command = enabled ? 0x56 : 0xf6;
1226
    if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
1227
        write_controller_data(p, command) == 0 ||
1228
        read_controller_data(p) != command)
1229
        return -1;
1230
1231
    command = enabled ? 0xa4 : 0xa5;
1232
    if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
1233
        write_controller_data(p, command) == 0 ||
1234
        (version = read_controller_data(p)) == command)
1235
        return -1;
1236
1237
    return version;
1238
}
1239
1240
int
1241
set_active_aux_mux_port(KBDC p, int port)
1242
{
1243
1244
    if (!kbdcp(p)->aux_mux_enabled)
1245
        return FALSE;
1246
1247
    if (port < 0 || port >= KBDC_AUX_MUX_NUM_PORTS)
1248
        return FALSE;
1249
1250
    kbdcp(p)->aux_mux_port = port;
1251
1252
    return TRUE;
1253
}
1254
1255
/* Checks for active multiplexing support and enables it */
1256
int
1257
enable_aux_mux(KBDC p)
1258
{
1259
    int version;
1260
1261
    version = set_aux_mux_state(p, TRUE);
1262
    if (version >= 0) {
1263
        kbdcp(p)->aux_mux_enabled = TRUE;
1264
        set_active_aux_mux_port(p, 0);
1265
    }
1266
1267
    return version;
1268
}
1269
1270
int
1271
disable_aux_mux(KBDC p)
1272
{
1273
1274
    kbdcp(p)->aux_mux_enabled = FALSE;
1275
1276
    return (set_aux_mux_state(p, FALSE));
1277
}
(-)b/sys/dev/atkbdc/atkbdcreg.h (+12 lines)
Lines 51-56 Link Here
51
/* controller commands (sent to KBD_COMMAND_PORT) */
51
/* controller commands (sent to KBD_COMMAND_PORT) */
52
#define KBDC_SET_COMMAND_BYTE 	0x0060
52
#define KBDC_SET_COMMAND_BYTE 	0x0060
53
#define KBDC_GET_COMMAND_BYTE 	0x0020
53
#define KBDC_GET_COMMAND_BYTE 	0x0020
54
#define KBDC_WRITE_TO_AUX_MUX	0x0090
55
#define KBDC_FORCE_AUX_OUTPUT	0x00d3
54
#define KBDC_WRITE_TO_AUX    	0x00d4
56
#define KBDC_WRITE_TO_AUX    	0x00d4
55
#define KBDC_DISABLE_AUX_PORT 	0x00a7
57
#define KBDC_DISABLE_AUX_PORT 	0x00a7
56
#define KBDC_ENABLE_AUX_PORT 	0x00a8
58
#define KBDC_ENABLE_AUX_PORT 	0x00a8
Lines 117-122 Link Here
117
#define KBDS_KBD_BUFFER_FULL	0x0001
119
#define KBDS_KBD_BUFFER_FULL	0x0001
118
#define KBDS_AUX_BUFFER_FULL	0x0021
120
#define KBDS_AUX_BUFFER_FULL	0x0021
119
#define KBDS_INPUT_BUFFER_FULL	0x0002
121
#define KBDS_INPUT_BUFFER_FULL	0x0002
122
#define KBDS_AUX_MUX_ERROR	0x0004
123
#define KBDS_AUX_MUX_PORT	0x00c0
120
124
121
/* return code */
125
/* return code */
122
#define KBD_ACK 		0x00fa
126
#define KBD_ACK 		0x00fa
Lines 209-214 typedef struct atkbdc_softc { Link Here
209
#define KBDC_QUIRK_IGNORE_PROBE_RESULT	(1 << 1)
213
#define KBDC_QUIRK_IGNORE_PROBE_RESULT	(1 << 1)
210
#define KBDC_QUIRK_RESET_AFTER_PROBE	(1 << 2)
214
#define KBDC_QUIRK_RESET_AFTER_PROBE	(1 << 2)
211
#define KBDC_QUIRK_SETLEDS_ON_INIT	(1 << 3)
215
#define KBDC_QUIRK_SETLEDS_ON_INIT	(1 << 3)
216
    int aux_mux_enabled;	/* active PS/2 multiplexing is enabled */
217
    int aux_mux_port;		/* current aux mux port */
212
} atkbdc_softc_t; 
218
} atkbdc_softc_t; 
213
219
214
enum kbdc_device_ivar {
220
enum kbdc_device_ivar {
Lines 223-228 typedef caddr_t KBDC; Link Here
223
#define KBDC_RID_KBD	0
229
#define KBDC_RID_KBD	0
224
#define KBDC_RID_AUX	1
230
#define KBDC_RID_AUX	1
225
231
232
#define KBDC_AUX_MUX_NUM_PORTS	4
233
226
/* function prototypes */
234
/* function prototypes */
227
235
228
atkbdc_softc_t *atkbdc_get_softc(int unit);
236
atkbdc_softc_t *atkbdc_get_softc(int unit);
Lines 268-273 void kbdc_set_device_mask(KBDC kbdc, int mask); Link Here
268
int get_controller_command_byte(KBDC kbdc);
276
int get_controller_command_byte(KBDC kbdc);
269
int set_controller_command_byte(KBDC kbdc, int command, int flag);
277
int set_controller_command_byte(KBDC kbdc, int command, int flag);
270
278
279
int set_active_aux_mux_port(KBDC p, int port);
280
int enable_aux_mux(KBDC p);
281
int disable_aux_mux(KBDC p);
282
271
#endif /* _KERNEL */
283
#endif /* _KERNEL */
272
284
273
#endif /* !_DEV_ATKBDC_ATKBDCREG_H_ */
285
#endif /* !_DEV_ATKBDC_ATKBDCREG_H_ */
(-)b/sys/dev/atkbdc/psm.c (+82 lines)
Lines 499-504 static int verbose = PSM_DEBUG; Link Here
499
static int synaptics_support = 0;
499
static int synaptics_support = 0;
500
static int trackpoint_support = 0;
500
static int trackpoint_support = 0;
501
static int elantech_support = 0;
501
static int elantech_support = 0;
502
static int force_mux_discovery = 0;
502
503
503
/* for backward compatibility */
504
/* for backward compatibility */
504
#define	OLD_MOUSE_GETHWINFO	_IOR('M', 1, old_mousehw_t)
505
#define	OLD_MOUSE_GETHWINFO	_IOR('M', 1, old_mousehw_t)
Lines 642-647 static probefunc_t enable_4dmouse; Link Here
642
static probefunc_t	enable_4dplus;
643
static probefunc_t	enable_4dplus;
643
static probefunc_t	enable_mmanplus;
644
static probefunc_t	enable_mmanplus;
644
static probefunc_t	enable_synaptics;
645
static probefunc_t	enable_synaptics;
646
static probefunc_t	enable_synaptics_mux;
645
static probefunc_t	enable_trackpoint;
647
static probefunc_t	enable_trackpoint;
646
static probefunc_t	enable_versapad;
648
static probefunc_t	enable_versapad;
647
static probefunc_t	enable_elantech;
649
static probefunc_t	enable_elantech;
Lines 674-679 static struct { Link Here
674
	  0x08, MOUSE_4D_PACKETSIZE, enable_4dmouse },
676
	  0x08, MOUSE_4D_PACKETSIZE, enable_4dmouse },
675
	{ MOUSE_MODEL_4DPLUS,		/* A4 Tech 4D+ Mouse */
677
	{ MOUSE_MODEL_4DPLUS,		/* A4 Tech 4D+ Mouse */
676
	  0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus },
678
	  0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus },
679
	{ MOUSE_MODEL_SYNAPTICS,	/* Synaptics Touchpad on Active Mux */
680
	  0x00, MOUSE_PS2_PACKETSIZE, enable_synaptics_mux },
677
	{ MOUSE_MODEL_SYNAPTICS,	/* Synaptics Touchpad */
681
	{ MOUSE_MODEL_SYNAPTICS,	/* Synaptics Touchpad */
678
	  0xc0, MOUSE_SYNAPTICS_PACKETSIZE, enable_synaptics },
682
	  0xc0, MOUSE_SYNAPTICS_PACKETSIZE, enable_synaptics },
679
	{ MOUSE_MODEL_ELANTECH,		/* Elantech Touchpad */
683
	{ MOUSE_MODEL_ELANTECH,		/* Elantech Touchpad */
Lines 2933-2938 SYSCTL_INT(_hw_psm, OID_AUTO, trackpoint_support, CTLFLAG_RDTUN, Link Here
2933
SYSCTL_INT(_hw_psm, OID_AUTO, elantech_support, CTLFLAG_RDTUN,
2937
SYSCTL_INT(_hw_psm, OID_AUTO, elantech_support, CTLFLAG_RDTUN,
2934
    &elantech_support, 0, "Enable support for Elantech touchpads");
2938
    &elantech_support, 0, "Enable support for Elantech touchpads");
2935
2939
2940
SYSCTL_INT(_hw_psm, OID_AUTO, force_mux_discovery, CTLFLAG_RDTUN,
2941
    &force_mux_discovery, 0, "Force probing of multiplexed PS/2 ports");
2942
2936
static void
2943
static void
2937
psmintr(void *arg)
2944
psmintr(void *arg)
2938
{
2945
{
Lines 2940-2946 psmintr(void *arg) Link Here
2940
	struct timeval now;
2947
	struct timeval now;
2941
	int c;
2948
	int c;
2942
	packetbuf_t *pb;
2949
	packetbuf_t *pb;
2950
	static int active_mode_logged = FALSE;
2943
2951
2952
	if (kbdcp(sc->kbdc)->aux_mux_enabled && !active_mode_logged) {
2953
		printf ("psm0: AUX IRQ fired in active multiplexing mode");
2954
		active_mode_logged = TRUE;
2955
	}
2944
2956
2945
	/* read until there is nothing to read */
2957
	/* read until there is nothing to read */
2946
	while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
2958
	while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
Lines 4933-4938 psmsoftintr(void *arg) Link Here
4933
			break;
4945
			break;
4934
4946
4935
		case MOUSE_MODEL_SYNAPTICS:
4947
		case MOUSE_MODEL_SYNAPTICS:
4948
			if (sc->mode.packetsize == 3) {
4949
				static u_char save[3];
4950
				if (pb->ipacket[0] & 0x08) {
4951
					/* Convert generic -> pass-through */
4952
					pb->ipacket[5] = pb->ipacket[2];
4953
					pb->ipacket[4] = pb->ipacket[1];
4954
					pb->ipacket[1] = pb->ipacket[0];
4955
					pb->ipacket[0] = 0x84 | (save[0] & 3);
4956
					pb->ipacket[3] = 0xc4 | (save[0] & 3);
4957
					pb->ipacket[2] = 0;
4958
				} else {
4959
					/* Join two 3-bytes absolute packets */
4960
					if (!(pb->ipacket[0] & 0x40)) {
4961
						bcopy(pb->ipacket, save, 3);
4962
						goto next;
4963
					}
4964
					bcopy(pb->ipacket, pb->ipacket + 3, 3);
4965
					bcopy(save, pb->ipacket, 3);
4966
					save[0] &= 0x03;
4967
				}
4968
				pb->inputbytes = 6;
4969
			}
4936
			if (proc_synaptics(sc, pb, &ms, &x, &y, &z) != 0) {
4970
			if (proc_synaptics(sc, pb, &ms, &x, &y, &z) != 0) {
4937
				VLOG(3, (LOG_DEBUG, "synaptics: "
4971
				VLOG(3, (LOG_DEBUG, "synaptics: "
4938
				    "packet rejected\n"));
4972
				    "packet rejected\n"));
Lines 6043-6048 synaptics_set_mode(struct psm_softc *sc, int mode_byte) { Link Here
6043
	}
6077
	}
6044
}
6078
}
6045
6079
6080
static int
6081
enable_synaptics_mux(struct psm_softc *sc, enum probearg arg)
6082
{
6083
	KBDC kbdc = sc->kbdc;
6084
	int status[3];
6085
	int port, probe = FALSE, version, has_trackpoint = FALSE;
6086
6087
	/*
6088
	 * Some HP laptops e.g. EB 8560w and 9470m have a trackpoint attached
6089
	 * to AUX multiplexer rather than to synaptics pass-through interface.
6090
	 * If active multiplexing mode is not activated this device produces
6091
	 * own response to synaptics identify query thus preventing synaptics
6092
	 * touchpad detection.
6093
	 */
6094
	set_mouse_scaling(kbdc, 1);
6095
	if (mouse_ext_command(kbdc, 0) &&
6096
	    get_mouse_status(kbdc, status, 0, 3) == 3 &&
6097
	    status[0] == 0x00 && status[1] == 0x46 && status[2] == 0x12)
6098
		has_trackpoint = TRUE;
6099
6100
	version = enable_aux_mux(kbdc);
6101
	if (version == -1)
6102
		return (FALSE);
6103
6104
	if (verbose >= 2)
6105
		printf("Active Multiplexing PS/2 controller v%d.%d\n",
6106
		    (version >> 4) & 0x0f, version & 0x0f);
6107
6108
	/* If trackpoint is detected we should scan AUX ports in active mode */
6109
	if (has_trackpoint || force_mux_discovery) {
6110
		for (port = 0; port < KBDC_AUX_MUX_NUM_PORTS; port++) {
6111
			VLOG(3, (LOG_DEBUG, "aux_mux: probe port %d\n", port));
6112
			set_active_aux_mux_port(kbdc, port);
6113
			probe = enable_synaptics(sc, arg);
6114
			if (probe) {
6115
				/* Relative mouses are mapped to passthrough */
6116
				sc->synhw.capPassthrough = 1;
6117
				break;
6118
			}
6119
		}
6120
	}
6121
6122
	/* Back to hidden multiplexing. Active one is not supported by reads */
6123
	disable_aux_mux(kbdc);
6124
6125
	return (probe);
6126
}
6127
6046
static int
6128
static int
6047
enable_synaptics(struct psm_softc *sc, enum probearg arg)
6129
enable_synaptics(struct psm_softc *sc, enum probearg arg)
6048
{
6130
{

Return to bug 231058