@@ -1669,6 +1669,7 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
16691669
16701670#define HIDPP_FF_EFFECTID_NONE -1
16711671#define HIDPP_FF_EFFECTID_AUTOCENTER -2
1672+ #define HIDPP_AUTOCENTER_PARAMS_LENGTH 18
16721673
16731674#define HIDPP_FF_MAX_PARAMS 20
16741675#define HIDPP_FF_RESERVED_SLOTS 1
@@ -2009,7 +2010,7 @@ static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id)
20092010static void hidpp_ff_set_autocenter (struct input_dev * dev , u16 magnitude )
20102011{
20112012 struct hidpp_ff_private_data * data = dev -> ff -> private ;
2012- u8 params [18 ];
2013+ u8 params [HIDPP_AUTOCENTER_PARAMS_LENGTH ];
20132014
20142015 dbg_hid ("Setting autocenter to %d.\n" , magnitude );
20152016
@@ -2081,17 +2082,16 @@ static void hidpp_ff_destroy(struct ff_device *ff)
20812082 kfree (data -> effect_ids );
20822083}
20832084
2084- static int hidpp_ff_init (struct hidpp_device * hidpp , u8 feature_index )
2085+ static int hidpp_ff_init (struct hidpp_device * hidpp ,
2086+ struct hidpp_ff_private_data * data )
20852087{
20862088 struct hid_device * hid = hidpp -> hid_dev ;
20872089 struct hid_input * hidinput ;
20882090 struct input_dev * dev ;
20892091 const struct usb_device_descriptor * udesc = & (hid_to_usb_dev (hid )-> descriptor );
20902092 const u16 bcdDevice = le16_to_cpu (udesc -> bcdDevice );
20912093 struct ff_device * ff ;
2092- struct hidpp_report response ;
2093- struct hidpp_ff_private_data * data ;
2094- int error , j , num_slots ;
2094+ int error , j , num_slots = data -> num_effects ;
20952095 u8 version ;
20962096
20972097 if (list_empty (& hid -> inputs )) {
@@ -2116,27 +2116,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
21162116 for (j = 0 ; hidpp_ff_effects_v2 [j ] >= 0 ; j ++ )
21172117 set_bit (hidpp_ff_effects_v2 [j ], dev -> ffbit );
21182118
2119- /* Read number of slots available in device */
2120- error = hidpp_send_fap_command_sync (hidpp , feature_index ,
2121- HIDPP_FF_GET_INFO , NULL , 0 , & response );
2122- if (error ) {
2123- if (error < 0 )
2124- return error ;
2125- hid_err (hidpp -> hid_dev , "%s: received protocol error 0x%02x\n" ,
2126- __func__ , error );
2127- return - EPROTO ;
2128- }
2129-
2130- num_slots = response .fap .params [0 ] - HIDPP_FF_RESERVED_SLOTS ;
2131-
21322119 error = input_ff_create (dev , num_slots );
21332120
21342121 if (error ) {
21352122 hid_err (dev , "Failed to create FF device!\n" );
21362123 return error ;
21372124 }
2138-
2139- data = kzalloc (sizeof (* data ), GFP_KERNEL );
2125+ /*
2126+ * Create a copy of passed data, so we can transfer memory
2127+ * ownership to FF core
2128+ */
2129+ data = kmemdup (data , sizeof (* data ), GFP_KERNEL );
21402130 if (!data )
21412131 return - ENOMEM ;
21422132 data -> effect_ids = kcalloc (num_slots , sizeof (int ), GFP_KERNEL );
@@ -2152,10 +2142,7 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
21522142 }
21532143
21542144 data -> hidpp = hidpp ;
2155- data -> feature_index = feature_index ;
21562145 data -> version = version ;
2157- data -> slot_autocenter = 0 ;
2158- data -> num_effects = num_slots ;
21592146 for (j = 0 ; j < num_slots ; j ++ )
21602147 data -> effect_ids [j ] = -1 ;
21612148
@@ -2169,37 +2156,14 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
21692156 ff -> set_autocenter = hidpp_ff_set_autocenter ;
21702157 ff -> destroy = hidpp_ff_destroy ;
21712158
2172-
2173- /* reset all forces */
2174- error = hidpp_send_fap_command_sync (hidpp , feature_index ,
2175- HIDPP_FF_RESET_ALL , NULL , 0 , & response );
2176-
2177- /* Read current Range */
2178- error = hidpp_send_fap_command_sync (hidpp , feature_index ,
2179- HIDPP_FF_GET_APERTURE , NULL , 0 , & response );
2180- if (error )
2181- hid_warn (hidpp -> hid_dev , "Failed to read range from device!\n" );
2182- data -> range = error ? 900 : get_unaligned_be16 (& response .fap .params [0 ]);
2183-
21842159 /* Create sysfs interface */
21852160 error = device_create_file (& (hidpp -> hid_dev -> dev ), & dev_attr_range );
21862161 if (error )
21872162 hid_warn (hidpp -> hid_dev , "Unable to create sysfs interface for \"range\", errno %d!\n" , error );
21882163
2189- /* Read the current gain values */
2190- error = hidpp_send_fap_command_sync (hidpp , feature_index ,
2191- HIDPP_FF_GET_GLOBAL_GAINS , NULL , 0 , & response );
2192- if (error )
2193- hid_warn (hidpp -> hid_dev , "Failed to read gain values from device!\n" );
2194- data -> gain = error ? 0xffff : get_unaligned_be16 (& response .fap .params [0 ]);
2195- /* ignore boost value at response.fap.params[2] */
2196-
21972164 /* init the hardware command queue */
21982165 atomic_set (& data -> workqueue_size , 0 );
21992166
2200- /* initialize with zero autocenter to get wheel in usable state */
2201- hidpp_ff_set_autocenter (dev , 0 );
2202-
22032167 hid_info (hid , "Force feedback support loaded (firmware release %d).\n" ,
22042168 version );
22052169
@@ -2732,24 +2696,93 @@ static int k400_connect(struct hid_device *hdev, bool connected)
27322696
27332697#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
27342698
2735- static int g920_get_config (struct hidpp_device * hidpp )
2699+ static int g920_ff_set_autocenter (struct hidpp_device * hidpp ,
2700+ struct hidpp_ff_private_data * data )
27362701{
2702+ struct hidpp_report response ;
2703+ u8 params [HIDPP_AUTOCENTER_PARAMS_LENGTH ] = {
2704+ [1 ] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART ,
2705+ };
2706+ int ret ;
2707+
2708+ /* initialize with zero autocenter to get wheel in usable state */
2709+
2710+ dbg_hid ("Setting autocenter to 0.\n" );
2711+ ret = hidpp_send_fap_command_sync (hidpp , data -> feature_index ,
2712+ HIDPP_FF_DOWNLOAD_EFFECT ,
2713+ params , ARRAY_SIZE (params ),
2714+ & response );
2715+ if (ret )
2716+ hid_warn (hidpp -> hid_dev , "Failed to autocenter device!\n" );
2717+ else
2718+ data -> slot_autocenter = response .fap .params [0 ];
2719+
2720+ return ret ;
2721+ }
2722+
2723+ static int g920_get_config (struct hidpp_device * hidpp ,
2724+ struct hidpp_ff_private_data * data )
2725+ {
2726+ struct hidpp_report response ;
27372727 u8 feature_type ;
2738- u8 feature_index ;
27392728 int ret ;
27402729
2730+ memset (data , 0 , sizeof (* data ));
2731+
27412732 /* Find feature and store for later use */
27422733 ret = hidpp_root_get_feature (hidpp , HIDPP_PAGE_G920_FORCE_FEEDBACK ,
2743- & feature_index , & feature_type );
2734+ & data -> feature_index , & feature_type );
27442735 if (ret )
27452736 return ret ;
27462737
2747- ret = hidpp_ff_init (hidpp , feature_index );
2738+ /* Read number of slots available in device */
2739+ ret = hidpp_send_fap_command_sync (hidpp , data -> feature_index ,
2740+ HIDPP_FF_GET_INFO ,
2741+ NULL , 0 ,
2742+ & response );
2743+ if (ret ) {
2744+ if (ret < 0 )
2745+ return ret ;
2746+ hid_err (hidpp -> hid_dev ,
2747+ "%s: received protocol error 0x%02x\n" , __func__ , ret );
2748+ return - EPROTO ;
2749+ }
2750+
2751+ data -> num_effects = response .fap .params [0 ] - HIDPP_FF_RESERVED_SLOTS ;
2752+
2753+ /* reset all forces */
2754+ ret = hidpp_send_fap_command_sync (hidpp , data -> feature_index ,
2755+ HIDPP_FF_RESET_ALL ,
2756+ NULL , 0 ,
2757+ & response );
27482758 if (ret )
2749- hid_warn (hidpp -> hid_dev , "Unable to initialize force feedback support, errno %d\n" ,
2750- ret );
2759+ hid_warn (hidpp -> hid_dev , "Failed to reset all forces!\n" );
27512760
2752- return 0 ;
2761+ ret = hidpp_send_fap_command_sync (hidpp , data -> feature_index ,
2762+ HIDPP_FF_GET_APERTURE ,
2763+ NULL , 0 ,
2764+ & response );
2765+ if (ret ) {
2766+ hid_warn (hidpp -> hid_dev ,
2767+ "Failed to read range from device!\n" );
2768+ }
2769+ data -> range = ret ?
2770+ 900 : get_unaligned_be16 (& response .fap .params [0 ]);
2771+
2772+ /* Read the current gain values */
2773+ ret = hidpp_send_fap_command_sync (hidpp , data -> feature_index ,
2774+ HIDPP_FF_GET_GLOBAL_GAINS ,
2775+ NULL , 0 ,
2776+ & response );
2777+ if (ret )
2778+ hid_warn (hidpp -> hid_dev ,
2779+ "Failed to read gain values from device!\n" );
2780+ data -> gain = ret ?
2781+ 0xffff : get_unaligned_be16 (& response .fap .params [0 ]);
2782+
2783+ /* ignore boost value at response.fap.params[2] */
2784+
2785+ return g920_ff_set_autocenter (hidpp , data );
27532786}
27542787
27552788/* -------------------------------------------------------------------------- */
@@ -3512,6 +3545,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
35123545 int ret ;
35133546 bool connected ;
35143547 unsigned int connect_mask = HID_CONNECT_DEFAULT ;
3548+ struct hidpp_ff_private_data data ;
35153549
35163550 /* report_fixup needs drvdata to be set before we call hid_parse */
35173551 hidpp = devm_kzalloc (& hdev -> dev , sizeof (* hidpp ), GFP_KERNEL );
@@ -3621,7 +3655,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
36213655 if (ret )
36223656 goto hid_hw_init_fail ;
36233657 } else if (connected && (hidpp -> quirks & HIDPP_QUIRK_CLASS_G920 )) {
3624- ret = g920_get_config (hidpp );
3658+ ret = g920_get_config (hidpp , & data );
36253659 if (ret )
36263660 goto hid_hw_init_fail ;
36273661 }
@@ -3643,6 +3677,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
36433677 goto hid_hw_start_fail ;
36443678 }
36453679
3680+ if (hidpp -> quirks & HIDPP_QUIRK_CLASS_G920 ) {
3681+ ret = hidpp_ff_init (hidpp , & data );
3682+ if (ret )
3683+ hid_warn (hidpp -> hid_dev ,
3684+ "Unable to initialize force feedback support, errno %d\n" ,
3685+ ret );
3686+ }
3687+
36463688 return ret ;
36473689
36483690hid_hw_init_fail :
0 commit comments