NUC NUC6i3SYK with Linux + Kodi

On this page i'll add some information about getting Kodi working on a 6th generation Intel NUC - specifically a NUC6i3SYK

No Audio using Pulse Audio

When first starting Kodi without forcing direct Alsa sync (as called out here http://kodi.wiki/view/HOW-TO:Install_Kodi_on_an_Intel_NUC#disable_PulseAudio) , could not get sound.

Found that users could not list video cards using aplay -l

[dylan@kodiarch ~]$ aplay -l

aplay: device_list:268: no soundcards found...

[dylan@kodiarch ~]$

But root could

[dylan@kodiarch ~]$ sudo aplay -l

**** List of PLAYBACK Hardware Devices ****

card 0: PCH [HDA Intel PCH], device 0: ALC283 Analog [ALC283 Analog]

Subdevices: 0/1

Subdevice #0: subdevice #0

card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [HDMI 1]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 0: PCH [HDA Intel PCH], device 8: HDMI 2 [HDMI 2]

Subdevices: 1/1

Subdevice #0: subdevice #0

[dylan@kodiarch ~]$

Added user to 'audio' group

sudo usermod -a -G audio kodiuser

Then kodiuser could

[kodiuser@kodiarch dylan]$ aplay -l

**** List of PLAYBACK Hardware Devices ****

card 0: PCH [HDA Intel PCH], device 0: ALC283 Analog [ALC283 Analog]

Subdevices: 0/1

Subdevice #0: subdevice #0

card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [HDMI 1]

Subdevices: 1/1

Subdevice #0: subdevice #0

card 0: PCH [HDA Intel PCH], device 8: HDMI 2 [HDMI 2]

Subdevices: 1/1

Subdevice #0: subdevice #0

[kodiuser@kodiarch dylan]$

However in Kodi, i still could not view the devices.

How

Translating IR scancodes to keyboard keycodes with the linux kernel

When i first tried to get the IR input working on my NUC, i couldn't receive any codes. Below includes things I learned in the troubleshooting of that problem. It turned out that the problem appeared to be hardware (bad solder connection on the nuc) and not software.

Note that you do NOT need lirc for any of this. If you have it installed, uninstall it to keep it from conflicting with the other IR drivers and such. This is also an excellent place to start with troubleshooting for IR devices with Linux in general

Many thanks to the posting ir-keytable or: How I Learned to Stop Worrying about the LIRC Kernel for some of this information, and search engines for a lot of it too!

1. Identify CIR device. Mine was an ITE8713, as seen below. Also, you can see the driver that is being used (ite_cir).

[root@kodiarch kodiuser]# dmesg | grep CIR

[ 1.504776] ite_cir: Auto-detected model: ITE8713 CIR transceiver

[ 1.504777] ite_cir: Using model: ITE8713 CIR transceiver

[ 1.537620] input: ITE8713 CIR transceiver as /devices/virtual/rc/rc0/input3

[ 1.537646] rc rc0: ITE8713 CIR transceiver as /devices/virtual/rc/rc0

2. verify driver is loaded - although we see it in dmesg, might as well make sure it is still currently loaded... lsmod shows it is..

[root@kodiarch kodiuser]# lsmod | grep ite_cir

ite_cir 24576 0

rc_core 24576 7 ir_rc6_decoder,ir_nec_decoder,rc_rc6_mce,ir_lirc_codec,ite_cir,lirc_dev

[root@kodiarch kodiuser]#

3. Make sure ir-keytables finds device and properly identifies driver. be sure to run as root/with sudo to get full info. You can see below that ir-keytables finds the device, indicates it is associated with an input/event(3), shows the driver name, existing remote control keytable (rc-rc6-mce), and the supported and enabled protocols. ir-keytables is part of the v4l project, and for my distro was included in the v4l-utils package. You will want it installed, as it is the primary tool we will be using to modify the scancode<->keycode tables.

[root@kodiarch kodiuser]# ir-keytable

Found /sys/class/rc/rc0/ (/dev/input/event3) with:

Driver ite-cir, table rc-rc6-mce

Supported protocols: unknown other lirc rc-5 jvc sony nec sanyo mce-kbd rc-6 sharp xmp

Enabled protocols: lirc nec

Name: ITE8713 CIR transceiver

bus: 25, vendor/product: 1283:0000, version: 0x0000

Repeat delay = 500 ms, repeat period = 125 ms

[root@kodiarch kodiuser]#

Note that you can also see the input device information in /proc/bus/input/devices. Here is what mine looked like.

I: Bus=0019 Vendor=1283 Product=0000 Version=0000

N: Name="ITE8713 CIR transceiver"

P: Phys=

S: Sysfs=/devices/virtual/rc/rc0/input3

U: Uniq=

H: Handlers=kbd event3

B: PROP=0

B: EV=100013

B: KEY=fff 0 200000fc32e 237605000000000 0 700158000 1ba00004801 9e968000000000 10000002

B: MSC=10

4. Tell the kernel to not filter based on protocol using ir-keytables. By default, in my case (i haven't found where), the kernel filters out most protocols. We will use ir-keytable to enable all supported protocols. In my case, it for some reason didn't like mce-kbd protocol, so i had to skip it (found that was the problem via trial and error). Note- If the protocol of your remote isn't enabled, you will NOT see any output in the next step (with cat /dev/input/eventX or ir-keytable -t)

[root@kodiarch kodiuser]# ir-keytable 2>&1 | grep Enabled

Enabled protocols: lirc nec

[root@kodiarch kodiuser]# ir-keytable 2>&1 | grep Supported

Supported protocols: unknown other lirc rc-5 jvc sony nec sanyo mce-kbd rc-6 sharp xmp

[root@kodiarch kodiuser]# ir-keytable -p lirc,rc-5,jvc,sony,nec,sanyo,rc-6,sharp,xmp

Protocols changed to lirc rc-5 jvc sony nec sanyo rc-6 sharp xmp

[root@kodiarch kodiuser]# ir-keytable 2>&1 | grep Enabled

Enabled protocols: lirc rc-5 jvc sony nec sanyo rc-6 sharp xmp

[root@kodiarch kodiuser]#

5. Since now the kernel isn't filtering based on protocol, you should be able to check for input from the remote. You can see the scancodes using ir-keytable -t, or verify there is data coming into the raw device as follows. Note the raw device is the one you identified using ir-keytable or from /proc/bus/input/devices earlier. IF YOU DO NOT HAVE THE RIGHT PROTOCOL SELECTED, YOU WILL NOT SEE ANY OUTPUT WITH EITHER COMMAND! This is why we set to all supported protocols in the previous step.

[root@kodiarch kodiuser]# ir-keytable -t

Testing events. Please, press CTRL-C to abort.

1483600824.829553: event type EV_MSC(0x04): scancode = 0x847479

1483600824.829553: event type EV_SYN(0x00).

^C

[root@kodiarch kodiuser]#

[root@kodiarch kodiuser]# cat /dev/input/event3

.�mX@

yt�.�mX@

^C�0�mX� 0�mX�

[root@kodiarch kodiuser]#

6. Save a copy of the default keytable. You'll use this as a basis for your new table.

[root@kodiarch dylan]# ir-keytable -r >/etc/ir-keytable/my_keymap.txt

Enabled protocols: lirc nec

[root@kodiarch dylan]#

7. Modify the new key table and test. This involves running ir-keytable -t and looking at the IR scancodes, then associating them with linux keycodes keytable file. Testing involves clearing the old keytable, loading the new keytable from file, pressing keys, and watching the output of ir-keytable -t while pressing assigned buttons. Linux keycodes / 'input event codes' can be found for mainline kernel here. Note that these are in decimal, while ir-keytables mapping printout notes the hex. The variable name is the important part, as ir-keytable doesn't pay attention to the hex in the parenthesis.

pusing a key on the remote

[root@kodiarch dylan]# ir-keytable -t

Testing events. Please, press CTRL-C to abort.

1483601876.516574: event type EV_MSC(0x04): scancode = 0x847479

1483601876.516574: event type EV_SYN(0x00).

^C

[root@kodiarch dylan]#

KEY_PRINT IR scancode before modification

[root@kodiarch dylan]# grep KEY_PRINT /etc/ir-keytable/my_keymap.txt

scancode 0x800f044e = KEY_PRINT (0xd2)

[root@kodiarch dylan]#

KEY_PRINT IR scancode after modification

[root@kodiarch dylan]# grep KEY_PRINT /etc/ir-keytable/my_keymap.txt

scancode 0x847479 = KEY_PRINT (0xd2)

[root@kodiarch dylan]#

reloading keytable

[root@kodiarch dylan]# ir-keytable -c -w /etc/ir-keytable/my_keymap.txt

Old keytable cleared

Wrote 64 keycode(s) to driver

[root@kodiarch dylan]#

ouput of ir-keytable -t now that IR scancode for button is assigned to KEY_PRINT linux keycode

[root@kodiarch dylan]# ir-keytable -t

Testing events. Please, press CTRL-C to abort.

1483602241.378881: event type EV_MSC(0x04): scancode = 0x847479

1483602241.378881: event type EV_KEY(0x01) key_down: KEY_PRINT(0x00d2)

1483602241.378881: event type EV_SYN(0x00).

1483602241.389519: event type EV_MSC(0x04): scancode = 0x847479

1483602241.389519: event type EV_SYN(0x00).

1483602241.485376: event type EV_MSC(0x04): scancode = 0x847479

1483602241.485376: event type EV_SYN(0x00).

1483602241.496453: event type EV_MSC(0x04): scancode = 0x847479

1483602241.496453: event type EV_SYN(0x00).

1483602241.697131: event type EV_MSC(0x04): scancode = 0x847479

1483602241.697131: event type EV_SYN(0x00).

1483602241.951043: event type EV_KEY(0x01) key_up: KEY_PRINT(0x00d2)

1483602241.951043: event type EV_SYN(0x00).

^C

[root@kodiarch dylan]#

7. Create a script to load correct protocols and keytable (to be used in next step). I stored in /etc since I plan on using at startup time. Here is what mine looks like. Be sure the keytable file is the one you created before.

[root@kodiarch dylan]# cat /etc/ir-keytable/fix_ir-keytable

#!/bin/bash

ir-keytable -p nec &&

ir-keytable -c --write=/etc/ir-keytable/keymap.txt

[root@kodiarch dylan]#

Test the above script

[root@kodiarch ir-keytable]# ./fix_ir-keytable

Protocols changed to nec

Old keytable cleared

Wrote 64 keycode(s) to driver

[root@kodiarch ir-keytable]#

8. In my case, the keytable loaded by default by the driver is hard-coded in the driver itself. That means that to make it load something different based on the drive, you'd possibly have to rebuild the driver with each new kernel after applying patches, and build a keytable in the same binary way as the kernel. Instead, we're going to run the script created in the previous step on boot, by creating a systemd unit file to call it. This only works if your linux distro uses systemd for startup.

Here is what my unit file looks like, how i have it named, and where it lives... be sure that permissoins mirror other unit files in the same directory:

[root@kodiarch ~]$ cat /usr/lib/systemd/system/ir-keytable-fix.service

[Unit]

Description=/etc/ir-keytable/fix_ir-keytable fixes for remote

After=network.target

[Service]

Type=oneshot

ExecStart=-/etc/ir-keytable/fix_ir-keytable

TimeoutSec=5

[Install]

WantedBy=multi-user.target

[root@kodiarch ~]$

As a side note, here is where the default keymap is noted in the driver

/usr/src/linux/drivers/media/rc $ grep -n RC_MAP_RC6_MCE ite-cir.c

1592: rdev->map_name = RC_MAP_RC6_MCE;

and this is the uevent file that dictates for udev which driver to use / keymap to load when loading

[dylan@kodiarch ~]$ cat /sys/class/rc/rc0/uevent

NAME=rc-rc6-mce

DRV_NAME=ite-cir

[dylan@kodiarch ~]$

9. Test systemd unit file

[root@kodiarch ir-keytable]# systemctl status ir-keytable-fix.service

● ir-keytable-fix.service - /etc/ir-keytable/fix_ir-keytable fixes for remote

Loaded: loaded (/etc/systemd/system/ir-keytable-fix.service; enabled; vendor preset: disabled)

Active: inactive (dead) since Thu 2017-01-05 00:00:27 PST; 9s ago

Process: 3420 ExecStart=/etc/ir-keytable/fix_ir-keytable (code=exited, status=0/SUCCESS)

Main PID: 3420 (code=exited, status=0/SUCCESS)

Jan 05 00:00:27 kodiarch systemd[1]: Starting /etc/ir-keytable/fix_ir-keytable fixes for remote...

Jan 05 00:00:27 kodiarch fix_ir-keytable[3420]: Protocols changed to nec

Jan 05 00:00:27 kodiarch fix_ir-keytable[3420]: Old keytable cleared

Jan 05 00:00:27 kodiarch fix_ir-keytable[3420]: Wrote 64 keycode(s) to driver

Jan 05 00:00:27 kodiarch systemd[1]: Started /etc/ir-keytable/fix_ir-keytable fixes for remote.

[root@kodiarch ir-keytable]#

10. Enable on startup

[root@kodiarch ir-keytable]# sudo systemctl enable ir-keytable-fix.service

Created symlink /etc/systemd/system/multi-user.target.wants/ir-keytable-fix.service → /etc/systemd/system/ir-keytable-fix.service.

[root@kodiarch ir-keytable]#

Translating linux keycodes to kodi actions

In the above section, you've created a keymap for IR scancodes to linux keycodes.

So now we have to turn the above key strokes into actions in Kodi. This involves

- Linux Keycodes

- Kodi Keycodes

-Kodi Actions

- Kodi input (remote) config files

Linux and Kodi Keycodes are not 1:1. You can see a mapping between the two in the kodi source code

https://github.com/xbmc/xbmc/blob/master/xbmc/input/linux/LinuxInputDevices.cpp

For example the Linux KEY_STOP gets translated to the XBMCK_MEDIA_STOP

{ KEY_STOP , XBMCK_MEDIA_STOP },

Which in turn gets turned into

{ XBMCK_MEDIA_STOP, 0, 0, XBMCVK_MEDIA_STOP, "stop" }

in xbmc/input/XBMC_keytable.cpp

However for some reason i can't get this to pick up in the config file

We have to put the right keycode name in the remote control config file, in the correct place.

flix2kodi

Info as of 5 Jan 2016--

The official kodi wiki page points to a thread. The github source used by the repository noted at the head of that thread is no longer maintained, with the code being broken. There is a fork on github that has fixes as of now, but it appears to be a bit buggy in account handling. Also, it seems you can only install from a zip file of the source on github, so it has no repository / will not auto-update. I haven't gotten this fully working yet, due to using kodi in standalone mode, and associated window management issues and audio issues. I did find a problem with the way the plugin launches Chrome, which i will mention shortly.

installing broken initial plugin can be done as per instructions at head of the thread noted in the wiki.

installing fixed plugin (as of 4 jan 2016 is done by grabbing a zipfile of the source. (select 'clone or download' in top right corne, then sub-select'download zip' ). Place resulting zipfile in kodi user's home dir. Then in the kodi interface, go to programs -> install -> get more -> install from zip file

modifications needed for fixed plugin

flix2kodi did not properly launch chrome browser for me. This is because the launch script calls chrome by one name, but my distro/installation method named the binary file a different name.

My binary is /usr/bin/google-chrome-stable, however the script looks for just /usr/bin/google-chrome. The script is here:

/home/kodiuser/.kodi/addons/plugin.video.flix2kodi-master/resources/scripts/launcher/linux/chrome.sh

I simply modified the instances of 'google-chrome' in the script to say 'google-chrome-stable'.