summaryrefslogtreecommitdiffstats
path: root/Documentation/input/appletouch.txt
blob: b13de3f89108df1e7b9cd585c97aa81b458261d9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
Apple Touchpad Driver (appletouch)
----------------------------------
	Copyright (C) 2005 Stelian Pop <stelian@popies.net>

appletouch is a Linux kernel driver for the USB touchpad found on post
February 2005 and October 2005 Apple Aluminium Powerbooks.

This driver is derived from Johannes Berg's appletrackpad driver[1], but it has
been improved in some areas:
	* appletouch is a full kernel driver, no userspace program is necessary
	* appletouch can be interfaced with the synaptics X11 driver, in order
	  to have touchpad acceleration, scrolling, etc.

Credits go to Johannes Berg for reverse-engineering the touchpad protocol,
Frank Arnold for further improvements, and Alex Harper for some additional
information about the inner workings of the touchpad sensors. Michael
Hanselmann added support for the October 2005 models.

Usage:
------

In order to use the touchpad in the basic mode, compile the driver and load
the module. A new input device will be detected and you will be able to read
the mouse data from /dev/input/mice (using gpm, or X11).

In X11, you can configure the touchpad to use the synaptics X11 driver, which
will give additional functionalities, like acceleration, scrolling, 2 finger
tap for middle button mouse emulation, 3 finger tap for right button mouse
emulation, etc. In order to do this, make sure you're using a recent version of
the synaptics driver (tested with 0.14.2, available from [2]), and configure a
new input device in your X11 configuration file (take a look below for an
example). For additional configuration, see the synaptics driver documentation.

	Section "InputDevice"
        	Identifier      "Synaptics Touchpad"
	        Driver          "synaptics"
		Option          "SendCoreEvents"        "true"
		Option          "Device"                "/dev/input/mice"
		Option          "Protocol"              "auto-dev"
		Option		"LeftEdge"		"0"
		Option		"RightEdge"		"850"
		Option		"TopEdge"		"0"
		Option		"BottomEdge"		"645"
		Option		"MinSpeed"		"0.4"
		Option		"MaxSpeed"		"1"
		Option		"AccelFactor"		"0.02"
		Option		"FingerLow"		"0"
		Option		"FingerHigh"		"30"
		Option		"MaxTapMove"		"20"
		Option		"MaxTapTime"		"100"
		Option		"HorizScrollDelta"	"0"
		Option		"VertScrollDelta"	"30"
		Option		"SHMConfig"		"on"
	EndSection

	Section "ServerLayout"
		...
		InputDevice	"Mouse"
		InputDevice	"Synaptics Touchpad"
	...
	EndSection

Fuzz problems:
--------------

The touchpad sensors are very sensitive to heat, and will generate a lot of
noise when the temperature changes. This is especially true when you power-on
the laptop for the first time.

The appletouch driver tries to handle this noise and auto adapt itself, but it
is not perfect. If finger movements are not recognized anymore, try reloading
the driver.

You can activate debugging using the 'debug' module parameter. A value of 0
deactivates any debugging, 1 activates tracing of invalid samples, 2 activates
full tracing (each sample is being traced):
	modprobe appletouch debug=1
		or
	echo "1" > /sys/module/appletouch/parameters/debug

Links:
------

[1]: http://johannes.sipsolutions.net/PowerBook/touchpad/
[2]: http://web.archive.org/web/*/http://web.telia.com/~u89404340/touchpad/index.html
^
4c2a7e72d593 ^




4865ecf1315b ^
071df104f808 ^

3ea056c50476 ^
071df104f808 ^
bcf58e725ddc ^
bb96a6f50be2 ^
071df104f808 ^

f7af3d1c0313 ^
98f842e675f9 ^
071df104f808 ^
df75e7748bae ^
f7af3d1c0313 ^




4c2a7e72d593 ^
467e9f4b5086 ^
f7af3d1c0313 ^
467e9f4b5086 ^
6344c433a452 ^
f7af3d1c0313 ^

98f842e675f9 ^
f7af3d1c0313 ^
33c429405a2c ^

efc63c4fb0f9 ^
467e9f4b5086 ^
bcf58e725ddc ^
efc63c4fb0f9 ^
071df104f808 ^
f7af3d1c0313 ^

3ea056c50476 ^
f7af3d1c0313 ^



071df104f808 ^


4865ecf1315b ^




bb96a6f50be2 ^
bcf58e725ddc ^
4865ecf1315b ^
071df104f808 ^
4865ecf1315b ^
e3222c4ecc64 ^
4865ecf1315b ^

071df104f808 ^
e3222c4ecc64 ^
071df104f808 ^
bcf58e725ddc ^
071df104f808 ^
071df104f808 ^
e3222c4ecc64 ^
4865ecf1315b ^






f7af3d1c0313 ^
59607db367c5 ^
6344c433a452 ^
3ea056c50476 ^
4865ecf1315b ^
34482e89a521 ^
3c0411846118 ^




64964528b24e ^
34482e89a521 ^



728dba3a39c6 ^

34482e89a521 ^



728dba3a39c6 ^
34482e89a521 ^
3c0411846118 ^
34482e89a521 ^

64964528b24e ^
34482e89a521 ^
3c0411846118 ^
34482e89a521 ^

64964528b24e ^
34482e89a521 ^
3c0411846118 ^
142e1d1d5f08 ^
5e4a08476b50 ^
c7b96acf1456 ^
142e1d1d5f08 ^

34482e89a521 ^





bcac25a58bfc ^




34482e89a521 ^





