imon remote (15c2:0038) + rc-6 (mce) + ubuntu precise 12.04: a brute-force approach

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
rickx Offline
Senior Member
Posts: 159
Joined: Feb 2009
Reputation: 0
Post: #1
After a couple of rather happy years with my HTPC, I recently came back to this wonderful forum deciding to give pvr, eden and precise a try.
My HTPC is a quad-core core 2 with ION chipset and our beloved IMON remote system. The remote stopped working some months ago - a hardware problem. I replaced it with a Harmony 525 which had been hidden in a drawer since I got it. Back in the days (last time I went through all the setting up) there was a nice mod param to switch the protocol, so that was the only thing to do...more or less.
Now everything has changed regarding lirc, and more in general in handling remote controls in linux. I read tons of tutorials, bug reports, solution proposals...nothing was really satisfying and always left some ugly behavior hidden somewhere.
For example:
- first the remote did not work at all, allthough the imon module etc was loaded
- then I learned about ir-keytable: that helped a bit, but it still was not a nice and smooth solution: all that mapping and key table assigning was not clear
- sometimes ir-keytables would simply hang and block the terminal, giving no responses at all
- I found out a bug may be the cause, one that is patched in the current ubuntu git kernel
- I compiled the kernel using my current config but the problems did not solve completely
- I removed everything from rc_maps.cfg and rc.local: that made things look a bit better
- I found out that rc_maps.cfg is (more or less?) useless: I removed it and nothing changed. I always had rc-imon-pad and imon loading
- this meant that everything happened in the kernel, so that's where I started to look around

So after all this introduction:
- I'll tell how to have a perfect solution for an imon receiver using an mce remote (or protocol) with ubuntu precise 12.04

Advantages:
- boot and use (aka plug and play) the remote
- no lirc
- no ir-keytable
- no xml or any other key/table/mapping editing
- no other related bugs

Disadvantages:
- kernel compilation necessary
- no noob solution
- no switching back to imon protocol using the obtained kernel! (but any other may be used for that)
- no quick key remapping/adding/editing: a new compilation is needed (but kernel compilations after the first are much faster)

What is changed:
The kernel will load ir-imon-mce (instead of rc-imon-pad) and use the rc-6 protocol (used by MCE remotes) in ANY case.
It will load the perfect key table (rc-imon-mce module is just that) from the very beginning, so no need to change anything later

So, if you're still interested AND
- are no linux noob AND
- are going to use ONLY MCE remotes/protocol anyway AND
- are unhappy with your current solution AND
- are using ubuntu 12.04 (may work on older, but don't know) AND
- are not using lirc for other than xbmc
- etc..

, here are the steps to do:
1) Kernel compilation part 1
- download and prepare
Code:
mkdir src
cd src
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-precise
drink beer and wait
fakeroot debian/rules clean
cp -vi /boot/config-`uname -r` .config #loads your current config, that's ok
make localmodconfig #compiles the modules you're already using instead of the whole bunch
if something is missing, this was my source: https://help.ubuntu.com/community/Kernel/Compile
- patch
Code:
diff -ruN ubuntu-precise/drivers/media/rc/imon.c linux-source-3.2.0/drivers/media/rc/imon.c
--- ubuntu-precise/drivers/media/rc/imon.c    2012-04-15 16:28:59.920332374 +0200
+++ linux-source-3.2.0/drivers/media/rc/imon.c    2012-04-14 22:04:21.971754763 +0200
@@ -1008,34 +1013,35 @@
    struct device *dev = ictx->dev;
    bool unlock = false;
    unsigned char ir_proto_packet[] = {
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };

    if (rc_type && !(rc_type & rc->allowed_protos))
        dev_warn(dev, "Looks like you're trying to use an IR protocol "
             "this device does not support\n");

-    switch (rc_type) {
-    case RC_TYPE_RC6:
-        dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
-        ir_proto_packet[0] = 0x01;
-        break;
-    case RC_TYPE_UNKNOWN:
-    case RC_TYPE_OTHER:
-        dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
-        if (!pad_stabilize)
-            dev_dbg(dev, "PAD stabilize functionality disabled\n");
-        /* ir_proto_packet[0] = 0x00; // already the default */
-        rc_type = RC_TYPE_OTHER;
-        break;
-    default:
-        dev_warn(dev, "Unsupported IR protocol specified, overriding "
-             "to iMON IR protocol\n");
-        if (!pad_stabilize)
-            dev_dbg(dev, "PAD stabilize functionality disabled\n");
-        /* ir_proto_packet[0] = 0x00; // already the default */
-        rc_type = RC_TYPE_OTHER;
-        break;
-    }
+    //switch (rc_type) {
+    //case RC_TYPE_RC6:
+        //dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
+    dev_warn(dev, "Configuring IR receiver for MCE protocol\n");
+    //    ir_proto_packet[0] = 0x01;
+    //    break;
+    //case RC_TYPE_UNKNOWN:
+    //case RC_TYPE_OTHER:
+    //    dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
+    //    if (!pad_stabilize)
+    //        dev_dbg(dev, "PAD stabilize functionality disabled\n");
+    //    /* ir_proto_packet[0] = 0x00; // already the default */
+    //    rc_type = RC_TYPE_OTHER;
+    //    break;
+    //default:
+    //    dev_warn(dev, "Unsupported IR protocol specified, overriding "
+    //         "to iMON IR protocol\n");
+    //    if (!pad_stabilize)
+    //        dev_dbg(dev, "PAD stabilize functionality disabled\n");
+    //    /* ir_proto_packet[0] = 0x00; // already the default */
+    //    rc_type = RC_TYPE_OTHER;
+    //    break;
+    //}

    memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));

