diff options
author | Jamie Lentin <jm@lentin.co.uk> | 2014-12-16 16:26:45 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-12-17 03:00:16 -0500 |
commit | e3cb0acd23258cf5e1a7ea270c98805eff01dcc5 (patch) | |
tree | 91f4a05fe9398b36c885ab6ac58dee0c1ae64972 | |
parent | 0349678ccd74d16c1f2bb58ecafec13ef7110e36 (diff) |
HID: lenovo: Add sensitivity control to compact keyboards
The trackpoint sensitivity can also be controlled, expose this via
sysfs.
Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-lenovo.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 4c55f4d95798..0f35a76d9c90 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c | |||
@@ -38,6 +38,7 @@ struct lenovo_drvdata_tpkbd { | |||
38 | 38 | ||
39 | struct lenovo_drvdata_cptkbd { | 39 | struct lenovo_drvdata_cptkbd { |
40 | bool fn_lock; | 40 | bool fn_lock; |
41 | int sensitivity; | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) | 44 | #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) |
@@ -145,6 +146,7 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev) | |||
145 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | 146 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); |
146 | 147 | ||
147 | ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); | 148 | ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); |
149 | ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); | ||
148 | if (ret) | 150 | if (ret) |
149 | hid_err(hdev, "Fn-lock setting failed: %d\n", ret); | 151 | hid_err(hdev, "Fn-lock setting failed: %d\n", ret); |
150 | } | 152 | } |
@@ -179,13 +181,50 @@ static ssize_t attr_fn_lock_store_cptkbd(struct device *dev, | |||
179 | return count; | 181 | return count; |
180 | } | 182 | } |
181 | 183 | ||
184 | static ssize_t attr_sensitivity_show_cptkbd(struct device *dev, | ||
185 | struct device_attribute *attr, | ||
186 | char *buf) | ||
187 | { | ||
188 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
189 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | ||
190 | |||
191 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
192 | cptkbd_data->sensitivity); | ||
193 | } | ||
194 | |||
195 | static ssize_t attr_sensitivity_store_cptkbd(struct device *dev, | ||
196 | struct device_attribute *attr, | ||
197 | const char *buf, | ||
198 | size_t count) | ||
199 | { | ||
200 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
201 | struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); | ||
202 | int value; | ||
203 | |||
204 | if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) | ||
205 | return -EINVAL; | ||
206 | |||
207 | cptkbd_data->sensitivity = value; | ||
208 | lenovo_features_set_cptkbd(hdev); | ||
209 | |||
210 | return count; | ||
211 | } | ||
212 | |||
213 | |||
182 | static struct device_attribute dev_attr_fn_lock_cptkbd = | 214 | static struct device_attribute dev_attr_fn_lock_cptkbd = |
183 | __ATTR(fn_lock, S_IWUSR | S_IRUGO, | 215 | __ATTR(fn_lock, S_IWUSR | S_IRUGO, |
184 | attr_fn_lock_show_cptkbd, | 216 | attr_fn_lock_show_cptkbd, |
185 | attr_fn_lock_store_cptkbd); | 217 | attr_fn_lock_store_cptkbd); |
186 | 218 | ||
219 | static struct device_attribute dev_attr_sensitivity_cptkbd = | ||
220 | __ATTR(sensitivity, S_IWUSR | S_IRUGO, | ||
221 | attr_sensitivity_show_cptkbd, | ||
222 | attr_sensitivity_store_cptkbd); | ||
223 | |||
224 | |||
187 | static struct attribute *lenovo_attributes_cptkbd[] = { | 225 | static struct attribute *lenovo_attributes_cptkbd[] = { |
188 | &dev_attr_fn_lock_cptkbd.attr, | 226 | &dev_attr_fn_lock_cptkbd.attr, |
227 | &dev_attr_sensitivity_cptkbd.attr, | ||
189 | NULL | 228 | NULL |
190 | }; | 229 | }; |
191 | 230 | ||
@@ -594,8 +633,9 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev) | |||
594 | if (ret) | 633 | if (ret) |
595 | hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); | 634 | hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); |
596 | 635 | ||
597 | /* Turn Fn-Lock on by default */ | 636 | /* Set keyboard settings to known state */ |
598 | cptkbd_data->fn_lock = true; | 637 | cptkbd_data->fn_lock = true; |
638 | cptkbd_data->sensitivity = 0x05; | ||
599 | lenovo_features_set_cptkbd(hdev); | 639 | lenovo_features_set_cptkbd(hdev); |
600 | 640 | ||
601 | ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); | 641 | ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); |