xref: /openbmc/obmc-ikvm/create_usbhid.sh (revision a6c8f5d778eb7d2e14e85b6be6e4d5fc71a1d9a3)
1b9c253dcSEddie James#!/bin/sh
2b9c253dcSEddie James
3c11257d8SJae Hyun Yoohid_conf_directory="/sys/kernel/config/usb_gadget/obmc_hid"
4c11257d8SJae Hyun Yoodev_name="1e6a0000.usb-vhub"
5b9c253dcSEddie James
6c11257d8SJae Hyun Yoocreate_hid() {
7b9c253dcSEddie James    # create gadget
8c11257d8SJae Hyun Yoo    mkdir "${hid_conf_directory}"
967a9bd4bSPatrick Williams    cd "${hid_conf_directory}" || exit 1
10b9c253dcSEddie James
11b9c253dcSEddie James    # add basic information
12b9c253dcSEddie James    echo 0x0100 > bcdDevice
13b9c253dcSEddie James    echo 0x0200 > bcdUSB
14b9c253dcSEddie James    echo 0x0104 > idProduct		# Multifunction Composite Gadget
15b9c253dcSEddie James    echo 0x1d6b > idVendor		# Linux Foundation
16b9c253dcSEddie James
17b9c253dcSEddie James    # create English locale
18b9c253dcSEddie James    mkdir strings/0x409
19b9c253dcSEddie James
20b9c253dcSEddie James    echo "OpenBMC" > strings/0x409/manufacturer
21*a6c8f5d7SMohammed Javith Akthar M    echo "Virtual Keyboard and Mouse" > strings/0x409/product
22b9c253dcSEddie James    echo "OBMC0001" > strings/0x409/serialnumber
23b9c253dcSEddie James
247dfac9ffSJae Hyun Yoo    # Create HID keyboard function
257dfac9ffSJae Hyun Yoo    mkdir functions/hid.0
26b9c253dcSEddie James
277dfac9ffSJae Hyun Yoo    echo 1 > functions/hid.0/protocol	# 1: keyboard
287dfac9ffSJae Hyun Yoo    echo 8 > functions/hid.0/report_length
297dfac9ffSJae Hyun Yoo    echo 1 > functions/hid.0/subclass
30b9c253dcSEddie James
317dfac9ffSJae Hyun Yoo    # Binary HID keyboard descriptor
327dfac9ffSJae Hyun Yoo    #  0x05, 0x01, // USAGE_PAGE (Generic Desktop)
337dfac9ffSJae Hyun Yoo    #  0x09, 0x06, // USAGE (Keyboard)
347dfac9ffSJae Hyun Yoo    #  0xa1, 0x01, // COLLECTION (Application)
357dfac9ffSJae Hyun Yoo    #  0x05, 0x07, //   USAGE_PAGE (Keyboard)
367dfac9ffSJae Hyun Yoo    #  0x19, 0xe0, //   USAGE_MINIMUM (Keyboard LeftControl)
377dfac9ffSJae Hyun Yoo    #  0x29, 0xe7, //   USAGE_MAXIMUM (Keyboard Right GUI)
387dfac9ffSJae Hyun Yoo    #  0x15, 0x00, //   LOGICAL_MINIMUM (0)
397dfac9ffSJae Hyun Yoo    #  0x25, 0x01, //   LOGICAL_MAXIMUM (1)
407dfac9ffSJae Hyun Yoo    #  0x75, 0x01, //   REPORT_SIZE (1)
417dfac9ffSJae Hyun Yoo    #  0x95, 0x08, //   REPORT_COUNT (8)
427dfac9ffSJae Hyun Yoo    #  0x81, 0x02, //   INPUT (Data,Var,Abs)
437dfac9ffSJae Hyun Yoo    #  0x95, 0x01, //   REPORT_COUNT (1)
447dfac9ffSJae Hyun Yoo    #  0x75, 0x08, //   REPORT_SIZE (8)
457dfac9ffSJae Hyun Yoo    #  0x81, 0x03, //   INPUT (Data,Var,Abs)
467dfac9ffSJae Hyun Yoo    #  0x95, 0x05, //   REPORT_COUNT (5)
477dfac9ffSJae Hyun Yoo    #  0x75, 0x01, //   REPORT_SIZE (1)
487dfac9ffSJae Hyun Yoo    #  0x05, 0x08, //   USAGE_PAGE (LEDs)
497dfac9ffSJae Hyun Yoo    #  0x19, 0x01, //   USAGE_MINIMUM (Num Lock)
507dfac9ffSJae Hyun Yoo    #  0x29, 0x05, //   USAGE_MAXIMUM (Kana)
517dfac9ffSJae Hyun Yoo    #  0x91, 0x02, //   OUTPUT (Data,Var,Abs)
527dfac9ffSJae Hyun Yoo    #  0x95, 0x01, //   REPORT_COUNT (1)
537dfac9ffSJae Hyun Yoo    #  0x75, 0x03, //   REPORT_SIZE (3)
547dfac9ffSJae Hyun Yoo    #  0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)
557dfac9ffSJae Hyun Yoo    #  0x95, 0x06, //   REPORT_COUNT (6)
567dfac9ffSJae Hyun Yoo    #  0x75, 0x08, //   REPORT_SIZE (8)
577dfac9ffSJae Hyun Yoo    #  0x15, 0x00, //   LOGICAL_MINIMUM (0)
587dfac9ffSJae Hyun Yoo    #  0x25, 0x65, //   LOGICAL_MAXIMUM (101)
597dfac9ffSJae Hyun Yoo    #  0x05, 0x07, //   USAGE_PAGE (Keyboard)
607dfac9ffSJae Hyun Yoo    #  0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))
617dfac9ffSJae Hyun Yoo    #  0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)
627dfac9ffSJae Hyun Yoo    #  0x81, 0x00, //   INPUT (Data,Ary,Abs)
637dfac9ffSJae Hyun Yoo    #  0xc0        // END_COLLECTION
64c85668dbSJae Hyun Yoo    printf '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x03\x95\x05\x75\x01\x05\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x03\x95\x06\x75\x08\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0' > functions/hid.0/report_desc
657dfac9ffSJae Hyun Yoo
667dfac9ffSJae Hyun Yoo    # Create HID mouse function
677dfac9ffSJae Hyun Yoo    mkdir functions/hid.1
687dfac9ffSJae Hyun Yoo
697dfac9ffSJae Hyun Yoo    echo 2 > functions/hid.1/protocol	# 2: mouse
703fa0bfbaSTejas Patil    echo 6 > functions/hid.1/report_length
717dfac9ffSJae Hyun Yoo    echo 1 > functions/hid.1/subclass
727dfac9ffSJae Hyun Yoo
737dfac9ffSJae Hyun Yoo    # Binary HID mouse descriptor (absolute coordinate)
747dfac9ffSJae Hyun Yoo    #  0x05, 0x01,       // USAGE_PAGE (Generic Desktop)
757dfac9ffSJae Hyun Yoo    #  0x09, 0x02,       // USAGE (Mouse)
767dfac9ffSJae Hyun Yoo    #  0xa1, 0x01,       // COLLECTION (Application)
777dfac9ffSJae Hyun Yoo    #  0x09, 0x01,       //   USAGE (Pointer)
787dfac9ffSJae Hyun Yoo    #  0xa1, 0x00,       //   COLLECTION (Physical)
797dfac9ffSJae Hyun Yoo    #  0x05, 0x09,       //     USAGE_PAGE (Button)
807dfac9ffSJae Hyun Yoo    #  0x19, 0x01,       //     USAGE_MINIMUM (Button 1)
817dfac9ffSJae Hyun Yoo    #  0x29, 0x03,       //     USAGE_MAXIMUM (Button 3)
827dfac9ffSJae Hyun Yoo    #  0x15, 0x00,       //     LOGICAL_MINIMUM (0)
837dfac9ffSJae Hyun Yoo    #  0x25, 0x01,       //     LOGICAL_MAXIMUM (1)
847dfac9ffSJae Hyun Yoo    #  0x95, 0x03,       //     REPORT_COUNT (3)
857dfac9ffSJae Hyun Yoo    #  0x75, 0x01,       //     REPORT_SIZE (1)
867dfac9ffSJae Hyun Yoo    #  0x81, 0x02,       //     INPUT (Data,Var,Abs)
877dfac9ffSJae Hyun Yoo    #  0x95, 0x01,       //     REPORT_COUNT (1)
887dfac9ffSJae Hyun Yoo    #  0x75, 0x05,       //     REPORT_SIZE (5)
897dfac9ffSJae Hyun Yoo    #  0x81, 0x03,       //     INPUT (Cnst,Var,Abs)
907dfac9ffSJae Hyun Yoo    #  0x05, 0x01,       //     USAGE_PAGE (Generic Desktop)
917dfac9ffSJae Hyun Yoo    #  0x09, 0x30,       //     USAGE (X)
927dfac9ffSJae Hyun Yoo    #  0x09, 0x31,       //     USAGE (Y)
937dfac9ffSJae Hyun Yoo    #  0x35, 0x00,       //     PHYSICAL_MINIMUM (0)
947dfac9ffSJae Hyun Yoo    #  0x46, 0xff, 0x7f, //     PHYSICAL_MAXIMUM (32767)
957dfac9ffSJae Hyun Yoo    #  0x15, 0x00,       //     LOGICAL_MINIMUM (0)
967dfac9ffSJae Hyun Yoo    #  0x26, 0xff, 0x7f, //     LOGICAL_MAXIMUM (32767)
977dfac9ffSJae Hyun Yoo    #  0x65, 0x11,       //     UNIT (SI Lin:Distance)
987dfac9ffSJae Hyun Yoo    #  0x55, 0x00,       //     UNIT_EXPONENT (0)
997dfac9ffSJae Hyun Yoo    #  0x75, 0x10,       //     REPORT_SIZE (16)
1007dfac9ffSJae Hyun Yoo    #  0x95, 0x02,       //     REPORT_COUNT (2)
1017dfac9ffSJae Hyun Yoo    #  0x81, 0x02,       //     INPUT (Data,Var,Abs)
1023fa0bfbaSTejas Patil    #  0x09, 0x38,       //     Usage (Wheel)
1033fa0bfbaSTejas Patil    #  0x15, 0xff,       //     LOGICAL_MINIMUM (-1)
1043fa0bfbaSTejas Patil    #  0x25, 0x01,       //     LOGICAL_MAXIMUM (1)
1053fa0bfbaSTejas Patil    #  0x35, 0x00,       //     PHYSICAL_MINIMUM (-127)
1063fa0bfbaSTejas Patil    #  0x45, 0x00,       //     PHYSICAL_MAXIMUM (127)
1073fa0bfbaSTejas Patil    #  0x75, 0x08,       //     REPORT_SIZE (8)
1083fa0bfbaSTejas Patil    #  0x95, 0x01,       //     REPORT_COUNT (1)
1093fa0bfbaSTejas Patil    #  0x81, 0x06,       //     INPUT (Data,Var,Rel)
1107dfac9ffSJae Hyun Yoo    #  0xc0,             //   END_COLLECTION
1117dfac9ffSJae Hyun Yoo    #  0xc0              // END_COLLECTION
112c85668dbSJae Hyun Yoo    printf '\x05\x01\x09\x02\xa1\x01\x09\x01\xa1\x00\x05\x09\x19\x01\x29\x03\x15\x00\x25\x01\x95\x03\x75\x01\x81\x02\x95\x01\x75\x05\x81\x03\x05\x01\x09\x30\x09\x31\x35\x00\x46\xff\x7f\x15\x00\x26\xff\x7f\x65\x11\x55\x00\x75\x10\x95\x02\x81\x02\x09\x38\x15\xff\x25\x01\x35\x00\x45\x00\x75\x08\x95\x01\x81\x06\xc0\xc0' > functions/hid.1/report_desc
1137dfac9ffSJae Hyun Yoo
114b9c253dcSEddie James    # Create configuration
115b9c253dcSEddie James    mkdir configs/c.1
116b9c253dcSEddie James    mkdir configs/c.1/strings/0x409
117b9c253dcSEddie James
1183b201f69SNeal Liu    echo 0xe0 > configs/c.1/bmAttributes
119b9c253dcSEddie James    echo 200 > configs/c.1/MaxPower
120b9c253dcSEddie James    echo "" > configs/c.1/strings/0x409/configuration
121b9c253dcSEddie James
1227dfac9ffSJae Hyun Yoo    # Link HID functions to configuration
1237dfac9ffSJae Hyun Yoo    ln -s functions/hid.0 configs/c.1
1247dfac9ffSJae Hyun Yoo    ln -s functions/hid.1 configs/c.1
125c11257d8SJae Hyun Yoo}
126b9c253dcSEddie James
127c11257d8SJae Hyun Yooconnect_hid() {
128c85668dbSJae Hyun Yoo    if ! grep -q "${dev_name}:p" UDC; then
129b9c253dcSEddie James        i=0
130b9c253dcSEddie James        num_ports=5
131b9c253dcSEddie James        base_usb_dir="/sys/bus/platform/devices/${dev_name}/${dev_name}:p"
132c85668dbSJae Hyun Yoo        while [ "${i}" -lt "${num_ports}" ]; do
133c85668dbSJae Hyun Yoo            port=$(("${i}" + 1))
134c85668dbSJae Hyun Yoo            i="${port}"
135b9c253dcSEddie James            if [ ! -e "${base_usb_dir}${port}/gadget/suspended" ]; then
136b9c253dcSEddie James                break
137b9c253dcSEddie James            fi
138b9c253dcSEddie James        done
139b9c253dcSEddie James        echo "${dev_name}:p${port}" > UDC
140c11257d8SJae Hyun Yoo    fi
141c11257d8SJae Hyun Yoo}
142c11257d8SJae Hyun Yoo
143c11257d8SJae Hyun Yoodisconnect_hid() {
144c85668dbSJae Hyun Yoo    if grep -q "${dev_name}:p" UDC; then
145c11257d8SJae Hyun Yoo        echo "" > UDC
146c11257d8SJae Hyun Yoo    fi
147c11257d8SJae Hyun Yoo}
148c11257d8SJae Hyun Yoo
149c11257d8SJae Hyun Yooif [ ! -e "${hid_conf_directory}" ]; then
150c11257d8SJae Hyun Yoo    create_hid
151c11257d8SJae Hyun Yooelse
15267a9bd4bSPatrick Williams    cd "${hid_conf_directory}" || exit 1
153c11257d8SJae Hyun Yoofi
154c11257d8SJae Hyun Yoo
155c11257d8SJae Hyun Yooif [ "$1" = "connect" ]; then
156c11257d8SJae Hyun Yoo    connect_hid
157c11257d8SJae Hyun Yooelif [ "$1" = "disconnect" ]; then
158c11257d8SJae Hyun Yoo    disconnect_hid
159c11257d8SJae Hyun Yooelse
160c85668dbSJae Hyun Yoo    echo >&2 "Invalid option: $1. Use 'connect' or 'disconnect'."
161c85668dbSJae Hyun Yoo    exit 1
162c11257d8SJae Hyun Yoofi
163