Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15

Thread: Touchscreen changing usb event device on power on/off

  1. #11
    pkg
    pkg is offline
    Low Bitrate pkg's Avatar
    Join Date
    Apr 2005
    Location
    Arizona
    Posts
    96
    Updated my post above with the rule from my udev.rules file
    -pkg

    Check out my tC: http://publicjestering.com/tc
    Check out my site: http://publicjestering.com

  2. #12
    Newbie LavaJoe's Avatar
    Join Date
    Jul 2005
    Location
    Lafayette, CO
    Posts
    20
    Wow, have I been struggling with this one for the past week! Basically, all info here is good info. Yes, udev is one way to make the device name persistent. Problem is, once the USB device disconnects (happens for me every time I even start to close my in-dash display), even though it gets the same name again through udev, X seems to lose track of it, and it stops working (or reverts to the mouse device if you have that one enabled).

    Today I finally solved it!

    It involved a bit of kernel hacking, but I finally realized that the only solid solution is to mimic the /dev/input/mice device. This is a "mixer" device that catches all events from all mice. And the device is there from boot onward, even if no USB device is attached, so X never "loses" it.

    Of course, you cannot use /dev/input/mice, since the output is not the right format for a touch screen... Sooooo, I hacked "evdev.c", which is the counterpart to "mousedev.c", in the kernel, and I added a new mixer device called /dev/input/events (this goes in xorg.conf under the touchscreen section - note that I am using the evtouch X driver to translate events). I plan to confer with the developer of these kernel drivers to make sure what I did is OK (it's a bit hard to comprehend the whole workings of these quickly). I had to do a few things that were not obvious to avoid crashes (null pointers) - not issues in mousedev.c.

    But it works, at least so far, and no need for any udev rules or switching of virtual terminals (which I tried, but I found it did not always work right, and it causes lots of flashing on boot). If anyone wants the new evdev.c, email me. You'd need to get kernel source and rebuild the kernel, but it's worth it to have this working!

    -Joe



    Quote Originally Posted by pkg
    So I have finally came up with a fix, there were a few things that were all tied up

    I was originally NOT running udev on my system. This was a problem because the behavior of the Linux event interface system is to not constrain a device to a single event device in case the event is in use. So, udev is the solution.

    I installed udev. Incredibly easy on Debian (# apt-get install udev [doesn't get any easier than that!]). I then created a udev rule in the /etc/udev/udev.rules file:

    BUS="usb", KERNEL="event[0-3]*", SYSFS{product}="USB TouchController", SYMLINK="input/touchscreen"

    The rule above creates a symlink from whatever event device file the Linux kernel assigns to the touchscreen to /dev/input/touchscreen.
    "/dev/input/touchscreen" is the device that is used in the XF86Config-4 file for the touchscreen.

    Originally I had left out the KERNEL directive in the rule. This was causing udev to default to the /dev/input/ts0 device for the symlink. This does not work. Adding the KERNEL directive for the event devices fixed this problem and the symlink points to /dev/input/event1 (or event3 depending).

    I was then running into a problem with the pointer not working when the touchscreen would power back on. After doing A LOT of reading I came across the same bug that occurs when the system comes out of hibernation. X loses the pointer!.

    The solution to X losing the pointer was to switch virtual terminals out of X and then back in. ctrl+alt+F1, ctrl+alt+F7. This was not going to work in a keyboard-less system! I then came across a scriptable command "chvt". So, now that I could script the VT change I just needed a way to launch the script when the touchscreen was powered up. This is where hotplug comes in for linux.

    As some of you may know hotplug has the perfect facility for this type of thing (heck, it is what it was made for). So, I added a hotplug "handmap" to the system. I created a new file named touchkitusb in the /etc/hotplug/usb/ directory. This file is a bash script that (essentially) contains the commands: chvt 6; chvt 7. (This script is currently set SUID root though this is not the best way to do it. I will be doing sudo chvt inside of the script instead.)

    So what did this do? When the touchscreen is turned back on udev assigns the /dev/input/hotplug to the correct event# device. Hotplug then detects the device as coming up and executes the touchkitusb script. The system then changes to VT6 and then back to VT7, making the touchscreen work on a power off/power on!

    So what next? There was some mention of a kernel bug in 2.6.9 causing this behavior but I haven't seen any real reference to it yet. I will look into a kernel upgrade at some point. Those of you not using X will probably not have this problem. The udev configuration is mandatory for this situation, the hotplug script is a workaround for the pointer "bug".

    Hope this helps someone

  3. #13
    pkg
    pkg is offline
    Low Bitrate pkg's Avatar
    Join Date
    Apr 2005
    Location
    Arizona
    Posts
    96
    Awesome,

    This is a really good fix. Sounds like the TS problems are the same thing that made /dev/input/mice be created back in the day.

    Could you post a diff of your changes to evdev.c? It would be great to get this in the kernel as we have shown this to be a problem with touchscreens.

    I have limited my project to only use distro kernels so hopefully we can get this in.

    Good work!
    -pkg

    Check out my tC: http://publicjestering.com/tc
    Check out my site: http://publicjestering.com

  4. #14
    Newbie LavaJoe's Avatar
    Join Date
    Jul 2005
    Location
    Lafayette, CO
    Posts
    20
    Quote Originally Posted by pkg
    Awesome,

    This is a really good fix. Sounds like the TS problems are the same thing that made /dev/input/mice be created back in the day.

    Could you post a diff of your changes to evdev.c? It would be great to get this in the kernel as we have shown this to be a problem with touchscreens.

    I have limited my project to only use distro kernels so hopefully we can get this in.

    Good work!
    No problem - see below. Note that I still want to check with the devloper, since I am not convinced all of my changes are completely without issues.

    -Joe

    Code:
    10a11,18
    > /*
    >  * Modified 2005-8-12  Joe Peterson
    >  *
    >  *     - Added persistent mixer device "/dev/input/events"
    >  *       (analogous to mousedev.c's "/dev/input/mice")
    >  *
    >  */
    >
    12a21
    > #define EVDEV_MIX               31
    44a54,55
    > static struct input_handler evdev_handler;
    >
    45a57
    > static struct evdev evdev_mix;
    47c59
    < static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
    ---
    > static void evdev_handle_event(struct evdev *evdev, unsigned int type, unsigned int code, int value)
    49d60
    <       struct evdev *evdev = handle->private;
    76a88,95
    > static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
    > {
    >       struct evdev *evdev = handle->private;
    >
    >         evdev_handle_event(evdev, type, code, value);
    >         evdev_handle_event(&evdev_mix, type, code, value);
    > }
    >
    89c108,111
    <       return input_flush_device(&list->evdev->handle, file);
    ---
    >         if (list->evdev->handle.dev)
    >             return input_flush_device(&list->evdev->handle, file);
    >         else
    >             return 0;
    97a120,137
    > static int mixdev_release(void)
    > {
    >       struct input_handle *handle;
    >
    >       list_for_each_entry(handle, &evdev_handler.h_list, h_node) {
    >               struct evdev *evdev = handle->private;
    >
    >               if (!evdev->open) {
    >                       if (evdev->exist)
    >                               input_close_device(&evdev->handle);
    >                       else
    >                               evdev_free(evdev);
    >               }
    >       }
    >
    >       return 0;
    > }
    >
    111,114c151,159
    <               if (list->evdev->exist)
    <                       input_close_device(&list->evdev->handle);
    <               else
    <                       evdev_free(list->evdev);
    ---
    >               if (list->evdev->minor == EVDEV_MIX)
    >                       return mixdev_release();
    >
    >               if (!evdev_mix.open) {
    >                       if (list->evdev->exist)
    >                               input_close_device(&list->evdev->handle);
    >                       else
    >                               evdev_free(list->evdev);
    >               }
    123a169,170
    >       struct input_handle *handle;
    >       struct evdev *evdev;
    130c177,178
    <       if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
    ---
    >         if (evdev_table[i]->handle.dev)
    >             if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
    141,144c189,200
    <       if (!list->evdev->open++)
    <               if (list->evdev->exist)
    <                       input_open_device(&list->evdev->handle);
    <
    ---
    >       if (!list->evdev->open++) {
    >               if (list->evdev->minor == EVDEV_MIX) {
    >                       list_for_each_entry(handle, &evdev_handler.h_list, h_node) {
    >                               evdev = handle->private;
    >                               if (!evdev->open && evdev->exist)
    >                                       input_open_device(handle);
    >                       }
    >               } else
    >                       if (!evdev_mix.open && list->evdev->exist)
    >                               input_open_device(&list->evdev->handle);
    >         }
    >
    160c216,217
    <               input_event(list->evdev->handle.dev, event.type, event.code, event.value);
    ---
    >                 if (list->evdev->handle.dev)
    >                     input_event(list->evdev->handle.dev, event.type, event.code, event.value);
    271c328,329
    <                       if (arg) {
    ---
    >                         if (evdev->handle.dev) {
    >                             if (arg) {
    278c336
    <                       } else {
    ---
    >                           } else {
    284c342,345
    <                       }
    ---
    >                           }
    >                         } else {
    >                             return 0;
    >                         }
    429a491,493
    >       if (evdev_mix.open)
    >               input_open_device(&evdev->handle);
    >
    455c519,521
    <       } else
    ---
    >       } else {
    >               if (evdev_mix.open)
    >                       input_close_device(handle);
    456a523
    >         }
    478a546,560
    >
    >       memset(&evdev_mix, 0, sizeof(struct evdev));
    >       INIT_LIST_HEAD(&evdev_mix.list);
    >       init_waitqueue_head(&evdev_mix.wait);
    >       evdev_table[EVDEV_MIX] = &evdev_mix;
    >       evdev_mix.exist = 1;
    >       evdev_mix.minor = EVDEV_MIX;
    >
    >       devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + EVDEV_MIX),
    >                       S_IFCHR|S_IRUGO|S_IWUSR, "input/events");
    >       class_simple_device_add(input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + EVDEV_MIX),
    >                               NULL, "events");
    >
    >       printk(KERN_INFO "events: event device common for all events\n");
    >
    483a566,567
    >       devfs_remove("input/events");
    >       class_simple_device_remove(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + EVDEV_MIX));

  5. #15
    Newbie LavaJoe's Avatar
    Join Date
    Jul 2005
    Location
    Lafayette, CO
    Posts
    20
    Quote Originally Posted by pkg
    Awesome,

    This is a really good fix. Sounds like the TS problems are the same thing that made /dev/input/mice be created back in the day.

    Could you post a diff of your changes to evdev.c? It would be great to get this in the kernel as we have shown this to be a problem with touchscreens.

    I have limited my project to only use distro kernels so hopefully we can get this in.

    Good work!
    Well, a little bit of bad news: I had a discussion on the kernel mailing lists today with the author of evdev.c, and he feels that /dev/input/mice is actually a hack, and that X windows should fix it on their end (i.e. be hotplug friendly). He does not want to add another similar hack for events.

    Also, he says events can't mix the same way mouse events can. I know this does not affect us, since we will only have one touch screen and no mice, but in any case, it looks like this "feature" won't make it into the kernel distributions. I will look into other solutions, but for now you can always rebuild your kernel and use my patch. He suggested trying to create a "repeater daemon" using a uinput device. I did try, before modifying evdev, to create a fifo device to work like this, but I didn't spend long on it. Another idea he had was doing something like synaptics does in their X driver, auto-detecting the event device. I looked through their source, and I am not sure it would solve the issue of disconnecting and reconnecting or booting without the USB on, though. But a fix, using a similar idea, to evtouch.c might be possible. This is something I'd like to hack on, but I need to find the time!

    -Joe

Page 2 of 2 FirstFirst 12

Similar Threads

  1. Replies: 15
    Last Post: 05-04-2006, 04:53 PM
  2. Replies: 11
    Last Post: 07-11-2005, 10:28 AM
  3. DC-DC Car Power for Mac Mini
    By MikeH in forum MacCar
    Replies: 53
    Last Post: 02-19-2005, 12:13 PM
  4. USB Power problem please help
    By Uconnputer in forum Power Supplies
    Replies: 9
    Last Post: 12-06-2004, 11:29 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •