@@ -94,29 +94,6 @@ struct i2c_hid_desc {
9494 __le32 reserved ;
9595} __packed ;
9696
97- struct i2c_hid_cmd {
98- unsigned int registerIndex ;
99- __u8 opcode ;
100- unsigned int length ;
101- };
102-
103- #define I2C_HID_CMD (opcode_ ) \
104- .opcode = opcode_, .length = 4, \
105- .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister)
106-
107- /* commands */
108- static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD (0x02 ) };
109-
110- /*
111- * These definitions are not used here, but are defined by the spec.
112- * Keeping them here for documentation purposes.
113- *
114- * static const struct i2c_hid_cmd hid_get_idle_cmd = { I2C_HID_CMD(0x04) };
115- * static const struct i2c_hid_cmd hid_set_idle_cmd = { I2C_HID_CMD(0x05) };
116- * static const struct i2c_hid_cmd hid_get_protocol_cmd = { I2C_HID_CMD(0x06) };
117- * static const struct i2c_hid_cmd hid_set_protocol_cmd = { I2C_HID_CMD(0x07) };
118- */
119-
12097/* The main device structure */
12198struct i2c_hid {
12299 struct i2c_client * client ; /* i2c client */
@@ -258,52 +235,62 @@ static size_t i2c_hid_encode_command(u8 *buf, u8 opcode,
258235 return length ;
259236}
260237
261- static int __i2c_hid_command (struct i2c_hid * ihid ,
262- const struct i2c_hid_cmd * command , u8 reportID ,
263- u8 reportType , u8 * args , int args_len ,
264- unsigned char * buf_recv , int data_len )
238+ static int i2c_hid_get_report (struct i2c_hid * ihid ,
239+ u8 report_type , u8 report_id ,
240+ u8 * recv_buf , size_t recv_len )
265241{
266- int length = command -> length ;
267- unsigned int registerIndex = command -> registerIndex ;
268-
269- ihid -> cmdbuf [0 ] = ihid -> hdesc_buffer [registerIndex ];
270- ihid -> cmdbuf [1 ] = ihid -> hdesc_buffer [registerIndex + 1 ];
242+ size_t length = 0 ;
243+ size_t ret_count ;
244+ int error ;
271245
272- if (length > 2 ) {
273- length = sizeof (__le16 ) + /* register */
274- i2c_hid_encode_command (ihid -> cmdbuf + sizeof (__le16 ),
275- command -> opcode ,
276- reportType , reportID );
277- }
246+ i2c_hid_dbg (ihid , "%s\n" , __func__ );
278247
279- memcpy (ihid -> cmdbuf + length , args , args_len );
280- length += args_len ;
248+ /* Command register goes first */
249+ * (__le16 * )ihid -> cmdbuf = ihid -> hdesc .wCommandRegister ;
250+ length += sizeof (__le16 );
251+ /* Next is GET_REPORT command */
252+ length += i2c_hid_encode_command (ihid -> cmdbuf + length ,
253+ I2C_HID_OPCODE_GET_REPORT ,
254+ report_type , report_id );
255+ /*
256+ * Device will send report data through data register. Because
257+ * command can be either 2 or 3 bytes destination for the data
258+ * register may be not aligned.
259+ */
260+ put_unaligned_le16 (le16_to_cpu (ihid -> hdesc .wDataRegister ),
261+ ihid -> cmdbuf + length );
262+ length += sizeof (__le16 );
281263
282- return i2c_hid_xfer (ihid , ihid -> cmdbuf , length , buf_recv , data_len );
283- }
264+ /*
265+ * In addition to report data device will supply data length
266+ * in the first 2 bytes of the response, so adjust .
267+ */
268+ error = i2c_hid_xfer (ihid , ihid -> cmdbuf , length ,
269+ ihid -> rawbuf , recv_len + sizeof (__le16 ));
270+ if (error ) {
271+ dev_err (& ihid -> client -> dev ,
272+ "failed to set a report to device: %d\n" , error );
273+ return error ;
274+ }
284275
285- static int i2c_hid_get_report (struct i2c_hid * ihid , u8 reportType ,
286- u8 reportID , unsigned char * buf_recv , int data_len )
287- {
288- u8 args [2 ];
289- int ret ;
290- int args_len = 0 ;
291- u16 readRegister = le16_to_cpu (ihid -> hdesc .wDataRegister );
276+ /* The buffer is sufficiently aligned */
277+ ret_count = le16_to_cpup ((__le16 * )ihid -> rawbuf );
292278
293- i2c_hid_dbg (ihid , "%s\n" , __func__ );
279+ /* Check for empty report response */
280+ if (ret_count <= sizeof (__le16 ))
281+ return 0 ;
294282
295- args [ args_len ++ ] = readRegister & 0xFF ;
296- args [ args_len ++ ] = readRegister >> 8 ;
283+ recv_len = min ( recv_len , ret_count - sizeof ( __le16 )) ;
284+ memcpy ( recv_buf , ihid -> rawbuf + sizeof ( __le16 ), recv_len ) ;
297285
298- ret = __i2c_hid_command (ihid , & hid_get_report_cmd , reportID ,
299- reportType , args , args_len , buf_recv , data_len );
300- if (ret ) {
286+ if (report_id && recv_len != 0 && recv_buf [0 ] != report_id ) {
301287 dev_err (& ihid -> client -> dev ,
302- "failed to retrieve report from device.\n" );
303- return ret ;
288+ "device returned incorrect report (%d vs %d expected)\n" ,
289+ recv_buf [0 ], report_id );
290+ return - EINVAL ;
304291 }
305292
306- return 0 ;
293+ return recv_len ;
307294}
308295
309296static size_t i2c_hid_format_report (u8 * buf , int report_id ,
@@ -654,13 +641,12 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size)
654641}
655642
656643static int i2c_hid_get_raw_report (struct hid_device * hid ,
657- unsigned char report_number , __u8 * buf , size_t count ,
658- unsigned char report_type )
644+ u8 report_type , u8 report_id ,
645+ u8 * buf , size_t count )
659646{
660647 struct i2c_client * client = hid -> driver_data ;
661648 struct i2c_hid * ihid = i2c_get_clientdata (client );
662- size_t ret_count , ask_count ;
663- int ret ;
649+ int ret_count ;
664650
665651 if (report_type == HID_OUTPUT_REPORT )
666652 return - EINVAL ;
@@ -670,42 +656,24 @@ static int i2c_hid_get_raw_report(struct hid_device *hid,
670656 * not have the report ID that the upper layers expect, so we need
671657 * to stash it the buffer ourselves and adjust the data size.
672658 */
673- if (!report_number ) {
659+ if (!report_id ) {
674660 buf [0 ] = 0 ;
675661 buf ++ ;
676662 count -- ;
677663 }
678664
679- /* +2 bytes to include the size of the reply in the query buffer */
680- ask_count = min (count + 2 , (size_t )ihid -> bufsize );
681-
682- ret = i2c_hid_get_report (ihid ,
665+ ret_count = i2c_hid_get_report (ihid ,
683666 report_type == HID_FEATURE_REPORT ? 0x03 : 0x01 ,
684- report_number , ihid -> rawbuf , ask_count );
685-
686- if (ret < 0 )
687- return ret ;
688-
689- ret_count = ihid -> rawbuf [0 ] | (ihid -> rawbuf [1 ] << 8 );
690-
691- if (ret_count <= 2 )
692- return 0 ;
693-
694- ret_count = min (ret_count , ask_count );
695-
696- /* The query buffer contains the size, dropping it in the reply */
697- count = min (count , ret_count - 2 );
698- memcpy (buf , ihid -> rawbuf + 2 , count );
667+ report_id , buf , count );
699668
700- if (! report_number )
701- count ++ ;
669+ if (ret_count > 0 && ! report_id )
670+ ret_count ++ ;
702671
703- return count ;
672+ return ret_count ;
704673}
705674
706- static int i2c_hid_output_raw_report (struct hid_device * hid ,
707- const u8 * buf , size_t count ,
708- u8 report_type , bool do_set )
675+ static int i2c_hid_output_raw_report (struct hid_device * hid , u8 report_type ,
676+ const u8 * buf , size_t count , bool do_set )
709677{
710678 struct i2c_client * client = hid -> driver_data ;
711679 struct i2c_hid * ihid = i2c_get_clientdata (client );
@@ -738,7 +706,7 @@ static int i2c_hid_output_raw_report(struct hid_device *hid,
738706
739707static int i2c_hid_output_report (struct hid_device * hid , u8 * buf , size_t count )
740708{
741- return i2c_hid_output_raw_report (hid , buf , count , HID_OUTPUT_REPORT ,
709+ return i2c_hid_output_raw_report (hid , HID_OUTPUT_REPORT , buf , count ,
742710 false);
743711}
744712
@@ -748,11 +716,11 @@ static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum,
748716{
749717 switch (reqtype ) {
750718 case HID_REQ_GET_REPORT :
751- return i2c_hid_get_raw_report (hid , reportnum , buf , len , rtype );
719+ return i2c_hid_get_raw_report (hid , rtype , reportnum , buf , len );
752720 case HID_REQ_SET_REPORT :
753721 if (buf [0 ] != reportnum )
754722 return - EINVAL ;
755- return i2c_hid_output_raw_report (hid , buf , len , rtype , true);
723+ return i2c_hid_output_raw_report (hid , rtype , buf , len , true);
756724 default :
757725 return - EIO ;
758726 }
0 commit comments