summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-logitech-hidpp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-logitech-hidpp.c')
-rw-r--r--drivers/hid/hid-logitech-hidpp.c248
1 files changed, 140 insertions, 108 deletions
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 0179f7ed77e5..8e91e2f06cb4 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -1669,6 +1669,7 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
1669 1669
1670#define HIDPP_FF_EFFECTID_NONE -1 1670#define HIDPP_FF_EFFECTID_NONE -1
1671#define HIDPP_FF_EFFECTID_AUTOCENTER -2 1671#define HIDPP_FF_EFFECTID_AUTOCENTER -2
1672#define HIDPP_AUTOCENTER_PARAMS_LENGTH 18
1672 1673
1673#define HIDPP_FF_MAX_PARAMS 20 1674#define HIDPP_FF_MAX_PARAMS 20
1674#define HIDPP_FF_RESERVED_SLOTS 1 1675#define HIDPP_FF_RESERVED_SLOTS 1
@@ -2009,7 +2010,7 @@ static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id)
2009static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude) 2010static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude)
2010{ 2011{
2011 struct hidpp_ff_private_data *data = dev->ff->private; 2012 struct hidpp_ff_private_data *data = dev->ff->private;
2012 u8 params[18]; 2013 u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH];
2013 2014
2014 dbg_hid("Setting autocenter to %d.\n", magnitude); 2015 dbg_hid("Setting autocenter to %d.\n", magnitude);
2015 2016
@@ -2077,23 +2078,34 @@ static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, hidpp
2077static void hidpp_ff_destroy(struct ff_device *ff) 2078static void hidpp_ff_destroy(struct ff_device *ff)
2078{ 2079{
2079 struct hidpp_ff_private_data *data = ff->private; 2080 struct hidpp_ff_private_data *data = ff->private;
2081 struct hid_device *hid = data->hidpp->hid_dev;
2080 2082
2083 hid_info(hid, "Unloading HID++ force feedback.\n");
2084
2085 device_remove_file(&hid->dev, &dev_attr_range);
2086 destroy_workqueue(data->wq);
2081 kfree(data->effect_ids); 2087 kfree(data->effect_ids);
2082} 2088}
2083 2089
2084static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) 2090static int hidpp_ff_init(struct hidpp_device *hidpp,
2091 struct hidpp_ff_private_data *data)
2085{ 2092{
2086 struct hid_device *hid = hidpp->hid_dev; 2093 struct hid_device *hid = hidpp->hid_dev;
2087 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); 2094 struct hid_input *hidinput;
2088 struct input_dev *dev = hidinput->input; 2095 struct input_dev *dev;
2089 const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); 2096 const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
2090 const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); 2097 const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
2091 struct ff_device *ff; 2098 struct ff_device *ff;
2092 struct hidpp_report response; 2099 int error, j, num_slots = data->num_effects;
2093 struct hidpp_ff_private_data *data;
2094 int error, j, num_slots;
2095 u8 version; 2100 u8 version;
2096 2101
2102 if (list_empty(&hid->inputs)) {
2103 hid_err(hid, "no inputs found\n");
2104 return -ENODEV;
2105 }
2106 hidinput = list_entry(hid->inputs.next, struct hid_input, list);
2107 dev = hidinput->input;
2108
2097 if (!dev) { 2109 if (!dev) {
2098 hid_err(hid, "Struct input_dev not set!\n"); 2110 hid_err(hid, "Struct input_dev not set!\n");
2099 return -EINVAL; 2111 return -EINVAL;
@@ -2109,27 +2121,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
2109 for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++) 2121 for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++)
2110 set_bit(hidpp_ff_effects_v2[j], dev->ffbit); 2122 set_bit(hidpp_ff_effects_v2[j], dev->ffbit);
2111 2123
2112 /* Read number of slots available in device */
2113 error = hidpp_send_fap_command_sync(hidpp, feature_index,
2114 HIDPP_FF_GET_INFO, NULL, 0, &response);
2115 if (error) {
2116 if (error < 0)
2117 return error;
2118 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
2119 __func__, error);
2120 return -EPROTO;
2121 }
2122
2123 num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
2124
2125 error = input_ff_create(dev, num_slots); 2124 error = input_ff_create(dev, num_slots);
2126 2125
2127 if (error) { 2126 if (error) {
2128 hid_err(dev, "Failed to create FF device!\n"); 2127 hid_err(dev, "Failed to create FF device!\n");
2129 return error; 2128 return error;
2130 } 2129 }
2131 2130 /*
2132 data = kzalloc(sizeof(*data), GFP_KERNEL); 2131 * Create a copy of passed data, so we can transfer memory
2132 * ownership to FF core
2133 */
2134 data = kmemdup(data, sizeof(*data), GFP_KERNEL);
2133 if (!data) 2135 if (!data)
2134 return -ENOMEM; 2136 return -ENOMEM;
2135 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); 2137 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL);
@@ -2145,10 +2147,7 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
2145 } 2147 }
2146 2148
2147 data->hidpp = hidpp; 2149 data->hidpp = hidpp;
2148 data->feature_index = feature_index;
2149 data->version = version; 2150 data->version = version;
2150 data->slot_autocenter = 0;
2151 data->num_effects = num_slots;
2152 for (j = 0; j < num_slots; j++) 2151 for (j = 0; j < num_slots; j++)
2153 data->effect_ids[j] = -1; 2152 data->effect_ids[j] = -1;
2154 2153
@@ -2162,68 +2161,20 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
2162 ff->set_autocenter = hidpp_ff_set_autocenter; 2161 ff->set_autocenter = hidpp_ff_set_autocenter;
2163 ff->destroy = hidpp_ff_destroy; 2162 ff->destroy = hidpp_ff_destroy;
2164 2163
2165
2166 /* reset all forces */
2167 error = hidpp_send_fap_command_sync(hidpp, feature_index,
2168 HIDPP_FF_RESET_ALL, NULL, 0, &response);
2169
2170 /* Read current Range */
2171 error = hidpp_send_fap_command_sync(hidpp, feature_index,
2172 HIDPP_FF_GET_APERTURE, NULL, 0, &response);
2173 if (error)
2174 hid_warn(hidpp->hid_dev, "Failed to read range from device!\n");
2175 data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]);
2176
2177 /* Create sysfs interface */ 2164 /* Create sysfs interface */
2178 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); 2165 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
2179 if (error) 2166 if (error)
2180 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error); 2167 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error);
2181 2168
2182 /* Read the current gain values */
2183 error = hidpp_send_fap_command_sync(hidpp, feature_index,
2184 HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response);
2185 if (error)
2186 hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n");
2187 data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]);
2188 /* ignore boost value at response.fap.params[2] */
2189
2190 /* init the hardware command queue */ 2169 /* init the hardware command queue */
2191 atomic_set(&data->workqueue_size, 0); 2170 atomic_set(&data->workqueue_size, 0);
2192 2171
2193 /* initialize with zero autocenter to get wheel in usable state */
2194 hidpp_ff_set_autocenter(dev, 0);
2195
2196 hid_info(hid, "Force feedback support loaded (firmware release %d).\n", 2172 hid_info(hid, "Force feedback support loaded (firmware release %d).\n",
2197 version); 2173 version);
2198 2174
2199 return 0; 2175 return 0;
2200} 2176}
2201 2177
2202static int hidpp_ff_deinit(struct hid_device *hid)
2203{
2204 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
2205 struct input_dev *dev = hidinput->input;
2206 struct hidpp_ff_private_data *data;
2207
2208 if (!dev) {
2209 hid_err(hid, "Struct input_dev not found!\n");
2210 return -EINVAL;
2211 }
2212
2213 hid_info(hid, "Unloading HID++ force feedback.\n");
2214 data = dev->ff->private;
2215 if (!data) {
2216 hid_err(hid, "Private data not found!\n");
2217 return -EINVAL;
2218 }
2219
2220 destroy_workqueue(data->wq);
2221 device_remove_file(&hid->dev, &dev_attr_range);
2222
2223 return 0;
2224}
2225
2226
2227/* ************************************************************************** */ 2178/* ************************************************************************** */
2228/* */ 2179/* */
2229/* Device Support */ 2180/* Device Support */
@@ -2725,24 +2676,93 @@ static int k400_connect(struct hid_device *hdev, bool connected)
2725 2676
2726#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 2677#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
2727 2678
2728static int g920_get_config(struct hidpp_device *hidpp) 2679static int g920_ff_set_autocenter(struct hidpp_device *hidpp,
2680 struct hidpp_ff_private_data *data)
2729{ 2681{
2682 struct hidpp_report response;
2683 u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH] = {
2684 [1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART,
2685 };
2686 int ret;
2687
2688 /* initialize with zero autocenter to get wheel in usable state */
2689
2690 dbg_hid("Setting autocenter to 0.\n");
2691 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2692 HIDPP_FF_DOWNLOAD_EFFECT,
2693 params, ARRAY_SIZE(params),
2694 &response);
2695 if (ret)
2696 hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n");
2697 else
2698 data->slot_autocenter = response.fap.params[0];
2699
2700 return ret;
2701}
2702
2703static int g920_get_config(struct hidpp_device *hidpp,
2704 struct hidpp_ff_private_data *data)
2705{
2706 struct hidpp_report response;
2730 u8 feature_type; 2707 u8 feature_type;
2731 u8 feature_index;
2732 int ret; 2708 int ret;
2733 2709
2710 memset(data, 0, sizeof(*data));
2711
2734 /* Find feature and store for later use */ 2712 /* Find feature and store for later use */
2735 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, 2713 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK,
2736 &feature_index, &feature_type); 2714 &data->feature_index, &feature_type);
2737 if (ret) 2715 if (ret)
2738 return ret; 2716 return ret;
2739 2717
2740 ret = hidpp_ff_init(hidpp, feature_index); 2718 /* Read number of slots available in device */
2719 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2720 HIDPP_FF_GET_INFO,
2721 NULL, 0,
2722 &response);
2723 if (ret) {
2724 if (ret < 0)
2725 return ret;
2726 hid_err(hidpp->hid_dev,
2727 "%s: received protocol error 0x%02x\n", __func__, ret);
2728 return -EPROTO;
2729 }
2730
2731 data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
2732
2733 /* reset all forces */
2734 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2735 HIDPP_FF_RESET_ALL,
2736 NULL, 0,
2737 &response);
2741 if (ret) 2738 if (ret)
2742 hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n", 2739 hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n");
2743 ret);
2744 2740
2745 return 0; 2741 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2742 HIDPP_FF_GET_APERTURE,
2743 NULL, 0,
2744 &response);
2745 if (ret) {
2746 hid_warn(hidpp->hid_dev,
2747 "Failed to read range from device!\n");
2748 }
2749 data->range = ret ?
2750 900 : get_unaligned_be16(&response.fap.params[0]);
2751
2752 /* Read the current gain values */
2753 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2754 HIDPP_FF_GET_GLOBAL_GAINS,
2755 NULL, 0,
2756 &response);
2757 if (ret)
2758 hid_warn(hidpp->hid_dev,
2759 "Failed to read gain values from device!\n");
2760 data->gain = ret ?
2761 0xffff : get_unaligned_be16(&response.fap.params[0]);
2762
2763 /* ignore boost value at response.fap.params[2] */
2764
2765 return g920_ff_set_autocenter(hidpp, data);
2746} 2766}
2747 2767
2748/* -------------------------------------------------------------------------- */ 2768/* -------------------------------------------------------------------------- */
@@ -3458,34 +3478,45 @@ static int hidpp_get_report_length(struct hid_device *hdev, int id)
3458 return report->field[0]->report_count + 1; 3478 return report->field[0]->report_count + 1;
3459} 3479}
3460 3480
3461static bool hidpp_validate_report(struct hid_device *hdev, int id, 3481static bool hidpp_validate_device(struct hid_device *hdev)
3462 int expected_length, bool optional)
3463{ 3482{
3464 int report_length; 3483 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3484 int id, report_length, supported_reports = 0;
3465 3485
3466 if (id >= HID_MAX_IDS || id < 0) { 3486 id = REPORT_ID_HIDPP_SHORT;
3467 hid_err(hdev, "invalid HID report id %u\n", id); 3487 report_length = hidpp_get_report_length(hdev, id);
3468 return false; 3488 if (report_length) {
3489 if (report_length < HIDPP_REPORT_SHORT_LENGTH)
3490 goto bad_device;
3491
3492 supported_reports++;
3469 } 3493 }
3470 3494
3495 id = REPORT_ID_HIDPP_LONG;
3471 report_length = hidpp_get_report_length(hdev, id); 3496 report_length = hidpp_get_report_length(hdev, id);
3472 if (!report_length) 3497 if (report_length) {
3473 return optional; 3498 if (report_length < HIDPP_REPORT_LONG_LENGTH)
3499 goto bad_device;
3474 3500
3475 if (report_length < expected_length) { 3501 supported_reports++;
3476 hid_warn(hdev, "not enough values in hidpp report %d\n", id);
3477 return false;
3478 } 3502 }
3479 3503
3480 return true; 3504 id = REPORT_ID_HIDPP_VERY_LONG;
3481} 3505 report_length = hidpp_get_report_length(hdev, id);
3506 if (report_length) {
3507 if (report_length < HIDPP_REPORT_LONG_LENGTH ||
3508 report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH)
3509 goto bad_device;
3482 3510
3483static bool hidpp_validate_device(struct hid_device *hdev) 3511 supported_reports++;
3484{ 3512 hidpp->very_long_report_length = report_length;
3485 return hidpp_validate_report(hdev, REPORT_ID_HIDPP_SHORT, 3513 }
3486 HIDPP_REPORT_SHORT_LENGTH, false) && 3514
3487 hidpp_validate_report(hdev, REPORT_ID_HIDPP_LONG, 3515 return supported_reports;
3488 HIDPP_REPORT_LONG_LENGTH, true); 3516
3517bad_device:
3518 hid_warn(hdev, "not enough values in hidpp report %d\n", id);
3519 return false;
3489} 3520}
3490 3521
3491static bool hidpp_application_equals(struct hid_device *hdev, 3522static bool hidpp_application_equals(struct hid_device *hdev,
@@ -3505,6 +3536,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
3505 int ret; 3536 int ret;
3506 bool connected; 3537 bool connected;
3507 unsigned int connect_mask = HID_CONNECT_DEFAULT; 3538 unsigned int connect_mask = HID_CONNECT_DEFAULT;
3539 struct hidpp_ff_private_data data;
3508 3540
3509 /* report_fixup needs drvdata to be set before we call hid_parse */ 3541 /* report_fixup needs drvdata to be set before we call hid_parse */
3510 hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); 3542 hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
@@ -3531,11 +3563,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
3531 return hid_hw_start(hdev, HID_CONNECT_DEFAULT); 3563 return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
3532 } 3564 }
3533 3565
3534 hidpp->very_long_report_length =
3535 hidpp_get_report_length(hdev, REPORT_ID_HIDPP_VERY_LONG);
3536 if (hidpp->very_long_report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH)
3537 hidpp->very_long_report_length = HIDPP_REPORT_VERY_LONG_MAX_LENGTH;
3538
3539 if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) 3566 if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE)
3540 hidpp->quirks |= HIDPP_QUIRK_UNIFYING; 3567 hidpp->quirks |= HIDPP_QUIRK_UNIFYING;
3541 3568
@@ -3614,7 +3641,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
3614 if (ret) 3641 if (ret)
3615 goto hid_hw_init_fail; 3642 goto hid_hw_init_fail;
3616 } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { 3643 } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
3617 ret = g920_get_config(hidpp); 3644 ret = g920_get_config(hidpp, &data);
3618 if (ret) 3645 if (ret)
3619 goto hid_hw_init_fail; 3646 goto hid_hw_init_fail;
3620 } 3647 }
@@ -3636,6 +3663,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
3636 goto hid_hw_start_fail; 3663 goto hid_hw_start_fail;
3637 } 3664 }
3638 3665
3666 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3667 ret = hidpp_ff_init(hidpp, &data);
3668 if (ret)
3669 hid_warn(hidpp->hid_dev,
3670 "Unable to initialize force feedback support, errno %d\n",
3671 ret);
3672 }
3673
3639 return ret; 3674 return ret;
3640 3675
3641hid_hw_init_fail: 3676hid_hw_init_fail:
@@ -3658,9 +3693,6 @@ static void hidpp_remove(struct hid_device *hdev)
3658 3693
3659 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); 3694 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
3660 3695
3661 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)
3662 hidpp_ff_deinit(hdev);
3663
3664 hid_hw_stop(hdev); 3696 hid_hw_stop(hdev);
3665 cancel_work_sync(&hidpp->work); 3697 cancel_work_sync(&hidpp->work);
3666 mutex_destroy(&hidpp->send_mutex); 3698 mutex_destroy(&hidpp->send_mutex);