xref: /OK3568_Linux_fs/kernel/drivers/hid/usbhid/hid-pidff.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Force feedback driver for USB HID PID compliant devices
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* #define DEBUG */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #include <linux/input.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/usb.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <linux/hid.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include "usbhid.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define	PID_EFFECTS_MAX		64
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* Report usage table used to put reports into an array */
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define PID_SET_EFFECT		0
28*4882a593Smuzhiyun #define PID_EFFECT_OPERATION	1
29*4882a593Smuzhiyun #define PID_DEVICE_GAIN		2
30*4882a593Smuzhiyun #define PID_POOL		3
31*4882a593Smuzhiyun #define PID_BLOCK_LOAD		4
32*4882a593Smuzhiyun #define PID_BLOCK_FREE		5
33*4882a593Smuzhiyun #define PID_DEVICE_CONTROL	6
34*4882a593Smuzhiyun #define PID_CREATE_NEW_EFFECT	7
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define PID_REQUIRED_REPORTS	7
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define PID_SET_ENVELOPE	8
39*4882a593Smuzhiyun #define PID_SET_CONDITION	9
40*4882a593Smuzhiyun #define PID_SET_PERIODIC	10
41*4882a593Smuzhiyun #define PID_SET_CONSTANT	11
42*4882a593Smuzhiyun #define PID_SET_RAMP		12
43*4882a593Smuzhiyun static const u8 pidff_reports[] = {
44*4882a593Smuzhiyun 	0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
45*4882a593Smuzhiyun 	0x5a, 0x5f, 0x6e, 0x73, 0x74
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /* device_control is really 0x95, but 0x96 specified as it is the usage of
49*4882a593Smuzhiyun the only field in that report */
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* Value usage tables used to put fields and values into arrays */
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define PID_EFFECT_BLOCK_INDEX	0
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define PID_DURATION		1
56*4882a593Smuzhiyun #define PID_GAIN		2
57*4882a593Smuzhiyun #define PID_TRIGGER_BUTTON	3
58*4882a593Smuzhiyun #define PID_TRIGGER_REPEAT_INT	4
59*4882a593Smuzhiyun #define PID_DIRECTION_ENABLE	5
60*4882a593Smuzhiyun #define PID_START_DELAY		6
61*4882a593Smuzhiyun static const u8 pidff_set_effect[] = {
62*4882a593Smuzhiyun 	0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #define PID_ATTACK_LEVEL	1
66*4882a593Smuzhiyun #define PID_ATTACK_TIME		2
67*4882a593Smuzhiyun #define PID_FADE_LEVEL		3
68*4882a593Smuzhiyun #define PID_FADE_TIME		4
69*4882a593Smuzhiyun static const u8 pidff_set_envelope[] = { 0x22, 0x5b, 0x5c, 0x5d, 0x5e };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #define PID_PARAM_BLOCK_OFFSET	1
72*4882a593Smuzhiyun #define PID_CP_OFFSET		2
73*4882a593Smuzhiyun #define PID_POS_COEFFICIENT	3
74*4882a593Smuzhiyun #define PID_NEG_COEFFICIENT	4
75*4882a593Smuzhiyun #define PID_POS_SATURATION	5
76*4882a593Smuzhiyun #define PID_NEG_SATURATION	6
77*4882a593Smuzhiyun #define PID_DEAD_BAND		7
78*4882a593Smuzhiyun static const u8 pidff_set_condition[] = {
79*4882a593Smuzhiyun 	0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun #define PID_MAGNITUDE		1
83*4882a593Smuzhiyun #define PID_OFFSET		2
84*4882a593Smuzhiyun #define PID_PHASE		3
85*4882a593Smuzhiyun #define PID_PERIOD		4
86*4882a593Smuzhiyun static const u8 pidff_set_periodic[] = { 0x22, 0x70, 0x6f, 0x71, 0x72 };
87*4882a593Smuzhiyun static const u8 pidff_set_constant[] = { 0x22, 0x70 };
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun #define PID_RAMP_START		1
90*4882a593Smuzhiyun #define PID_RAMP_END		2
91*4882a593Smuzhiyun static const u8 pidff_set_ramp[] = { 0x22, 0x75, 0x76 };
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun #define PID_RAM_POOL_AVAILABLE	1
94*4882a593Smuzhiyun static const u8 pidff_block_load[] = { 0x22, 0xac };
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun #define PID_LOOP_COUNT		1
97*4882a593Smuzhiyun static const u8 pidff_effect_operation[] = { 0x22, 0x7c };
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun static const u8 pidff_block_free[] = { 0x22 };
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun #define PID_DEVICE_GAIN_FIELD	0
102*4882a593Smuzhiyun static const u8 pidff_device_gain[] = { 0x7e };
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #define PID_RAM_POOL_SIZE	0
105*4882a593Smuzhiyun #define PID_SIMULTANEOUS_MAX	1
106*4882a593Smuzhiyun #define PID_DEVICE_MANAGED_POOL	2
107*4882a593Smuzhiyun static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /* Special field key tables used to put special field keys into arrays */
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #define PID_ENABLE_ACTUATORS	0
112*4882a593Smuzhiyun #define PID_RESET		1
113*4882a593Smuzhiyun static const u8 pidff_device_control[] = { 0x97, 0x9a };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #define PID_CONSTANT	0
116*4882a593Smuzhiyun #define PID_RAMP	1
117*4882a593Smuzhiyun #define PID_SQUARE	2
118*4882a593Smuzhiyun #define PID_SINE	3
119*4882a593Smuzhiyun #define PID_TRIANGLE	4
120*4882a593Smuzhiyun #define PID_SAW_UP	5
121*4882a593Smuzhiyun #define PID_SAW_DOWN	6
122*4882a593Smuzhiyun #define PID_SPRING	7
123*4882a593Smuzhiyun #define PID_DAMPER	8
124*4882a593Smuzhiyun #define PID_INERTIA	9
125*4882a593Smuzhiyun #define PID_FRICTION	10
126*4882a593Smuzhiyun static const u8 pidff_effect_types[] = {
127*4882a593Smuzhiyun 	0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34,
128*4882a593Smuzhiyun 	0x40, 0x41, 0x42, 0x43
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun #define PID_BLOCK_LOAD_SUCCESS	0
132*4882a593Smuzhiyun #define PID_BLOCK_LOAD_FULL	1
133*4882a593Smuzhiyun static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun #define PID_EFFECT_START	0
136*4882a593Smuzhiyun #define PID_EFFECT_STOP		1
137*4882a593Smuzhiyun static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun struct pidff_usage {
140*4882a593Smuzhiyun 	struct hid_field *field;
141*4882a593Smuzhiyun 	s32 *value;
142*4882a593Smuzhiyun };
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun struct pidff_device {
145*4882a593Smuzhiyun 	struct hid_device *hid;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	struct hid_report *reports[sizeof(pidff_reports)];
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	struct pidff_usage set_effect[sizeof(pidff_set_effect)];
150*4882a593Smuzhiyun 	struct pidff_usage set_envelope[sizeof(pidff_set_envelope)];
151*4882a593Smuzhiyun 	struct pidff_usage set_condition[sizeof(pidff_set_condition)];
152*4882a593Smuzhiyun 	struct pidff_usage set_periodic[sizeof(pidff_set_periodic)];
153*4882a593Smuzhiyun 	struct pidff_usage set_constant[sizeof(pidff_set_constant)];
154*4882a593Smuzhiyun 	struct pidff_usage set_ramp[sizeof(pidff_set_ramp)];
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	struct pidff_usage device_gain[sizeof(pidff_device_gain)];
157*4882a593Smuzhiyun 	struct pidff_usage block_load[sizeof(pidff_block_load)];
158*4882a593Smuzhiyun 	struct pidff_usage pool[sizeof(pidff_pool)];
159*4882a593Smuzhiyun 	struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
160*4882a593Smuzhiyun 	struct pidff_usage block_free[sizeof(pidff_block_free)];
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	/* Special field is a field that is not composed of
163*4882a593Smuzhiyun 	   usage<->value pairs that pidff_usage values are */
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* Special field in create_new_effect */
166*4882a593Smuzhiyun 	struct hid_field *create_new_effect_type;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	/* Special fields in set_effect */
169*4882a593Smuzhiyun 	struct hid_field *set_effect_type;
170*4882a593Smuzhiyun 	struct hid_field *effect_direction;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* Special field in device_control */
173*4882a593Smuzhiyun 	struct hid_field *device_control;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	/* Special field in block_load */
176*4882a593Smuzhiyun 	struct hid_field *block_load_status;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	/* Special field in effect_operation */
179*4882a593Smuzhiyun 	struct hid_field *effect_operation_status;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	int control_id[sizeof(pidff_device_control)];
182*4882a593Smuzhiyun 	int type_id[sizeof(pidff_effect_types)];
183*4882a593Smuzhiyun 	int status_id[sizeof(pidff_block_load_status)];
184*4882a593Smuzhiyun 	int operation_id[sizeof(pidff_effect_operation_status)];
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	int pid_id[PID_EFFECTS_MAX];
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /*
190*4882a593Smuzhiyun  * Scale an unsigned value with range 0..max for the given field
191*4882a593Smuzhiyun  */
pidff_rescale(int i,int max,struct hid_field * field)192*4882a593Smuzhiyun static int pidff_rescale(int i, int max, struct hid_field *field)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	return i * (field->logical_maximum - field->logical_minimum) / max +
195*4882a593Smuzhiyun 	    field->logical_minimum;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun /*
199*4882a593Smuzhiyun  * Scale a signed value in range -0x8000..0x7fff for the given field
200*4882a593Smuzhiyun  */
pidff_rescale_signed(int i,struct hid_field * field)201*4882a593Smuzhiyun static int pidff_rescale_signed(int i, struct hid_field *field)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	return i == 0 ? 0 : i >
204*4882a593Smuzhiyun 	    0 ? i * field->logical_maximum / 0x7fff : i *
205*4882a593Smuzhiyun 	    field->logical_minimum / -0x8000;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
pidff_set(struct pidff_usage * usage,u16 value)208*4882a593Smuzhiyun static void pidff_set(struct pidff_usage *usage, u16 value)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
211*4882a593Smuzhiyun 	pr_debug("calculated from %d to %d\n", value, usage->value[0]);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
pidff_set_signed(struct pidff_usage * usage,s16 value)214*4882a593Smuzhiyun static void pidff_set_signed(struct pidff_usage *usage, s16 value)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	if (usage->field->logical_minimum < 0)
217*4882a593Smuzhiyun 		usage->value[0] = pidff_rescale_signed(value, usage->field);
218*4882a593Smuzhiyun 	else {
219*4882a593Smuzhiyun 		if (value < 0)
220*4882a593Smuzhiyun 			usage->value[0] =
221*4882a593Smuzhiyun 			    pidff_rescale(-value, 0x8000, usage->field);
222*4882a593Smuzhiyun 		else
223*4882a593Smuzhiyun 			usage->value[0] =
224*4882a593Smuzhiyun 			    pidff_rescale(value, 0x7fff, usage->field);
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 	pr_debug("calculated from %d to %d\n", value, usage->value[0]);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun /*
230*4882a593Smuzhiyun  * Send envelope report to the device
231*4882a593Smuzhiyun  */
pidff_set_envelope_report(struct pidff_device * pidff,struct ff_envelope * envelope)232*4882a593Smuzhiyun static void pidff_set_envelope_report(struct pidff_device *pidff,
233*4882a593Smuzhiyun 				      struct ff_envelope *envelope)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
236*4882a593Smuzhiyun 	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
239*4882a593Smuzhiyun 	    pidff_rescale(envelope->attack_level >
240*4882a593Smuzhiyun 			  0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
241*4882a593Smuzhiyun 			  pidff->set_envelope[PID_ATTACK_LEVEL].field);
242*4882a593Smuzhiyun 	pidff->set_envelope[PID_FADE_LEVEL].value[0] =
243*4882a593Smuzhiyun 	    pidff_rescale(envelope->fade_level >
244*4882a593Smuzhiyun 			  0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
245*4882a593Smuzhiyun 			  pidff->set_envelope[PID_FADE_LEVEL].field);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
248*4882a593Smuzhiyun 	pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	hid_dbg(pidff->hid, "attack %u => %d\n",
251*4882a593Smuzhiyun 		envelope->attack_level,
252*4882a593Smuzhiyun 		pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
255*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun /*
259*4882a593Smuzhiyun  * Test if the new envelope differs from old one
260*4882a593Smuzhiyun  */
pidff_needs_set_envelope(struct ff_envelope * envelope,struct ff_envelope * old)261*4882a593Smuzhiyun static int pidff_needs_set_envelope(struct ff_envelope *envelope,
262*4882a593Smuzhiyun 				    struct ff_envelope *old)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	return envelope->attack_level != old->attack_level ||
265*4882a593Smuzhiyun 	       envelope->fade_level != old->fade_level ||
266*4882a593Smuzhiyun 	       envelope->attack_length != old->attack_length ||
267*4882a593Smuzhiyun 	       envelope->fade_length != old->fade_length;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun /*
271*4882a593Smuzhiyun  * Send constant force report to the device
272*4882a593Smuzhiyun  */
pidff_set_constant_force_report(struct pidff_device * pidff,struct ff_effect * effect)273*4882a593Smuzhiyun static void pidff_set_constant_force_report(struct pidff_device *pidff,
274*4882a593Smuzhiyun 					    struct ff_effect *effect)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
277*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
278*4882a593Smuzhiyun 	pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
279*4882a593Smuzhiyun 			 effect->u.constant.level);
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONSTANT],
282*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun /*
286*4882a593Smuzhiyun  * Test if the constant parameters have changed between effects
287*4882a593Smuzhiyun  */
pidff_needs_set_constant(struct ff_effect * effect,struct ff_effect * old)288*4882a593Smuzhiyun static int pidff_needs_set_constant(struct ff_effect *effect,
289*4882a593Smuzhiyun 				    struct ff_effect *old)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	return effect->u.constant.level != old->u.constant.level;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun /*
295*4882a593Smuzhiyun  * Send set effect report to the device
296*4882a593Smuzhiyun  */
pidff_set_effect_report(struct pidff_device * pidff,struct ff_effect * effect)297*4882a593Smuzhiyun static void pidff_set_effect_report(struct pidff_device *pidff,
298*4882a593Smuzhiyun 				    struct ff_effect *effect)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
301*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
302*4882a593Smuzhiyun 	pidff->set_effect_type->value[0] =
303*4882a593Smuzhiyun 		pidff->create_new_effect_type->value[0];
304*4882a593Smuzhiyun 	pidff->set_effect[PID_DURATION].value[0] = effect->replay.length;
305*4882a593Smuzhiyun 	pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
306*4882a593Smuzhiyun 	pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
307*4882a593Smuzhiyun 		effect->trigger.interval;
308*4882a593Smuzhiyun 	pidff->set_effect[PID_GAIN].value[0] =
309*4882a593Smuzhiyun 		pidff->set_effect[PID_GAIN].field->logical_maximum;
310*4882a593Smuzhiyun 	pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
311*4882a593Smuzhiyun 	pidff->effect_direction->value[0] =
312*4882a593Smuzhiyun 		pidff_rescale(effect->direction, 0xffff,
313*4882a593Smuzhiyun 				pidff->effect_direction);
314*4882a593Smuzhiyun 	pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT],
317*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun /*
321*4882a593Smuzhiyun  * Test if the values used in set_effect have changed
322*4882a593Smuzhiyun  */
pidff_needs_set_effect(struct ff_effect * effect,struct ff_effect * old)323*4882a593Smuzhiyun static int pidff_needs_set_effect(struct ff_effect *effect,
324*4882a593Smuzhiyun 				  struct ff_effect *old)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun 	return effect->replay.length != old->replay.length ||
327*4882a593Smuzhiyun 	       effect->trigger.interval != old->trigger.interval ||
328*4882a593Smuzhiyun 	       effect->trigger.button != old->trigger.button ||
329*4882a593Smuzhiyun 	       effect->direction != old->direction ||
330*4882a593Smuzhiyun 	       effect->replay.delay != old->replay.delay;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun /*
334*4882a593Smuzhiyun  * Send periodic effect report to the device
335*4882a593Smuzhiyun  */
pidff_set_periodic_report(struct pidff_device * pidff,struct ff_effect * effect)336*4882a593Smuzhiyun static void pidff_set_periodic_report(struct pidff_device *pidff,
337*4882a593Smuzhiyun 				      struct ff_effect *effect)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun 	pidff->set_periodic[PID_EFFECT_BLOCK_INDEX].value[0] =
340*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
341*4882a593Smuzhiyun 	pidff_set_signed(&pidff->set_periodic[PID_MAGNITUDE],
342*4882a593Smuzhiyun 			 effect->u.periodic.magnitude);
343*4882a593Smuzhiyun 	pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
344*4882a593Smuzhiyun 			 effect->u.periodic.offset);
345*4882a593Smuzhiyun 	pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
346*4882a593Smuzhiyun 	pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC],
349*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun /*
354*4882a593Smuzhiyun  * Test if periodic effect parameters have changed
355*4882a593Smuzhiyun  */
pidff_needs_set_periodic(struct ff_effect * effect,struct ff_effect * old)356*4882a593Smuzhiyun static int pidff_needs_set_periodic(struct ff_effect *effect,
357*4882a593Smuzhiyun 				    struct ff_effect *old)
358*4882a593Smuzhiyun {
359*4882a593Smuzhiyun 	return effect->u.periodic.magnitude != old->u.periodic.magnitude ||
360*4882a593Smuzhiyun 	       effect->u.periodic.offset != old->u.periodic.offset ||
361*4882a593Smuzhiyun 	       effect->u.periodic.phase != old->u.periodic.phase ||
362*4882a593Smuzhiyun 	       effect->u.periodic.period != old->u.periodic.period;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun /*
366*4882a593Smuzhiyun  * Send condition effect reports to the device
367*4882a593Smuzhiyun  */
pidff_set_condition_report(struct pidff_device * pidff,struct ff_effect * effect)368*4882a593Smuzhiyun static void pidff_set_condition_report(struct pidff_device *pidff,
369*4882a593Smuzhiyun 				       struct ff_effect *effect)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun 	int i;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	pidff->set_condition[PID_EFFECT_BLOCK_INDEX].value[0] =
374*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	for (i = 0; i < 2; i++) {
377*4882a593Smuzhiyun 		pidff->set_condition[PID_PARAM_BLOCK_OFFSET].value[0] = i;
378*4882a593Smuzhiyun 		pidff_set_signed(&pidff->set_condition[PID_CP_OFFSET],
379*4882a593Smuzhiyun 				 effect->u.condition[i].center);
380*4882a593Smuzhiyun 		pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],
381*4882a593Smuzhiyun 				 effect->u.condition[i].right_coeff);
382*4882a593Smuzhiyun 		pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],
383*4882a593Smuzhiyun 				 effect->u.condition[i].left_coeff);
384*4882a593Smuzhiyun 		pidff_set(&pidff->set_condition[PID_POS_SATURATION],
385*4882a593Smuzhiyun 			  effect->u.condition[i].right_saturation);
386*4882a593Smuzhiyun 		pidff_set(&pidff->set_condition[PID_NEG_SATURATION],
387*4882a593Smuzhiyun 			  effect->u.condition[i].left_saturation);
388*4882a593Smuzhiyun 		pidff_set(&pidff->set_condition[PID_DEAD_BAND],
389*4882a593Smuzhiyun 			  effect->u.condition[i].deadband);
390*4882a593Smuzhiyun 		hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONDITION],
391*4882a593Smuzhiyun 				HID_REQ_SET_REPORT);
392*4882a593Smuzhiyun 	}
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun /*
396*4882a593Smuzhiyun  * Test if condition effect parameters have changed
397*4882a593Smuzhiyun  */
pidff_needs_set_condition(struct ff_effect * effect,struct ff_effect * old)398*4882a593Smuzhiyun static int pidff_needs_set_condition(struct ff_effect *effect,
399*4882a593Smuzhiyun 				     struct ff_effect *old)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	int i;
402*4882a593Smuzhiyun 	int ret = 0;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	for (i = 0; i < 2; i++) {
405*4882a593Smuzhiyun 		struct ff_condition_effect *cond = &effect->u.condition[i];
406*4882a593Smuzhiyun 		struct ff_condition_effect *old_cond = &old->u.condition[i];
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 		ret |= cond->center != old_cond->center ||
409*4882a593Smuzhiyun 		       cond->right_coeff != old_cond->right_coeff ||
410*4882a593Smuzhiyun 		       cond->left_coeff != old_cond->left_coeff ||
411*4882a593Smuzhiyun 		       cond->right_saturation != old_cond->right_saturation ||
412*4882a593Smuzhiyun 		       cond->left_saturation != old_cond->left_saturation ||
413*4882a593Smuzhiyun 		       cond->deadband != old_cond->deadband;
414*4882a593Smuzhiyun 	}
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	return ret;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun /*
420*4882a593Smuzhiyun  * Send ramp force report to the device
421*4882a593Smuzhiyun  */
pidff_set_ramp_force_report(struct pidff_device * pidff,struct ff_effect * effect)422*4882a593Smuzhiyun static void pidff_set_ramp_force_report(struct pidff_device *pidff,
423*4882a593Smuzhiyun 					struct ff_effect *effect)
424*4882a593Smuzhiyun {
425*4882a593Smuzhiyun 	pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
426*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
427*4882a593Smuzhiyun 	pidff_set_signed(&pidff->set_ramp[PID_RAMP_START],
428*4882a593Smuzhiyun 			 effect->u.ramp.start_level);
429*4882a593Smuzhiyun 	pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
430*4882a593Smuzhiyun 			 effect->u.ramp.end_level);
431*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_SET_RAMP],
432*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun /*
436*4882a593Smuzhiyun  * Test if ramp force parameters have changed
437*4882a593Smuzhiyun  */
pidff_needs_set_ramp(struct ff_effect * effect,struct ff_effect * old)438*4882a593Smuzhiyun static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
439*4882a593Smuzhiyun {
440*4882a593Smuzhiyun 	return effect->u.ramp.start_level != old->u.ramp.start_level ||
441*4882a593Smuzhiyun 	       effect->u.ramp.end_level != old->u.ramp.end_level;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun /*
445*4882a593Smuzhiyun  * Send a request for effect upload to the device
446*4882a593Smuzhiyun  *
447*4882a593Smuzhiyun  * Returns 0 if device reported success, -ENOSPC if the device reported memory
448*4882a593Smuzhiyun  * is full. Upon unknown response the function will retry for 60 times, if
449*4882a593Smuzhiyun  * still unsuccessful -EIO is returned.
450*4882a593Smuzhiyun  */
pidff_request_effect_upload(struct pidff_device * pidff,int efnum)451*4882a593Smuzhiyun static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 	int j;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	pidff->create_new_effect_type->value[0] = efnum;
456*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
457*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
458*4882a593Smuzhiyun 	hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
461*4882a593Smuzhiyun 	pidff->block_load_status->value[0] = 0;
462*4882a593Smuzhiyun 	hid_hw_wait(pidff->hid);
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	for (j = 0; j < 60; j++) {
465*4882a593Smuzhiyun 		hid_dbg(pidff->hid, "pid_block_load requested\n");
466*4882a593Smuzhiyun 		hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
467*4882a593Smuzhiyun 				HID_REQ_GET_REPORT);
468*4882a593Smuzhiyun 		hid_hw_wait(pidff->hid);
469*4882a593Smuzhiyun 		if (pidff->block_load_status->value[0] ==
470*4882a593Smuzhiyun 		    pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
471*4882a593Smuzhiyun 			hid_dbg(pidff->hid, "device reported free memory: %d bytes\n",
472*4882a593Smuzhiyun 				 pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
473*4882a593Smuzhiyun 				 pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
474*4882a593Smuzhiyun 			return 0;
475*4882a593Smuzhiyun 		}
476*4882a593Smuzhiyun 		if (pidff->block_load_status->value[0] ==
477*4882a593Smuzhiyun 		    pidff->status_id[PID_BLOCK_LOAD_FULL]) {
478*4882a593Smuzhiyun 			hid_dbg(pidff->hid, "not enough memory free: %d bytes\n",
479*4882a593Smuzhiyun 				pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
480*4882a593Smuzhiyun 				pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
481*4882a593Smuzhiyun 			return -ENOSPC;
482*4882a593Smuzhiyun 		}
483*4882a593Smuzhiyun 	}
484*4882a593Smuzhiyun 	hid_err(pidff->hid, "pid_block_load failed 60 times\n");
485*4882a593Smuzhiyun 	return -EIO;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun /*
489*4882a593Smuzhiyun  * Play the effect with PID id n times
490*4882a593Smuzhiyun  */
pidff_playback_pid(struct pidff_device * pidff,int pid_id,int n)491*4882a593Smuzhiyun static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun 	pidff->effect_operation[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	if (n == 0) {
496*4882a593Smuzhiyun 		pidff->effect_operation_status->value[0] =
497*4882a593Smuzhiyun 			pidff->operation_id[PID_EFFECT_STOP];
498*4882a593Smuzhiyun 	} else {
499*4882a593Smuzhiyun 		pidff->effect_operation_status->value[0] =
500*4882a593Smuzhiyun 			pidff->operation_id[PID_EFFECT_START];
501*4882a593Smuzhiyun 		pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
502*4882a593Smuzhiyun 	}
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
505*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun /**
509*4882a593Smuzhiyun  * Play the effect with effect id @effect_id for @value times
510*4882a593Smuzhiyun  */
pidff_playback(struct input_dev * dev,int effect_id,int value)511*4882a593Smuzhiyun static int pidff_playback(struct input_dev *dev, int effect_id, int value)
512*4882a593Smuzhiyun {
513*4882a593Smuzhiyun 	struct pidff_device *pidff = dev->ff->private;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	return 0;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun /*
521*4882a593Smuzhiyun  * Erase effect with PID id
522*4882a593Smuzhiyun  */
pidff_erase_pid(struct pidff_device * pidff,int pid_id)523*4882a593Smuzhiyun static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
526*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_FREE],
527*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun /*
531*4882a593Smuzhiyun  * Stop and erase effect with effect_id
532*4882a593Smuzhiyun  */
pidff_erase_effect(struct input_dev * dev,int effect_id)533*4882a593Smuzhiyun static int pidff_erase_effect(struct input_dev *dev, int effect_id)
534*4882a593Smuzhiyun {
535*4882a593Smuzhiyun 	struct pidff_device *pidff = dev->ff->private;
536*4882a593Smuzhiyun 	int pid_id = pidff->pid_id[effect_id];
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	hid_dbg(pidff->hid, "starting to erase %d/%d\n",
539*4882a593Smuzhiyun 		effect_id, pidff->pid_id[effect_id]);
540*4882a593Smuzhiyun 	/* Wait for the queue to clear. We do not want a full fifo to
541*4882a593Smuzhiyun 	   prevent the effect removal. */
542*4882a593Smuzhiyun 	hid_hw_wait(pidff->hid);
543*4882a593Smuzhiyun 	pidff_playback_pid(pidff, pid_id, 0);
544*4882a593Smuzhiyun 	pidff_erase_pid(pidff, pid_id);
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	return 0;
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun /*
550*4882a593Smuzhiyun  * Effect upload handler
551*4882a593Smuzhiyun  */
pidff_upload_effect(struct input_dev * dev,struct ff_effect * effect,struct ff_effect * old)552*4882a593Smuzhiyun static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
553*4882a593Smuzhiyun 			       struct ff_effect *old)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun 	struct pidff_device *pidff = dev->ff->private;
556*4882a593Smuzhiyun 	int type_id;
557*4882a593Smuzhiyun 	int error;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
560*4882a593Smuzhiyun 	if (old) {
561*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] =
562*4882a593Smuzhiyun 			pidff->pid_id[effect->id];
563*4882a593Smuzhiyun 	}
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 	switch (effect->type) {
566*4882a593Smuzhiyun 	case FF_CONSTANT:
567*4882a593Smuzhiyun 		if (!old) {
568*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
569*4882a593Smuzhiyun 					pidff->type_id[PID_CONSTANT]);
570*4882a593Smuzhiyun 			if (error)
571*4882a593Smuzhiyun 				return error;
572*4882a593Smuzhiyun 		}
573*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
574*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
575*4882a593Smuzhiyun 		if (!old || pidff_needs_set_constant(effect, old))
576*4882a593Smuzhiyun 			pidff_set_constant_force_report(pidff, effect);
577*4882a593Smuzhiyun 		if (!old ||
578*4882a593Smuzhiyun 		    pidff_needs_set_envelope(&effect->u.constant.envelope,
579*4882a593Smuzhiyun 					&old->u.constant.envelope))
580*4882a593Smuzhiyun 			pidff_set_envelope_report(pidff,
581*4882a593Smuzhiyun 					&effect->u.constant.envelope);
582*4882a593Smuzhiyun 		break;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	case FF_PERIODIC:
585*4882a593Smuzhiyun 		if (!old) {
586*4882a593Smuzhiyun 			switch (effect->u.periodic.waveform) {
587*4882a593Smuzhiyun 			case FF_SQUARE:
588*4882a593Smuzhiyun 				type_id = PID_SQUARE;
589*4882a593Smuzhiyun 				break;
590*4882a593Smuzhiyun 			case FF_TRIANGLE:
591*4882a593Smuzhiyun 				type_id = PID_TRIANGLE;
592*4882a593Smuzhiyun 				break;
593*4882a593Smuzhiyun 			case FF_SINE:
594*4882a593Smuzhiyun 				type_id = PID_SINE;
595*4882a593Smuzhiyun 				break;
596*4882a593Smuzhiyun 			case FF_SAW_UP:
597*4882a593Smuzhiyun 				type_id = PID_SAW_UP;
598*4882a593Smuzhiyun 				break;
599*4882a593Smuzhiyun 			case FF_SAW_DOWN:
600*4882a593Smuzhiyun 				type_id = PID_SAW_DOWN;
601*4882a593Smuzhiyun 				break;
602*4882a593Smuzhiyun 			default:
603*4882a593Smuzhiyun 				hid_err(pidff->hid, "invalid waveform\n");
604*4882a593Smuzhiyun 				return -EINVAL;
605*4882a593Smuzhiyun 			}
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
608*4882a593Smuzhiyun 					pidff->type_id[type_id]);
609*4882a593Smuzhiyun 			if (error)
610*4882a593Smuzhiyun 				return error;
611*4882a593Smuzhiyun 		}
612*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
613*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
614*4882a593Smuzhiyun 		if (!old || pidff_needs_set_periodic(effect, old))
615*4882a593Smuzhiyun 			pidff_set_periodic_report(pidff, effect);
616*4882a593Smuzhiyun 		if (!old ||
617*4882a593Smuzhiyun 		    pidff_needs_set_envelope(&effect->u.periodic.envelope,
618*4882a593Smuzhiyun 					&old->u.periodic.envelope))
619*4882a593Smuzhiyun 			pidff_set_envelope_report(pidff,
620*4882a593Smuzhiyun 					&effect->u.periodic.envelope);
621*4882a593Smuzhiyun 		break;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	case FF_RAMP:
624*4882a593Smuzhiyun 		if (!old) {
625*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
626*4882a593Smuzhiyun 					pidff->type_id[PID_RAMP]);
627*4882a593Smuzhiyun 			if (error)
628*4882a593Smuzhiyun 				return error;
629*4882a593Smuzhiyun 		}
630*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
631*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
632*4882a593Smuzhiyun 		if (!old || pidff_needs_set_ramp(effect, old))
633*4882a593Smuzhiyun 			pidff_set_ramp_force_report(pidff, effect);
634*4882a593Smuzhiyun 		if (!old ||
635*4882a593Smuzhiyun 		    pidff_needs_set_envelope(&effect->u.ramp.envelope,
636*4882a593Smuzhiyun 					&old->u.ramp.envelope))
637*4882a593Smuzhiyun 			pidff_set_envelope_report(pidff,
638*4882a593Smuzhiyun 					&effect->u.ramp.envelope);
639*4882a593Smuzhiyun 		break;
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	case FF_SPRING:
642*4882a593Smuzhiyun 		if (!old) {
643*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
644*4882a593Smuzhiyun 					pidff->type_id[PID_SPRING]);
645*4882a593Smuzhiyun 			if (error)
646*4882a593Smuzhiyun 				return error;
647*4882a593Smuzhiyun 		}
648*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
649*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
650*4882a593Smuzhiyun 		if (!old || pidff_needs_set_condition(effect, old))
651*4882a593Smuzhiyun 			pidff_set_condition_report(pidff, effect);
652*4882a593Smuzhiyun 		break;
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 	case FF_FRICTION:
655*4882a593Smuzhiyun 		if (!old) {
656*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
657*4882a593Smuzhiyun 					pidff->type_id[PID_FRICTION]);
658*4882a593Smuzhiyun 			if (error)
659*4882a593Smuzhiyun 				return error;
660*4882a593Smuzhiyun 		}
661*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
662*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
663*4882a593Smuzhiyun 		if (!old || pidff_needs_set_condition(effect, old))
664*4882a593Smuzhiyun 			pidff_set_condition_report(pidff, effect);
665*4882a593Smuzhiyun 		break;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	case FF_DAMPER:
668*4882a593Smuzhiyun 		if (!old) {
669*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
670*4882a593Smuzhiyun 					pidff->type_id[PID_DAMPER]);
671*4882a593Smuzhiyun 			if (error)
672*4882a593Smuzhiyun 				return error;
673*4882a593Smuzhiyun 		}
674*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
675*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
676*4882a593Smuzhiyun 		if (!old || pidff_needs_set_condition(effect, old))
677*4882a593Smuzhiyun 			pidff_set_condition_report(pidff, effect);
678*4882a593Smuzhiyun 		break;
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	case FF_INERTIA:
681*4882a593Smuzhiyun 		if (!old) {
682*4882a593Smuzhiyun 			error = pidff_request_effect_upload(pidff,
683*4882a593Smuzhiyun 					pidff->type_id[PID_INERTIA]);
684*4882a593Smuzhiyun 			if (error)
685*4882a593Smuzhiyun 				return error;
686*4882a593Smuzhiyun 		}
687*4882a593Smuzhiyun 		if (!old || pidff_needs_set_effect(effect, old))
688*4882a593Smuzhiyun 			pidff_set_effect_report(pidff, effect);
689*4882a593Smuzhiyun 		if (!old || pidff_needs_set_condition(effect, old))
690*4882a593Smuzhiyun 			pidff_set_condition_report(pidff, effect);
691*4882a593Smuzhiyun 		break;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	default:
694*4882a593Smuzhiyun 		hid_err(pidff->hid, "invalid type\n");
695*4882a593Smuzhiyun 		return -EINVAL;
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	if (!old)
699*4882a593Smuzhiyun 		pidff->pid_id[effect->id] =
700*4882a593Smuzhiyun 		    pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	hid_dbg(pidff->hid, "uploaded\n");
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	return 0;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun /*
708*4882a593Smuzhiyun  * set_gain() handler
709*4882a593Smuzhiyun  */
pidff_set_gain(struct input_dev * dev,u16 gain)710*4882a593Smuzhiyun static void pidff_set_gain(struct input_dev *dev, u16 gain)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun 	struct pidff_device *pidff = dev->ff->private;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
715*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
716*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun 
pidff_autocenter(struct pidff_device * pidff,u16 magnitude)719*4882a593Smuzhiyun static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun 	struct hid_field *field =
722*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].field;
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	if (!magnitude) {
725*4882a593Smuzhiyun 		pidff_playback_pid(pidff, field->logical_minimum, 0);
726*4882a593Smuzhiyun 		return;
727*4882a593Smuzhiyun 	}
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	pidff_playback_pid(pidff, field->logical_minimum, 1);
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
732*4882a593Smuzhiyun 		pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum;
733*4882a593Smuzhiyun 	pidff->set_effect_type->value[0] = pidff->type_id[PID_SPRING];
734*4882a593Smuzhiyun 	pidff->set_effect[PID_DURATION].value[0] = 0;
735*4882a593Smuzhiyun 	pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
736*4882a593Smuzhiyun 	pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
737*4882a593Smuzhiyun 	pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
738*4882a593Smuzhiyun 	pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
739*4882a593Smuzhiyun 	pidff->set_effect[PID_START_DELAY].value[0] = 0;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT],
742*4882a593Smuzhiyun 			HID_REQ_SET_REPORT);
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun /*
746*4882a593Smuzhiyun  * pidff_set_autocenter() handler
747*4882a593Smuzhiyun  */
pidff_set_autocenter(struct input_dev * dev,u16 magnitude)748*4882a593Smuzhiyun static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
749*4882a593Smuzhiyun {
750*4882a593Smuzhiyun 	struct pidff_device *pidff = dev->ff->private;
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	pidff_autocenter(pidff, magnitude);
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun /*
756*4882a593Smuzhiyun  * Find fields from a report and fill a pidff_usage
757*4882a593Smuzhiyun  */
pidff_find_fields(struct pidff_usage * usage,const u8 * table,struct hid_report * report,int count,int strict)758*4882a593Smuzhiyun static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
759*4882a593Smuzhiyun 			     struct hid_report *report, int count, int strict)
760*4882a593Smuzhiyun {
761*4882a593Smuzhiyun 	int i, j, k, found;
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 	for (k = 0; k < count; k++) {
764*4882a593Smuzhiyun 		found = 0;
765*4882a593Smuzhiyun 		for (i = 0; i < report->maxfield; i++) {
766*4882a593Smuzhiyun 			if (report->field[i]->maxusage !=
767*4882a593Smuzhiyun 			    report->field[i]->report_count) {
768*4882a593Smuzhiyun 				pr_debug("maxusage and report_count do not match, skipping\n");
769*4882a593Smuzhiyun 				continue;
770*4882a593Smuzhiyun 			}
771*4882a593Smuzhiyun 			for (j = 0; j < report->field[i]->maxusage; j++) {
772*4882a593Smuzhiyun 				if (report->field[i]->usage[j].hid ==
773*4882a593Smuzhiyun 				    (HID_UP_PID | table[k])) {
774*4882a593Smuzhiyun 					pr_debug("found %d at %d->%d\n",
775*4882a593Smuzhiyun 						 k, i, j);
776*4882a593Smuzhiyun 					usage[k].field = report->field[i];
777*4882a593Smuzhiyun 					usage[k].value =
778*4882a593Smuzhiyun 						&report->field[i]->value[j];
779*4882a593Smuzhiyun 					found = 1;
780*4882a593Smuzhiyun 					break;
781*4882a593Smuzhiyun 				}
782*4882a593Smuzhiyun 			}
783*4882a593Smuzhiyun 			if (found)
784*4882a593Smuzhiyun 				break;
785*4882a593Smuzhiyun 		}
786*4882a593Smuzhiyun 		if (!found && strict) {
787*4882a593Smuzhiyun 			pr_debug("failed to locate %d\n", k);
788*4882a593Smuzhiyun 			return -1;
789*4882a593Smuzhiyun 		}
790*4882a593Smuzhiyun 	}
791*4882a593Smuzhiyun 	return 0;
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun /*
795*4882a593Smuzhiyun  * Return index into pidff_reports for the given usage
796*4882a593Smuzhiyun  */
pidff_check_usage(int usage)797*4882a593Smuzhiyun static int pidff_check_usage(int usage)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun 	int i;
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	for (i = 0; i < sizeof(pidff_reports); i++)
802*4882a593Smuzhiyun 		if (usage == (HID_UP_PID | pidff_reports[i]))
803*4882a593Smuzhiyun 			return i;
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	return -1;
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun /*
809*4882a593Smuzhiyun  * Find the reports and fill pidff->reports[]
810*4882a593Smuzhiyun  * report_type specifies either OUTPUT or FEATURE reports
811*4882a593Smuzhiyun  */
pidff_find_reports(struct hid_device * hid,int report_type,struct pidff_device * pidff)812*4882a593Smuzhiyun static void pidff_find_reports(struct hid_device *hid, int report_type,
813*4882a593Smuzhiyun 			       struct pidff_device *pidff)
814*4882a593Smuzhiyun {
815*4882a593Smuzhiyun 	struct hid_report *report;
816*4882a593Smuzhiyun 	int i, ret;
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 	list_for_each_entry(report,
819*4882a593Smuzhiyun 			    &hid->report_enum[report_type].report_list, list) {
820*4882a593Smuzhiyun 		if (report->maxfield < 1)
821*4882a593Smuzhiyun 			continue;
822*4882a593Smuzhiyun 		ret = pidff_check_usage(report->field[0]->logical);
823*4882a593Smuzhiyun 		if (ret != -1) {
824*4882a593Smuzhiyun 			hid_dbg(hid, "found usage 0x%02x from field->logical\n",
825*4882a593Smuzhiyun 				pidff_reports[ret]);
826*4882a593Smuzhiyun 			pidff->reports[ret] = report;
827*4882a593Smuzhiyun 			continue;
828*4882a593Smuzhiyun 		}
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 		/*
831*4882a593Smuzhiyun 		 * Sometimes logical collections are stacked to indicate
832*4882a593Smuzhiyun 		 * different usages for the report and the field, in which
833*4882a593Smuzhiyun 		 * case we want the usage of the parent. However, Linux HID
834*4882a593Smuzhiyun 		 * implementation hides this fact, so we have to dig it up
835*4882a593Smuzhiyun 		 * ourselves
836*4882a593Smuzhiyun 		 */
837*4882a593Smuzhiyun 		i = report->field[0]->usage[0].collection_index;
838*4882a593Smuzhiyun 		if (i <= 0 ||
839*4882a593Smuzhiyun 		    hid->collection[i - 1].type != HID_COLLECTION_LOGICAL)
840*4882a593Smuzhiyun 			continue;
841*4882a593Smuzhiyun 		ret = pidff_check_usage(hid->collection[i - 1].usage);
842*4882a593Smuzhiyun 		if (ret != -1 && !pidff->reports[ret]) {
843*4882a593Smuzhiyun 			hid_dbg(hid,
844*4882a593Smuzhiyun 				"found usage 0x%02x from collection array\n",
845*4882a593Smuzhiyun 				pidff_reports[ret]);
846*4882a593Smuzhiyun 			pidff->reports[ret] = report;
847*4882a593Smuzhiyun 		}
848*4882a593Smuzhiyun 	}
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun /*
852*4882a593Smuzhiyun  * Test if the required reports have been found
853*4882a593Smuzhiyun  */
pidff_reports_ok(struct pidff_device * pidff)854*4882a593Smuzhiyun static int pidff_reports_ok(struct pidff_device *pidff)
855*4882a593Smuzhiyun {
856*4882a593Smuzhiyun 	int i;
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun 	for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
859*4882a593Smuzhiyun 		if (!pidff->reports[i]) {
860*4882a593Smuzhiyun 			hid_dbg(pidff->hid, "%d missing\n", i);
861*4882a593Smuzhiyun 			return 0;
862*4882a593Smuzhiyun 		}
863*4882a593Smuzhiyun 	}
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun 	return 1;
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun /*
869*4882a593Smuzhiyun  * Find a field with a specific usage within a report
870*4882a593Smuzhiyun  */
pidff_find_special_field(struct hid_report * report,int usage,int enforce_min)871*4882a593Smuzhiyun static struct hid_field *pidff_find_special_field(struct hid_report *report,
872*4882a593Smuzhiyun 						  int usage, int enforce_min)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun 	int i;
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	for (i = 0; i < report->maxfield; i++) {
877*4882a593Smuzhiyun 		if (report->field[i]->logical == (HID_UP_PID | usage) &&
878*4882a593Smuzhiyun 		    report->field[i]->report_count > 0) {
879*4882a593Smuzhiyun 			if (!enforce_min ||
880*4882a593Smuzhiyun 			    report->field[i]->logical_minimum == 1)
881*4882a593Smuzhiyun 				return report->field[i];
882*4882a593Smuzhiyun 			else {
883*4882a593Smuzhiyun 				pr_err("logical_minimum is not 1 as it should be\n");
884*4882a593Smuzhiyun 				return NULL;
885*4882a593Smuzhiyun 			}
886*4882a593Smuzhiyun 		}
887*4882a593Smuzhiyun 	}
888*4882a593Smuzhiyun 	return NULL;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun /*
892*4882a593Smuzhiyun  * Fill a pidff->*_id struct table
893*4882a593Smuzhiyun  */
pidff_find_special_keys(int * keys,struct hid_field * fld,const u8 * usagetable,int count)894*4882a593Smuzhiyun static int pidff_find_special_keys(int *keys, struct hid_field *fld,
895*4882a593Smuzhiyun 				   const u8 *usagetable, int count)
896*4882a593Smuzhiyun {
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun 	int i, j;
899*4882a593Smuzhiyun 	int found = 0;
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
902*4882a593Smuzhiyun 		for (j = 0; j < fld->maxusage; j++) {
903*4882a593Smuzhiyun 			if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
904*4882a593Smuzhiyun 				keys[i] = j + 1;
905*4882a593Smuzhiyun 				found++;
906*4882a593Smuzhiyun 				break;
907*4882a593Smuzhiyun 			}
908*4882a593Smuzhiyun 		}
909*4882a593Smuzhiyun 	}
910*4882a593Smuzhiyun 	return found;
911*4882a593Smuzhiyun }
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun #define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
914*4882a593Smuzhiyun 	pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
915*4882a593Smuzhiyun 		sizeof(pidff_ ## name))
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun /*
918*4882a593Smuzhiyun  * Find and check the special fields
919*4882a593Smuzhiyun  */
pidff_find_special_fields(struct pidff_device * pidff)920*4882a593Smuzhiyun static int pidff_find_special_fields(struct pidff_device *pidff)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun 	hid_dbg(pidff->hid, "finding special fields\n");
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 	pidff->create_new_effect_type =
925*4882a593Smuzhiyun 		pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
926*4882a593Smuzhiyun 					 0x25, 1);
927*4882a593Smuzhiyun 	pidff->set_effect_type =
928*4882a593Smuzhiyun 		pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
929*4882a593Smuzhiyun 					 0x25, 1);
930*4882a593Smuzhiyun 	pidff->effect_direction =
931*4882a593Smuzhiyun 		pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
932*4882a593Smuzhiyun 					 0x57, 0);
933*4882a593Smuzhiyun 	pidff->device_control =
934*4882a593Smuzhiyun 		pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
935*4882a593Smuzhiyun 					 0x96, 1);
936*4882a593Smuzhiyun 	pidff->block_load_status =
937*4882a593Smuzhiyun 		pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
938*4882a593Smuzhiyun 					 0x8b, 1);
939*4882a593Smuzhiyun 	pidff->effect_operation_status =
940*4882a593Smuzhiyun 		pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
941*4882a593Smuzhiyun 					 0x78, 1);
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	hid_dbg(pidff->hid, "search done\n");
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 	if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
946*4882a593Smuzhiyun 		hid_err(pidff->hid, "effect lists not found\n");
947*4882a593Smuzhiyun 		return -1;
948*4882a593Smuzhiyun 	}
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	if (!pidff->effect_direction) {
951*4882a593Smuzhiyun 		hid_err(pidff->hid, "direction field not found\n");
952*4882a593Smuzhiyun 		return -1;
953*4882a593Smuzhiyun 	}
954*4882a593Smuzhiyun 
955*4882a593Smuzhiyun 	if (!pidff->device_control) {
956*4882a593Smuzhiyun 		hid_err(pidff->hid, "device control field not found\n");
957*4882a593Smuzhiyun 		return -1;
958*4882a593Smuzhiyun 	}
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	if (!pidff->block_load_status) {
961*4882a593Smuzhiyun 		hid_err(pidff->hid, "block load status field not found\n");
962*4882a593Smuzhiyun 		return -1;
963*4882a593Smuzhiyun 	}
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun 	if (!pidff->effect_operation_status) {
966*4882a593Smuzhiyun 		hid_err(pidff->hid, "effect operation field not found\n");
967*4882a593Smuzhiyun 		return -1;
968*4882a593Smuzhiyun 	}
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 	pidff_find_special_keys(pidff->control_id, pidff->device_control,
971*4882a593Smuzhiyun 				pidff_device_control,
972*4882a593Smuzhiyun 				sizeof(pidff_device_control));
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun 	if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
977*4882a593Smuzhiyun 				     effect_types)) {
978*4882a593Smuzhiyun 		hid_err(pidff->hid, "no effect types found\n");
979*4882a593Smuzhiyun 		return -1;
980*4882a593Smuzhiyun 	}
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
983*4882a593Smuzhiyun 				    block_load_status) !=
984*4882a593Smuzhiyun 			sizeof(pidff_block_load_status)) {
985*4882a593Smuzhiyun 		hid_err(pidff->hid,
986*4882a593Smuzhiyun 			"block load status identifiers not found\n");
987*4882a593Smuzhiyun 		return -1;
988*4882a593Smuzhiyun 	}
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 	if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
991*4882a593Smuzhiyun 				    effect_operation_status) !=
992*4882a593Smuzhiyun 			sizeof(pidff_effect_operation_status)) {
993*4882a593Smuzhiyun 		hid_err(pidff->hid, "effect operation identifiers not found\n");
994*4882a593Smuzhiyun 		return -1;
995*4882a593Smuzhiyun 	}
996*4882a593Smuzhiyun 
997*4882a593Smuzhiyun 	return 0;
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun /**
1001*4882a593Smuzhiyun  * Find the implemented effect types
1002*4882a593Smuzhiyun  */
pidff_find_effects(struct pidff_device * pidff,struct input_dev * dev)1003*4882a593Smuzhiyun static int pidff_find_effects(struct pidff_device *pidff,
1004*4882a593Smuzhiyun 			      struct input_dev *dev)
1005*4882a593Smuzhiyun {
1006*4882a593Smuzhiyun 	int i;
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun 	for (i = 0; i < sizeof(pidff_effect_types); i++) {
1009*4882a593Smuzhiyun 		int pidff_type = pidff->type_id[i];
1010*4882a593Smuzhiyun 		if (pidff->set_effect_type->usage[pidff_type].hid !=
1011*4882a593Smuzhiyun 		    pidff->create_new_effect_type->usage[pidff_type].hid) {
1012*4882a593Smuzhiyun 			hid_err(pidff->hid,
1013*4882a593Smuzhiyun 				"effect type number %d is invalid\n", i);
1014*4882a593Smuzhiyun 			return -1;
1015*4882a593Smuzhiyun 		}
1016*4882a593Smuzhiyun 	}
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun 	if (pidff->type_id[PID_CONSTANT])
1019*4882a593Smuzhiyun 		set_bit(FF_CONSTANT, dev->ffbit);
1020*4882a593Smuzhiyun 	if (pidff->type_id[PID_RAMP])
1021*4882a593Smuzhiyun 		set_bit(FF_RAMP, dev->ffbit);
1022*4882a593Smuzhiyun 	if (pidff->type_id[PID_SQUARE]) {
1023*4882a593Smuzhiyun 		set_bit(FF_SQUARE, dev->ffbit);
1024*4882a593Smuzhiyun 		set_bit(FF_PERIODIC, dev->ffbit);
1025*4882a593Smuzhiyun 	}
1026*4882a593Smuzhiyun 	if (pidff->type_id[PID_SINE]) {
1027*4882a593Smuzhiyun 		set_bit(FF_SINE, dev->ffbit);
1028*4882a593Smuzhiyun 		set_bit(FF_PERIODIC, dev->ffbit);
1029*4882a593Smuzhiyun 	}
1030*4882a593Smuzhiyun 	if (pidff->type_id[PID_TRIANGLE]) {
1031*4882a593Smuzhiyun 		set_bit(FF_TRIANGLE, dev->ffbit);
1032*4882a593Smuzhiyun 		set_bit(FF_PERIODIC, dev->ffbit);
1033*4882a593Smuzhiyun 	}
1034*4882a593Smuzhiyun 	if (pidff->type_id[PID_SAW_UP]) {
1035*4882a593Smuzhiyun 		set_bit(FF_SAW_UP, dev->ffbit);
1036*4882a593Smuzhiyun 		set_bit(FF_PERIODIC, dev->ffbit);
1037*4882a593Smuzhiyun 	}
1038*4882a593Smuzhiyun 	if (pidff->type_id[PID_SAW_DOWN]) {
1039*4882a593Smuzhiyun 		set_bit(FF_SAW_DOWN, dev->ffbit);
1040*4882a593Smuzhiyun 		set_bit(FF_PERIODIC, dev->ffbit);
1041*4882a593Smuzhiyun 	}
1042*4882a593Smuzhiyun 	if (pidff->type_id[PID_SPRING])
1043*4882a593Smuzhiyun 		set_bit(FF_SPRING, dev->ffbit);
1044*4882a593Smuzhiyun 	if (pidff->type_id[PID_DAMPER])
1045*4882a593Smuzhiyun 		set_bit(FF_DAMPER, dev->ffbit);
1046*4882a593Smuzhiyun 	if (pidff->type_id[PID_INERTIA])
1047*4882a593Smuzhiyun 		set_bit(FF_INERTIA, dev->ffbit);
1048*4882a593Smuzhiyun 	if (pidff->type_id[PID_FRICTION])
1049*4882a593Smuzhiyun 		set_bit(FF_FRICTION, dev->ffbit);
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 	return 0;
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun }
1054*4882a593Smuzhiyun 
1055*4882a593Smuzhiyun #define PIDFF_FIND_FIELDS(name, report, strict) \
1056*4882a593Smuzhiyun 	pidff_find_fields(pidff->name, pidff_ ## name, \
1057*4882a593Smuzhiyun 		pidff->reports[report], \
1058*4882a593Smuzhiyun 		sizeof(pidff_ ## name), strict)
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun /*
1061*4882a593Smuzhiyun  * Fill and check the pidff_usages
1062*4882a593Smuzhiyun  */
pidff_init_fields(struct pidff_device * pidff,struct input_dev * dev)1063*4882a593Smuzhiyun static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
1064*4882a593Smuzhiyun {
1065*4882a593Smuzhiyun 	int envelope_ok = 0;
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun 	if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
1068*4882a593Smuzhiyun 		hid_err(pidff->hid, "unknown set_effect report layout\n");
1069*4882a593Smuzhiyun 		return -ENODEV;
1070*4882a593Smuzhiyun 	}
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
1073*4882a593Smuzhiyun 	if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
1074*4882a593Smuzhiyun 		hid_err(pidff->hid, "unknown pid_block_load report layout\n");
1075*4882a593Smuzhiyun 		return -ENODEV;
1076*4882a593Smuzhiyun 	}
1077*4882a593Smuzhiyun 
1078*4882a593Smuzhiyun 	if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
1079*4882a593Smuzhiyun 		hid_err(pidff->hid, "unknown effect_operation report layout\n");
1080*4882a593Smuzhiyun 		return -ENODEV;
1081*4882a593Smuzhiyun 	}
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
1084*4882a593Smuzhiyun 		hid_err(pidff->hid, "unknown pid_block_free report layout\n");
1085*4882a593Smuzhiyun 		return -ENODEV;
1086*4882a593Smuzhiyun 	}
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	if (!PIDFF_FIND_FIELDS(set_envelope, PID_SET_ENVELOPE, 1))
1089*4882a593Smuzhiyun 		envelope_ok = 1;
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	if (pidff_find_special_fields(pidff) || pidff_find_effects(pidff, dev))
1092*4882a593Smuzhiyun 		return -ENODEV;
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun 	if (!envelope_ok) {
1095*4882a593Smuzhiyun 		if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
1096*4882a593Smuzhiyun 			hid_warn(pidff->hid,
1097*4882a593Smuzhiyun 				 "has constant effect but no envelope\n");
1098*4882a593Smuzhiyun 		if (test_and_clear_bit(FF_RAMP, dev->ffbit))
1099*4882a593Smuzhiyun 			hid_warn(pidff->hid,
1100*4882a593Smuzhiyun 				 "has ramp effect but no envelope\n");
1101*4882a593Smuzhiyun 
1102*4882a593Smuzhiyun 		if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
1103*4882a593Smuzhiyun 			hid_warn(pidff->hid,
1104*4882a593Smuzhiyun 				 "has periodic effect but no envelope\n");
1105*4882a593Smuzhiyun 	}
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	if (test_bit(FF_CONSTANT, dev->ffbit) &&
1108*4882a593Smuzhiyun 	    PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
1109*4882a593Smuzhiyun 		hid_warn(pidff->hid, "unknown constant effect layout\n");
1110*4882a593Smuzhiyun 		clear_bit(FF_CONSTANT, dev->ffbit);
1111*4882a593Smuzhiyun 	}
1112*4882a593Smuzhiyun 
1113*4882a593Smuzhiyun 	if (test_bit(FF_RAMP, dev->ffbit) &&
1114*4882a593Smuzhiyun 	    PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
1115*4882a593Smuzhiyun 		hid_warn(pidff->hid, "unknown ramp effect layout\n");
1116*4882a593Smuzhiyun 		clear_bit(FF_RAMP, dev->ffbit);
1117*4882a593Smuzhiyun 	}
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	if ((test_bit(FF_SPRING, dev->ffbit) ||
1120*4882a593Smuzhiyun 	     test_bit(FF_DAMPER, dev->ffbit) ||
1121*4882a593Smuzhiyun 	     test_bit(FF_FRICTION, dev->ffbit) ||
1122*4882a593Smuzhiyun 	     test_bit(FF_INERTIA, dev->ffbit)) &&
1123*4882a593Smuzhiyun 	    PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
1124*4882a593Smuzhiyun 		hid_warn(pidff->hid, "unknown condition effect layout\n");
1125*4882a593Smuzhiyun 		clear_bit(FF_SPRING, dev->ffbit);
1126*4882a593Smuzhiyun 		clear_bit(FF_DAMPER, dev->ffbit);
1127*4882a593Smuzhiyun 		clear_bit(FF_FRICTION, dev->ffbit);
1128*4882a593Smuzhiyun 		clear_bit(FF_INERTIA, dev->ffbit);
1129*4882a593Smuzhiyun 	}
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	if (test_bit(FF_PERIODIC, dev->ffbit) &&
1132*4882a593Smuzhiyun 	    PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
1133*4882a593Smuzhiyun 		hid_warn(pidff->hid, "unknown periodic effect layout\n");
1134*4882a593Smuzhiyun 		clear_bit(FF_PERIODIC, dev->ffbit);
1135*4882a593Smuzhiyun 	}
1136*4882a593Smuzhiyun 
1137*4882a593Smuzhiyun 	PIDFF_FIND_FIELDS(pool, PID_POOL, 0);
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	if (!PIDFF_FIND_FIELDS(device_gain, PID_DEVICE_GAIN, 1))
1140*4882a593Smuzhiyun 		set_bit(FF_GAIN, dev->ffbit);
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun 	return 0;
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun 
1145*4882a593Smuzhiyun /*
1146*4882a593Smuzhiyun  * Reset the device
1147*4882a593Smuzhiyun  */
pidff_reset(struct pidff_device * pidff)1148*4882a593Smuzhiyun static void pidff_reset(struct pidff_device *pidff)
1149*4882a593Smuzhiyun {
1150*4882a593Smuzhiyun 	struct hid_device *hid = pidff->hid;
1151*4882a593Smuzhiyun 	int i = 0;
1152*4882a593Smuzhiyun 
1153*4882a593Smuzhiyun 	pidff->device_control->value[0] = pidff->control_id[PID_RESET];
1154*4882a593Smuzhiyun 	/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
1155*4882a593Smuzhiyun 	hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1156*4882a593Smuzhiyun 	hid_hw_wait(hid);
1157*4882a593Smuzhiyun 	hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1158*4882a593Smuzhiyun 	hid_hw_wait(hid);
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 	pidff->device_control->value[0] =
1161*4882a593Smuzhiyun 		pidff->control_id[PID_ENABLE_ACTUATORS];
1162*4882a593Smuzhiyun 	hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1163*4882a593Smuzhiyun 	hid_hw_wait(hid);
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun 	/* pool report is sometimes messed up, refetch it */
1166*4882a593Smuzhiyun 	hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT);
1167*4882a593Smuzhiyun 	hid_hw_wait(hid);
1168*4882a593Smuzhiyun 
1169*4882a593Smuzhiyun 	if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
1170*4882a593Smuzhiyun 		while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
1171*4882a593Smuzhiyun 			if (i++ > 20) {
1172*4882a593Smuzhiyun 				hid_warn(pidff->hid,
1173*4882a593Smuzhiyun 					 "device reports %d simultaneous effects\n",
1174*4882a593Smuzhiyun 					 pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
1175*4882a593Smuzhiyun 				break;
1176*4882a593Smuzhiyun 			}
1177*4882a593Smuzhiyun 			hid_dbg(pidff->hid, "pid_pool requested again\n");
1178*4882a593Smuzhiyun 			hid_hw_request(hid, pidff->reports[PID_POOL],
1179*4882a593Smuzhiyun 					  HID_REQ_GET_REPORT);
1180*4882a593Smuzhiyun 			hid_hw_wait(hid);
1181*4882a593Smuzhiyun 		}
1182*4882a593Smuzhiyun 	}
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun /*
1186*4882a593Smuzhiyun  * Test if autocenter modification is using the supported method
1187*4882a593Smuzhiyun  */
pidff_check_autocenter(struct pidff_device * pidff,struct input_dev * dev)1188*4882a593Smuzhiyun static int pidff_check_autocenter(struct pidff_device *pidff,
1189*4882a593Smuzhiyun 				  struct input_dev *dev)
1190*4882a593Smuzhiyun {
1191*4882a593Smuzhiyun 	int error;
1192*4882a593Smuzhiyun 
1193*4882a593Smuzhiyun 	/*
1194*4882a593Smuzhiyun 	 * Let's find out if autocenter modification is supported
1195*4882a593Smuzhiyun 	 * Specification doesn't specify anything, so we request an
1196*4882a593Smuzhiyun 	 * effect upload and cancel it immediately. If the approved
1197*4882a593Smuzhiyun 	 * effect id was one above the minimum, then we assume the first
1198*4882a593Smuzhiyun 	 * effect id is a built-in spring type effect used for autocenter
1199*4882a593Smuzhiyun 	 */
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun 	error = pidff_request_effect_upload(pidff, 1);
1202*4882a593Smuzhiyun 	if (error) {
1203*4882a593Smuzhiyun 		hid_err(pidff->hid, "upload request failed\n");
1204*4882a593Smuzhiyun 		return error;
1205*4882a593Smuzhiyun 	}
1206*4882a593Smuzhiyun 
1207*4882a593Smuzhiyun 	if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
1208*4882a593Smuzhiyun 	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
1209*4882a593Smuzhiyun 		pidff_autocenter(pidff, 0xffff);
1210*4882a593Smuzhiyun 		set_bit(FF_AUTOCENTER, dev->ffbit);
1211*4882a593Smuzhiyun 	} else {
1212*4882a593Smuzhiyun 		hid_notice(pidff->hid,
1213*4882a593Smuzhiyun 			   "device has unknown autocenter control method\n");
1214*4882a593Smuzhiyun 	}
1215*4882a593Smuzhiyun 
1216*4882a593Smuzhiyun 	pidff_erase_pid(pidff,
1217*4882a593Smuzhiyun 			pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
1218*4882a593Smuzhiyun 
1219*4882a593Smuzhiyun 	return 0;
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun 
1223*4882a593Smuzhiyun /*
1224*4882a593Smuzhiyun  * Check if the device is PID and initialize it
1225*4882a593Smuzhiyun  */
hid_pidff_init(struct hid_device * hid)1226*4882a593Smuzhiyun int hid_pidff_init(struct hid_device *hid)
1227*4882a593Smuzhiyun {
1228*4882a593Smuzhiyun 	struct pidff_device *pidff;
1229*4882a593Smuzhiyun 	struct hid_input *hidinput = list_entry(hid->inputs.next,
1230*4882a593Smuzhiyun 						struct hid_input, list);
1231*4882a593Smuzhiyun 	struct input_dev *dev = hidinput->input;
1232*4882a593Smuzhiyun 	struct ff_device *ff;
1233*4882a593Smuzhiyun 	int max_effects;
1234*4882a593Smuzhiyun 	int error;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	hid_dbg(hid, "starting pid init\n");
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun 	if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
1239*4882a593Smuzhiyun 		hid_dbg(hid, "not a PID device, no output report\n");
1240*4882a593Smuzhiyun 		return -ENODEV;
1241*4882a593Smuzhiyun 	}
1242*4882a593Smuzhiyun 
1243*4882a593Smuzhiyun 	pidff = kzalloc(sizeof(*pidff), GFP_KERNEL);
1244*4882a593Smuzhiyun 	if (!pidff)
1245*4882a593Smuzhiyun 		return -ENOMEM;
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun 	pidff->hid = hid;
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun 	hid_device_io_start(hid);
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
1252*4882a593Smuzhiyun 	pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
1253*4882a593Smuzhiyun 
1254*4882a593Smuzhiyun 	if (!pidff_reports_ok(pidff)) {
1255*4882a593Smuzhiyun 		hid_dbg(hid, "reports not ok, aborting\n");
1256*4882a593Smuzhiyun 		error = -ENODEV;
1257*4882a593Smuzhiyun 		goto fail;
1258*4882a593Smuzhiyun 	}
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 	error = pidff_init_fields(pidff, dev);
1261*4882a593Smuzhiyun 	if (error)
1262*4882a593Smuzhiyun 		goto fail;
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun 	pidff_reset(pidff);
1265*4882a593Smuzhiyun 
1266*4882a593Smuzhiyun 	if (test_bit(FF_GAIN, dev->ffbit)) {
1267*4882a593Smuzhiyun 		pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
1268*4882a593Smuzhiyun 		hid_hw_request(hid, pidff->reports[PID_DEVICE_GAIN],
1269*4882a593Smuzhiyun 				     HID_REQ_SET_REPORT);
1270*4882a593Smuzhiyun 	}
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun 	error = pidff_check_autocenter(pidff, dev);
1273*4882a593Smuzhiyun 	if (error)
1274*4882a593Smuzhiyun 		goto fail;
1275*4882a593Smuzhiyun 
1276*4882a593Smuzhiyun 	max_effects =
1277*4882a593Smuzhiyun 	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
1278*4882a593Smuzhiyun 	    pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
1279*4882a593Smuzhiyun 	    1;
1280*4882a593Smuzhiyun 	hid_dbg(hid, "max effects is %d\n", max_effects);
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	if (max_effects > PID_EFFECTS_MAX)
1283*4882a593Smuzhiyun 		max_effects = PID_EFFECTS_MAX;
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 	if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
1286*4882a593Smuzhiyun 		hid_dbg(hid, "max simultaneous effects is %d\n",
1287*4882a593Smuzhiyun 			pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
1288*4882a593Smuzhiyun 
1289*4882a593Smuzhiyun 	if (pidff->pool[PID_RAM_POOL_SIZE].value)
1290*4882a593Smuzhiyun 		hid_dbg(hid, "device memory size is %d bytes\n",
1291*4882a593Smuzhiyun 			pidff->pool[PID_RAM_POOL_SIZE].value[0]);
1292*4882a593Smuzhiyun 
1293*4882a593Smuzhiyun 	if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
1294*4882a593Smuzhiyun 	    pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
1295*4882a593Smuzhiyun 		error = -EPERM;
1296*4882a593Smuzhiyun 		hid_notice(hid,
1297*4882a593Smuzhiyun 			   "device does not support device managed pool\n");
1298*4882a593Smuzhiyun 		goto fail;
1299*4882a593Smuzhiyun 	}
1300*4882a593Smuzhiyun 
1301*4882a593Smuzhiyun 	error = input_ff_create(dev, max_effects);
1302*4882a593Smuzhiyun 	if (error)
1303*4882a593Smuzhiyun 		goto fail;
1304*4882a593Smuzhiyun 
1305*4882a593Smuzhiyun 	ff = dev->ff;
1306*4882a593Smuzhiyun 	ff->private = pidff;
1307*4882a593Smuzhiyun 	ff->upload = pidff_upload_effect;
1308*4882a593Smuzhiyun 	ff->erase = pidff_erase_effect;
1309*4882a593Smuzhiyun 	ff->set_gain = pidff_set_gain;
1310*4882a593Smuzhiyun 	ff->set_autocenter = pidff_set_autocenter;
1311*4882a593Smuzhiyun 	ff->playback = pidff_playback;
1312*4882a593Smuzhiyun 
1313*4882a593Smuzhiyun 	hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun 	hid_device_io_stop(hid);
1316*4882a593Smuzhiyun 
1317*4882a593Smuzhiyun 	return 0;
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun  fail:
1320*4882a593Smuzhiyun 	hid_device_io_stop(hid);
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun 	kfree(pidff);
1323*4882a593Smuzhiyun 	return error;
1324*4882a593Smuzhiyun }
1325