Fix low speed USB devices (keyboard, mouse, ...) on C-Series Trident


From SamyGO
Jump to: navigation, search

If you're having problems connecting your mouse or keyboard on a C-Series Trident, then keep reading this page.

Enabling low speed devices

If you are using the stock firmware modules and try to connect a low speed USB device (like a mouse or a keyboard) on a C-Series Trident chipset, this is what you'll get:

SELP#> dmesg
[...]
hub 1-1.2.1:1.0: cannot reset port 4 (err = -131)
### reset USB hub IC by D+/D ###
hub 1-1.2.1:1.0: cannot reset port 4 (err = -131)
### reset USB hub IC by D+/D ###
hub 1-1.2.1:1.0: Cannot enable port 4.  Maybe the USB cable is bad?
hub 1-1.2.1:1.0: cannot disable port 4 (err = -131)

This happens because of a Samsung hack to the usbcore.ko module.

Looking at the file drivers/usb/core/hub.c, in line 2264:

/* Added by Sean Long for low-speed device debounce*/
for(i = 0; (i < 10) && (udev->speed == USB_SPEED_LOW); i++){
   unsigned short reg16;
   unsigned int reg32;
   //gpio47 set port - output, 0x1b0055a0[15,14]-01
   reg16 = ReadRegHWord(0x1b0055a0);
   WriteRegHWord(0x1b0055a0, reg16 | (0x4000));
   //gpio47 set port - low, 0x1b0055a2[7]-0
   reg16 = ReadRegHWord(0x1b0055a2);
   WriteRegHWord(0x1b0055a2, reg16 & ~(0x0080));           /*trun off USB enable-GPIO7 (external port power)*/
   mdelay(100);                                            /*stable delay*/
   reg32 = ReadRegWord(0x1b003184);
   WriteRegWord(0x1b003184, reg32 | (8 | 2));              /*clear the port status register¡¯s related change bit*/
   //gpio47 set port - high, 0x1b0055a2[7]-1
   WriteRegHWord(0x1b0055a2, reg16 | (0x0080));            /*trun on USB enable-GPIO7 (external port power)*/
   mdelay(100);
   WriteRegWord(0x1b003184, reg32 | (8 | 2));
   retval = hub_port_reset(hub, port1, udev, delay);       /*reset the port again*/
   if (retval < 0)                                         /* error or disconnect */
      goto fail;
}

This loop was added by Samsung to prevent high speed USB devices from being detected as low speed. As a side effect, it makes low speed devices unusable.

To fix it just remove or comment out the code and replace the module (compiled module is available here):

SELP#> rmmod [...]            # Remove all usbcore.ko dependent modules
SELP#> umount /proc/bus/usb
SELP#> rmmod usbcore
SELP#> insmod usbcore.ko
SELP#> mount -t usbfs none /proc/bus/usb
SELP#> insmod [...]           # Insert all usbcore.ko dependent modules
SELP#> insmod evdev.ko
SELP#> insmod mousedev.ko
SELP#> insmod joydev.ko
SELP#> insmod xpad.ko
SELP#> dmesg
[...]
usb 1-1.1: new low speed USB device using trihidtv-ehci and address 5
usb 1-1.1: configuration #1 chosen from 1 choice
input: MosArt Optical Mouse as /class/input/input1
input: USB HID v1.10 Mouse [MosArt Optical Mouse] on usb-trihidtv-1.1

Adding new devices to /dev

Now that your mouse and keyboard are properly detected by the TV, it's time to make them available to any application that uses the linux input subsystem.

To do this, it's necessary to create new devices in /dev/input. The problem is that this directory does not exist and /dev is a read-only filesystem so you cannot make any changes to it.

SELP#> ls /dev/input/* -l
ls: /dev/input/*: No such file or directory
SELP#> mknod /dev/input/mice c 13 63
mknod: /dev/input/mice: No such file or directory
SELP#> mkdir /dev/input
mkdir: cannot create directory '/dev/input': Read-only file system

A possible work-around is to create a squashfs file with the content of /dev and add to it the missing devices. This file can then be mounted on top of /dev making the new devices available to applications (squashfs file available here).

SELP#> mount -t squashfs dev.img /dev
SELP#> mount -t devpts devpts /dev/pts
SELP#> ls /dev/input/* -l
crwxrwxrwx    1 root     0         13,  64 Jan 16  2011 /dev/input/event0
crwxrwxrwx    1 root     0         13,  65 Jan 16  2011 /dev/input/event1
[...]
crwxrwxrwx    1 root     0         13,   0 Jan 16  2011 /dev/input/js0
crwxrwxrwx    1 root     0         13,   1 Jan 16  2011 /dev/input/js1
[...]
crwxrwxrwx    1 root     0         13,  63 Jan 16  2011 /dev/input/mice
crwxrwxrwx    1 root     0         13,  32 Jan 16  2011 /dev/input/mouse0
crwxrwxrwx    1 root     0         13,  33 Jan 16  2011 /dev/input/mouse1
crwxrwxrwx    1 root     0         13,  42 Jan 16  2011 /dev/input/mouse10
[...]


NOTE: If you need to make any changes this file, be sure to use squashfs3.0 with big endian option (-be).


Make changes visible at boot time

With everything working properly, you'll probably want to make all these changes visible at boot time. Since it depends on whether you have a custom boot script, SamyGo, or a mix of both, I'll leave you with an example that you can adapt to your need.