@@ -1893,10 +1899,10 @@

    imon_set_display_type(ictx);

-    if (ictx->rc_type == RC_TYPE_RC6)
+    //if (ictx->rc_type == RC_TYPE_RC6)
        rdev->map_name = RC_MAP_IMON_MCE;
-    else
-        rdev->map_name = RC_MAP_IMON_PAD;
+    //else
+    //    rdev->map_name = RC_MAP_IMON_PAD;

    ret = rc_register_device(rdev);
    if (ret < 0) {
diff -ruN ubuntu-precise/drivers/media/rc/keymaps/rc-imon-mce.c linux-source-3.2.0/drivers/media/rc/keymaps/rc-imon-mce.c
--- ubuntu-precise/drivers/media/rc/keymaps/rc-imon-mce.c    2012-04-15 16:28:59.928332374 +0200
+++ linux-source-3.2.0/drivers/media/rc/keymaps/rc-imon-mce.c    2012-04-15 15:13:44.570435206 +0200
@@ -36,12 +36,12 @@
    { 0x800ff421, KEY_RIGHT },

    /* 0x800ff40b also KEY_NUMERIC_POUND on some receivers */
-    { 0x800ff40b, KEY_ENTER },
+    /*{ 0x800ff40b, KEY_ENTER },*/
    { 0x02000028, KEY_ENTER },
-/* the OK and Enter buttons decode to the same value on some remotes
-    { 0x02000028, KEY_OK }, */
-    { 0x800ff422, KEY_OK },
-    { 0x0200002a, KEY_EXIT },
+/* the OK and Enter buttons decode to the same value on some remotes */
+    /*{ 0x02000028, KEY_OK }, */
+    /*{ 0x800ff422, KEY_OK }, */
+    { 0x0200002a, KEY_ESC },
    { 0x800ff423, KEY_EXIT },
    { 0x02000029, KEY_DELETE },
    /* 0x800ff40a also KEY_NUMERIC_STAR on some receivers */
@@ -88,13 +88,13 @@
    { 0x800ff449, KEY_CAMERA },
    { 0x800ff44a, KEY_VIDEO },
    /* 0x800ff424 also KEY_MENU on some receivers */
-    { 0x800ff424, KEY_DVD },
+    { 0x800ff424, KEY_C },
    /* 0x800ff425 also KEY_GREEN on some receivers */
    { 0x800ff425, KEY_TUNER }, /* LiveTV */
    { 0x800ff450, KEY_RADIO },

    { 0x800ff44c, KEY_LANGUAGE },
-    { 0x800ff427, KEY_ZOOM }, /* Aspect */
+    { 0x800ff427, KEY_BACK }, /* Aspect */

    { 0x800ff45b, KEY_RED },
    { 0x800ff45c, KEY_GREEN },
@@ -102,16 +102,16 @@
    { 0x800ff45e, KEY_BLUE },

    { 0x800ff466, KEY_RED },
-    /* { 0x800ff425, KEY_GREEN }, */
+        { 0x800ff425, KEY_GREEN },
    { 0x800ff468, KEY_YELLOW },
-    /* { 0x800ff41d, KEY_BLUE }, */
+    { 0x800ff41d, KEY_BLUE },

-    { 0x800ff40f, KEY_INFO },
-    { 0x800ff426, KEY_EPG }, /* Guide */
+    { 0x800ff40f, KEY_I },
+    { 0x800ff426, KEY_TAB }, /* Guide */
    { 0x800ff45a, KEY_SUBTITLE }, /* Caption/Teletext */
    { 0x800ff44d, KEY_TITLE },

-    { 0x800ff40c, KEY_POWER },
+    { 0x800ff40c, KEY_END },
    { 0x800ff40d, KEY_MEDIA }, /* Windows MCE button */

};

Before applying this code to the downloaded kernel source, pay attention to the last part! You'll recognize it's nothing more than a key table. The keys I used work out of the box and cover all main functions (also info, menu, tab, back, previous menu which are the ones usually not willing...) but your remote may be different, so change accordingly. To test you may use ir-keytable with a customized key table; once satisfied, transfer the codes/keynames to the patch before applying.
ALSO NOTE: this codes work out of the box IF AND ONLY IF you removed lirc! This means your remote will be seen as an SDLkeboard and therefore the same mapping as for keyboards applies (e.g. i button for info, tab for fullscreen video/music and back, end for power off etc.). If you go through lirc, NOT ALL the mappings will work!

So
Code:
sudo apt-get purge lirc
in case it's installed.

- compilation part 2
Code:
#export CONCURRENCY_LEVEL=3 --> use this with number = cores +1 (e.g. 3 for dual core), similar to make -j2
fakeroot make-kpkg --initrd --append-to-version=-some-string-here kernel-image kernel-headers # --> substitute that some-string-here :s

- done
Reboot and test
Be happy like me: everything is working again (including airplay and live-tv)!!

P.S. Sorry if I jumped over some steps, you may still ask though Big Grin

P.P.S. Ok, imonlcd is still not working with icons etc but all the rest...
(This post was last modified: 2012-04-15 17:57 by rickx.)
find quote