3535#include <linux/kernel.h>
3636#include <linux/hid.h>
3737#include <linux/mutex.h>
38+ #include <asm/unaligned.h>
3839
3940#include "../hid-ids.h"
4041#include "i2c-hid.h"
4748#define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6)
4849#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7)
4950
51+ /* Command opcodes */
52+ #define I2C_HID_OPCODE_RESET 0x01
53+ #define I2C_HID_OPCODE_GET_REPORT 0x02
54+ #define I2C_HID_OPCODE_SET_REPORT 0x03
55+ #define I2C_HID_OPCODE_GET_IDLE 0x04
56+ #define I2C_HID_OPCODE_SET_IDLE 0x05
57+ #define I2C_HID_OPCODE_GET_PROTOCOL 0x06
58+ #define I2C_HID_OPCODE_SET_PROTOCOL 0x07
59+ #define I2C_HID_OPCODE_SET_POWER 0x08
5060
5161/* flags */
5262#define I2C_HID_STARTED 0
@@ -90,16 +100,6 @@ struct i2c_hid_cmd {
90100 unsigned int length ;
91101};
92102
93- union command {
94- u8 data [0 ];
95- struct cmd {
96- __le16 reg ;
97- __u8 reportTypeID ;
98- __u8 opcode ;
99- __u8 reportID ;
100- } __packed c ;
101- };
102-
103103#define I2C_HID_CMD (opcode_ ) \
104104 .opcode = opcode_, .length = 4, \
105105 .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister)
@@ -115,9 +115,7 @@ static const struct i2c_hid_cmd hid_report_descr_cmd = {
115115/* commands */
116116static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD (0x01 ) };
117117static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD (0x02 ) };
118- static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD (0x03 ) };
119118static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD (0x08 ) };
120- static const struct i2c_hid_cmd hid_no_cmd = { .length = 0 };
121119
122120/*
123121 * These definitions are not used here, but are defined by the spec.
@@ -144,7 +142,6 @@ struct i2c_hid {
144142 u8 * inbuf ; /* Input buffer */
145143 u8 * rawbuf ; /* Raw Input buffer */
146144 u8 * cmdbuf ; /* Command buffer */
147- u8 * argsbuf ; /* Command arguments buffer */
148145
149146 unsigned long flags ; /* device flags */
150147 unsigned long quirks ; /* Various quirks */
@@ -206,67 +203,90 @@ static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct)
206203 return quirks ;
207204}
208205
206+ static int i2c_hid_xfer (struct i2c_hid * ihid ,
207+ u8 * send_buf , int send_len , u8 * recv_buf , int recv_len )
208+ {
209+ struct i2c_client * client = ihid -> client ;
210+ struct i2c_msg msgs [2 ] = { 0 };
211+ int n = 0 ;
212+ int ret ;
213+
214+ if (send_len ) {
215+ i2c_hid_dbg (ihid , "%s: cmd=%*ph\n" ,
216+ __func__ , send_len , send_buf );
217+
218+ msgs [n ].addr = client -> addr ;
219+ msgs [n ].flags = client -> flags & I2C_M_TEN ;
220+ msgs [n ].len = send_len ;
221+ msgs [n ].buf = send_buf ;
222+ n ++ ;
223+ }
224+
225+ if (recv_len ) {
226+ msgs [n ].addr = client -> addr ;
227+ msgs [n ].flags = (client -> flags & I2C_M_TEN ) | I2C_M_RD ;
228+ msgs [n ].len = recv_len ;
229+ msgs [n ].buf = recv_buf ;
230+ n ++ ;
231+
232+ set_bit (I2C_HID_READ_PENDING , & ihid -> flags );
233+ }
234+
235+ ret = i2c_transfer (client -> adapter , msgs , n );
236+
237+ if (recv_len )
238+ clear_bit (I2C_HID_READ_PENDING , & ihid -> flags );
239+
240+ if (ret != n )
241+ return ret < 0 ? ret : - EIO ;
242+
243+ return 0 ;
244+ }
245+
246+ static size_t i2c_hid_encode_command (u8 * buf , u8 opcode ,
247+ int report_type , int report_id )
248+ {
249+ size_t length = 0 ;
250+
251+ if (report_id < 0x0F ) {
252+ buf [length ++ ] = report_type << 4 | report_id ;
253+ buf [length ++ ] = opcode ;
254+ } else {
255+ buf [length ++ ] = report_type << 4 | 0x0F ;
256+ buf [length ++ ] = opcode ;
257+ buf [length ++ ] = report_id ;
258+ }
259+
260+ return length ;
261+ }
262+
209263static int __i2c_hid_command (struct i2c_hid * ihid ,
210264 const struct i2c_hid_cmd * command , u8 reportID ,
211265 u8 reportType , u8 * args , int args_len ,
212266 unsigned char * buf_recv , int data_len )
213267{
214- struct i2c_client * client = ihid -> client ;
215- union command * cmd = (union command * )ihid -> cmdbuf ;
216- int ret ;
217- struct i2c_msg msg [2 ];
218- int msg_num = 1 ;
219-
220268 int length = command -> length ;
221269 unsigned int registerIndex = command -> registerIndex ;
222270
223271 /* special case for hid_descr_cmd */
224272 if (command == & hid_descr_cmd ) {
225- cmd -> c . reg = ihid -> wHIDDescRegister ;
273+ * ( __le16 * ) ihid -> cmdbuf = ihid -> wHIDDescRegister ;
226274 } else {
227- cmd -> data [0 ] = ihid -> hdesc_buffer [registerIndex ];
228- cmd -> data [1 ] = ihid -> hdesc_buffer [registerIndex + 1 ];
275+ ihid -> cmdbuf [0 ] = ihid -> hdesc_buffer [registerIndex ];
276+ ihid -> cmdbuf [1 ] = ihid -> hdesc_buffer [registerIndex + 1 ];
229277 }
230278
231279 if (length > 2 ) {
232- cmd -> c .opcode = command -> opcode ;
233- if (reportID < 0x0F ) {
234- cmd -> c .reportTypeID = reportType << 4 | reportID ;
235- } else {
236- cmd -> c .reportTypeID = reportType << 4 | 0x0F ;
237- cmd -> c .reportID = reportID ;
238- length ++ ;
239- }
280+ length = sizeof (__le16 ) + /* register */
281+ i2c_hid_encode_command (ihid -> cmdbuf + sizeof (__le16 ),
282+ command -> opcode ,
283+ reportType , reportID );
240284 }
241285
242- memcpy (cmd -> data + length , args , args_len );
286+ memcpy (ihid -> cmdbuf + length , args , args_len );
243287 length += args_len ;
244288
245- i2c_hid_dbg (ihid , "%s: cmd=%*ph\n" , __func__ , length , cmd -> data );
246-
247- msg [0 ].addr = client -> addr ;
248- msg [0 ].flags = client -> flags & I2C_M_TEN ;
249- msg [0 ].len = length ;
250- msg [0 ].buf = cmd -> data ;
251- if (data_len > 0 ) {
252- msg [1 ].addr = client -> addr ;
253- msg [1 ].flags = client -> flags & I2C_M_TEN ;
254- msg [1 ].flags |= I2C_M_RD ;
255- msg [1 ].len = data_len ;
256- msg [1 ].buf = buf_recv ;
257- msg_num = 2 ;
258- set_bit (I2C_HID_READ_PENDING , & ihid -> flags );
259- }
260-
261- ret = i2c_transfer (client -> adapter , msg , msg_num );
262-
263- if (data_len > 0 )
264- clear_bit (I2C_HID_READ_PENDING , & ihid -> flags );
265-
266- if (ret != msg_num )
267- return ret < 0 ? ret : - EIO ;
268-
269- return 0 ;
289+ return i2c_hid_xfer (ihid , ihid -> cmdbuf , length , buf_recv , data_len );
270290}
271291
272292static int i2c_hid_command (struct i2c_hid * ihid ,
@@ -301,70 +321,81 @@ static int i2c_hid_get_report(struct i2c_hid *ihid, u8 reportType,
301321 return 0 ;
302322}
303323
324+ static size_t i2c_hid_format_report (u8 * buf , int report_id ,
325+ const u8 * data , size_t size )
326+ {
327+ size_t length = sizeof (__le16 ); /* reserve space to store size */
328+
329+ if (report_id )
330+ buf [length ++ ] = report_id ;
331+
332+ memcpy (buf + length , data , size );
333+ length += size ;
334+
335+ /* Store overall size in the beginning of the buffer */
336+ put_unaligned_le16 (length , buf );
337+
338+ return length ;
339+ }
340+
304341/**
305342 * i2c_hid_set_or_send_report: forward an incoming report to the device
306343 * @ihid: the i2c hid device
307- * @reportType : 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT
308- * @reportID : the report ID
344+ * @report_type : 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT
345+ * @report_id : the report ID
309346 * @buf: the actual data to transfer, without the report ID
310347 * @data_len: size of buf
311- * @use_data : true: use SET_REPORT HID command, false: send plain OUTPUT report
348+ * @do_set : true: use SET_REPORT HID command, false: send plain OUTPUT report
312349 */
313- static int i2c_hid_set_or_send_report (struct i2c_hid * ihid , u8 reportType ,
314- u8 reportID , unsigned char * buf , size_t data_len , bool use_data )
350+ static int i2c_hid_set_or_send_report (struct i2c_hid * ihid ,
351+ u8 report_type , u8 report_id ,
352+ const u8 * buf , size_t data_len ,
353+ bool do_set )
315354{
316- u8 * args = ihid -> argsbuf ;
317- const struct i2c_hid_cmd * hidcmd ;
318- int ret ;
319- u16 dataRegister = le16_to_cpu (ihid -> hdesc .wDataRegister );
320- u16 outputRegister = le16_to_cpu (ihid -> hdesc .wOutputRegister );
321- u16 maxOutputLength = le16_to_cpu (ihid -> hdesc .wMaxOutputLength );
322- u16 size ;
323- int args_len ;
324- int index = 0 ;
355+ size_t length = 0 ;
356+ int error ;
325357
326358 i2c_hid_dbg (ihid , "%s\n" , __func__ );
327359
328360 if (data_len > ihid -> bufsize )
329361 return - EINVAL ;
330362
331- size = 2 /* size */ +
332- (reportID ? 1 : 0 ) /* reportID */ +
333- data_len /* buf */ ;
334- args_len = 2 /* dataRegister */ +
335- size /* args */ ;
336-
337- if (!use_data && maxOutputLength == 0 )
363+ if (!do_set && le16_to_cpu (ihid -> hdesc .wMaxOutputLength ) == 0 )
338364 return - ENOSYS ;
339365
340- /*
341- * use the data register for feature reports or if the device does not
342- * support the output register
343- */
344- if (use_data ) {
345- args [index ++ ] = dataRegister & 0xFF ;
346- args [index ++ ] = dataRegister >> 8 ;
347- hidcmd = & hid_set_report_cmd ;
366+ if (do_set ) {
367+ /* Command register goes first */
368+ * (__le16 * )ihid -> cmdbuf = ihid -> hdesc .wCommandRegister ;
369+ length += sizeof (__le16 );
370+ /* Next is SET_REPORT command */
371+ length += i2c_hid_encode_command (ihid -> cmdbuf + length ,
372+ I2C_HID_OPCODE_SET_REPORT ,
373+ report_type , report_id );
374+ /*
375+ * Report data will go into the data register. Because
376+ * command can be either 2 or 3 bytes destination for
377+ * the data register may be not aligned.
378+ */
379+ put_unaligned_le16 (le16_to_cpu (ihid -> hdesc .wDataRegister ),
380+ ihid -> cmdbuf + length );
381+ length += sizeof (__le16 );
348382 } else {
349- args [index ++ ] = outputRegister & 0xFF ;
350- args [index ++ ] = outputRegister >> 8 ;
351- hidcmd = & hid_no_cmd ;
383+ /*
384+ * With simple "send report" all data goes into the output
385+ * register.
386+ */
387+ * (__le16 * )ihid -> cmdbuf = ihid -> hdesc .wOutputRegister ;;
388+ length += sizeof (__le16 );
352389 }
353390
354- args [index ++ ] = size & 0xFF ;
355- args [index ++ ] = size >> 8 ;
356-
357- if (reportID )
358- args [index ++ ] = reportID ;
391+ length += i2c_hid_format_report (ihid -> cmdbuf + length ,
392+ report_id , buf , data_len );
359393
360- memcpy (& args [index ], buf , data_len );
361-
362- ret = __i2c_hid_command (ihid , hidcmd , reportID ,
363- reportType , args , args_len , NULL , 0 );
364- if (ret ) {
394+ error = i2c_hid_xfer (ihid , ihid -> cmdbuf , length , NULL , 0 );
395+ if (error ) {
365396 dev_err (& ihid -> client -> dev ,
366- "failed to set a report to device. \n" );
367- return ret ;
397+ "failed to set a report to device: %d \n" , error );
398+ return error ;
368399 }
369400
370401 return data_len ;
@@ -578,31 +609,33 @@ static void i2c_hid_free_buffers(struct i2c_hid *ihid)
578609{
579610 kfree (ihid -> inbuf );
580611 kfree (ihid -> rawbuf );
581- kfree (ihid -> argsbuf );
582612 kfree (ihid -> cmdbuf );
583613 ihid -> inbuf = NULL ;
584614 ihid -> rawbuf = NULL ;
585615 ihid -> cmdbuf = NULL ;
586- ihid -> argsbuf = NULL ;
587616 ihid -> bufsize = 0 ;
588617}
589618
590619static int i2c_hid_alloc_buffers (struct i2c_hid * ihid , size_t report_size )
591620{
592- /* the worst case is computed from the set_report command with a
593- * reportID > 15 and the maximum report length */
594- int args_len = sizeof (__u8 ) + /* ReportID */
595- sizeof (__u8 ) + /* optional ReportID byte */
596- sizeof (__u16 ) + /* data register */
597- sizeof (__u16 ) + /* size of the report */
598- report_size ; /* report */
621+ /*
622+ * The worst case is computed from the set_report command with a
623+ * reportID > 15 and the maximum report length.
624+ */
625+ int cmd_len = sizeof (__le16 ) + /* command register */
626+ sizeof (u8 ) + /* encoded report type/ID */
627+ sizeof (u8 ) + /* opcode */
628+ sizeof (u8 ) + /* optional 3rd byte report ID */
629+ sizeof (__le16 ) + /* data register */
630+ sizeof (__le16 ) + /* report data size */
631+ sizeof (u8 ) + /* report ID if numbered report */
632+ report_size ;
599633
600634 ihid -> inbuf = kzalloc (report_size , GFP_KERNEL );
601635 ihid -> rawbuf = kzalloc (report_size , GFP_KERNEL );
602- ihid -> argsbuf = kzalloc (args_len , GFP_KERNEL );
603- ihid -> cmdbuf = kzalloc (sizeof (union command ) + args_len , GFP_KERNEL );
636+ ihid -> cmdbuf = kzalloc (cmd_len , GFP_KERNEL );
604637
605- if (!ihid -> inbuf || !ihid -> rawbuf || !ihid -> argsbuf || ! ihid -> cmdbuf ) {
638+ if (!ihid -> inbuf || !ihid -> rawbuf || !ihid -> cmdbuf ) {
606639 i2c_hid_free_buffers (ihid );
607640 return - ENOMEM ;
608641 }
@@ -662,8 +695,9 @@ static int i2c_hid_get_raw_report(struct hid_device *hid,
662695 return count ;
663696}
664697
665- static int i2c_hid_output_raw_report (struct hid_device * hid , __u8 * buf ,
666- size_t count , unsigned char report_type , bool use_data )
698+ static int i2c_hid_output_raw_report (struct hid_device * hid ,
699+ const u8 * buf , size_t count ,
700+ u8 report_type , bool do_set )
667701{
668702 struct i2c_client * client = hid -> driver_data ;
669703 struct i2c_hid * ihid = i2c_get_clientdata (client );
@@ -684,7 +718,7 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
684718 */
685719 ret = i2c_hid_set_or_send_report (ihid ,
686720 report_type == HID_FEATURE_REPORT ? 0x03 : 0x02 ,
687- report_id , buf + 1 , count - 1 , use_data );
721+ report_id , buf + 1 , count - 1 , do_set );
688722
689723 if (ret >= 0 )
690724 ret ++ ; /* add report_id to the number of transferred bytes */
@@ -694,11 +728,10 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
694728 return ret ;
695729}
696730
697- static int i2c_hid_output_report (struct hid_device * hid , __u8 * buf ,
698- size_t count )
731+ static int i2c_hid_output_report (struct hid_device * hid , u8 * buf , size_t count )
699732{
700733 return i2c_hid_output_raw_report (hid , buf , count , HID_OUTPUT_REPORT ,
701- false);
734+ false);
702735}
703736
704737static int i2c_hid_raw_request (struct hid_device * hid , unsigned char reportnum ,
0 commit comments