2010年5月29日 星期六

linux USB hid driver cypress_m8.c

參考 USB Device Class Definition for Human Interface Devices(HID)
firmware spec version 1.11,範例 driver 是 USB Cypress M8 driver
~linux/drivers/usb/serial/cypress_m8.c,source code 中說有
文件就在 ~linux/Documentation/usb/usb-serial.txt。

主要是看 DeLorme Earthmate USB 的 usb hid 如何設定,她使用的
是 feature report 的方式,在 control pipe 傳送 5 bytes 資料。
對應到 USB HID spec 的 7.2 Class-specific Requests 裡面的 7.2.1
Get_Report Request 跟 7.2.2 Set_Report Request,透過 control
pipe 傳送 host <-> device 資料。

呼叫 usb_control_msg(),定義在 USB core 的實作中
~linux/drivers/usb/core/message.c:


/**
* usb_control_msg - Builds a control urb, sends it off and waits for completion
* @dev: pointer to the usb device to send the message to
* @pipe: endpoint "pipe" to send the message to
* @request: USB message request value
* @requesttype: USB message request type value
* @value: USB message value
* @index: USB message index value
* @data: pointer to the data to send
* @size: length in bytes of the data to send
* @timeout: time in msecs to wait for the message to complete before timing
* out (if 0 the wait is forever)
*
* Context: !in_interrupt ()
*
...
*/
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data,
__u16 size, int timeout)



有兩種用法,差異在於傳輸方向,是以 host 為主體而有 in/out, set/get 不同。
一個是 host 傳到 device(out/set),另一個是 device 到 host(in/get)。

host->device 是 USB_DIR_OUT,使用 HID_REQ_SET_REPORT request
建立 send endpoint pipe 是用 usb_sndctrlpipe()

device->host 是 USB_DIR_IN,使用 HID_REQ_GET_REPORT request
建立 receive endpoint pipe 是用 usb_rcvctrlpipe()


retval = usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0),
HID_REQ_SET_REPORT,
USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
0x0300, 0, feature_buffer,
feature_len, 500);

retval = usb_control_msg(port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0),
HID_REQ_GET_REPORT,
USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
0x0300, 0, feature_buffer,
feature_len, 500);


第一個參數就是 struct usb_device *dev,probe 時就可以取到
第二個是利用 MACRO 從 usb device 找到 usb device 的 endpoint pipe
第三個參數是 message request value,HID_REQ_SET_REPORT 或
HID_REQ_GET_REPORT
第四個是 message request type value,
USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 或
USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,

第五個參數是 message value 看 device hard code: 0x0300
第六個參數是 message index value hard code: 0

因為採用的是 feature report 的方式傳送 5 bytes 資料存在
第七個參數 feature_buffer 中,
第八個參數是 feature_len 是資料長度。
第九個參數是 500 micro seconds 的 timeout。

相關文章:

TI OMAP3 DM3730 USB host controller high full low speed?



相關連結:

http://www.usb.org/developers/devclass_docs/HID1_11.pdf

~linux/drivers/usb/serial/cypress_m8.c

~linux/drivers/usb/core/message.c