bcac25a58bfc ^
34482e89a521 ^
3ea056c50476 ^









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183










                                                                  
                         

                          
                      
                       
                       
                                 
                          
                             
 

                                                       









                                                                     



                                                
                                                            




                                         
  

                                                                    
                                                                           
   
                                                                         
                                                                       

                                 
                                
                
 
                      




                                              
                             
                
                              
 
                                     

                               
 
                              

                                       
                            
                                                           
                                           
                          
                  

          
                                          



                                    


  




                                                            
                                                       
                                                                     
 
                                     
 
                        

                           
                                    
                              
 
                                               
 
                           
                      






                                                            
                                        
                                 
                              
                                          
 
 




                                                                   
                                                            



                                        

                                



                                     
                          
 
                                   

 
                                           
 
                                  

 
                                                                        
 
                                                  
 
                                                      
                                                          

                              





                                    




                                                               





                                                    
                                      
  









                                                                         
/*
 *  Copyright (C) 2004 IBM Corporation
 *
 *  Author: Serge Hallyn <serue@us.ibm.com>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation, version 2 of the
 *  License.
 */

#include <linux/export.h>
#include <linux/uts.h>
#include <linux/utsname.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/cred.h>
#include <linux/user_namespace.h>
#include <linux/proc_ns.h>
#include <linux/sched/task.h>

static struct kmem_cache *uts_ns_cache __ro_after_init;

static struct ucounts *inc_uts_namespaces(struct user_namespace *ns)
{
	return inc_ucount(ns, current_euid(), UCOUNT_UTS_NAMESPACES);
}

static void dec_uts_namespaces(struct ucounts *ucounts)
{
	dec_ucount(ucounts, UCOUNT_UTS_NAMESPACES);
}

static struct uts_namespace *create_uts_ns(void)
{
	struct uts_namespace *uts_ns;

	uts_ns = kmem_cache_alloc(uts_ns_cache, GFP_KERNEL);
	if (uts_ns)
		kref_init(&uts_ns->kref);
	return uts_ns;
}

/*
 * Clone a new ns copying an original utsname, setting refcount to 1
 * @old_ns: namespace to clone
 * Return ERR_PTR(-ENOMEM) on error (failure to allocate), new ns otherwise
 */
static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
					  struct uts_namespace *old_ns)
{
	struct uts_namespace *ns;
	struct ucounts *ucounts;
	int err;

	err = -ENOSPC;
	ucounts = inc_uts_namespaces(user_ns);
	if (!ucounts)
		goto fail;

	err = -ENOMEM;
	ns = create_uts_ns();
	if (!ns)
		goto fail_dec;

	err = ns_alloc_inum(&ns->ns);
	if (err)
		goto fail_free;

	ns->ucounts = ucounts;
	ns->ns.ops = &utsns_operations;

	down_read(&uts_sem);
	memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
	ns->user_ns = get_user_ns(user_ns);
	up_read(&uts_sem);
	return ns;

fail_free:
	kmem_cache_free(uts_ns_cache, ns);
fail_dec:
	dec_uts_namespaces(ucounts);
fail:
	return ERR_PTR(err);
}

/*
 * Copy task tsk's utsname namespace, or clone it if flags
 * specifies CLONE_NEWUTS.  In latter case, changes to the
 * utsname of this process won't be seen by parent, and vice
 * versa.
 */
struct uts_namespace *copy_utsname(unsigned long flags,
	struct user_namespace *user_ns, struct uts_namespace *old_ns)
{
	struct uts_namespace *new_ns;

	BUG_ON(!old_ns);
	get_uts_ns(old_ns);

	if (!(flags & CLONE_NEWUTS))
		return old_ns;

	new_ns = clone_uts_ns(user_ns, old_ns);

	put_uts_ns(old_ns);
	return new_ns;
}

void free_uts_ns(struct kref *kref)
{
	struct uts_namespace *ns;

	ns = container_of(kref, struct uts_namespace, kref);
	dec_uts_namespaces(ns->ucounts);
	put_user_ns(ns->user_ns);
	ns_free_inum(&ns->ns);
	kmem_cache_free(uts_ns_cache, ns);
}

static inline struct uts_namespace *to_uts_ns(struct ns_common *ns)
{
	return container_of(ns, struct uts_namespace, ns);
}

static struct ns_common *utsns_get(struct task_struct *task)
{
	struct uts_namespace *ns = NULL;
	struct nsproxy *nsproxy;

	task_lock(task);
	nsproxy = task->nsproxy;
	if (nsproxy) {
		ns = nsproxy->uts_ns;
		get_uts_ns(ns);
	}
	task_unlock(task);

	return ns ? &ns->ns : NULL;
}

static void utsns_put(struct ns_common *ns)
{
	put_uts_ns(to_uts_ns(ns));
}

static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new)
{
	struct uts_namespace *ns = to_uts_ns(new);

	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
	    !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
		return -EPERM;

	get_uts_ns(ns);
	put_uts_ns(nsproxy->uts_ns);
	nsproxy->uts_ns = ns;
	return 0;
}

static struct user_namespace *utsns_owner(struct ns_common *ns)
{
	return to_uts_ns(ns)->user_ns;
}

const struct proc_ns_operations utsns_operations = {
	.name		= "uts",
	.type		= CLONE_NEWUTS,
	.get		= utsns_get,
	.put		= utsns_put,
	.install	= utsns_install,
	.owner		= utsns_owner,
};

void __init uts_ns_init(void)
{
	uts_ns_cache = kmem_cache_create_usercopy(
			"uts_namespace", sizeof(struct uts_namespace), 0,
			SLAB_PANIC|SLAB_ACCOUNT,
			offsetof(struct uts_namespace, name),
			sizeof_field(struct uts_namespace, name),
			NULL);
}