Thursday, 27 February 2020

Create a new file in Nautilus with a shortcut

It is not very convenient to do a mouse click to create a document. We can create a shortcut  like for the terminal using scripts-accels.

We would create a script ~/.local/share/nautilus/scripts/newFile with the commands to create a new file. Don't forget to make the file executable.
To run this script through a shortcut we need to modify the file ~/.config/nautilus/scripts-accels.
I added the line  N newFile
and my files looks like this
F12 Terminal
N newFile
; Commented lines must have a space after the semicolon
; Examples of other key combinations:
; F12 Terminal
; F12 Terminal
; F12 Terminal

Now we have to put the commands for the file creation into ~/.local/share/nautilus/scripts/newFile. The simplest option is touch untitiled_document, however we  still would need to click on the file,  then press F2 to rename it and I find it  is quite cumbersome to do every time. I tried to select a file through DBus messages but unfortunately Nautilus does not have a DBus interface for file selection. The possible solution is to use Zenity (a tool for creating Gnome dialogs, credit forum.xfce.org). I used the  following script

#!/bin/sh

file=$(zenity --title 'Select Filename & Destination' \
--width=300 --height=200 --file-selection \
--save --confirm-overwrite)
if [ "$?" = "0" ]; then
   touch "$file"
fi


Wednesday, 19 February 2020

Battery conservation mode on Lenovo Yoga S940

Lenovo Yoga S940 has battery conservation mode which limits charging at 60%. It is also possible to use it in Linux. I found following thread with the commands to change the threshold and wrote a script which makes control of the battery threshold in Linux more convenient

Friday, 14 February 2020

Sound [subwoofer and microphone] on Lenovo Yoga S940 in Linux

I did not get microphone and subwoofer working out of the box in Ubuntu 19.10 on Lenovo Yoga S940 (ALC298). I played around with hdajackretask as was suggested on forums. Microphone was not even detected.

Eventually I came across the post about the laptop Lenovo Yoga C940 which I suppose is quite similar to S940. It suggested to use Sound Open Firmware (SOF). Even though the post suggested that one needs kernel 5.5 for me it worked with default 5.3.0-29-generic. SOF support should be enabled in the kernel. To check if current kernel supports SOF run

cat /boot/config-`uname -r` | grep SOF

and see if CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y

One also need to  download the sof  firmware and put  it into /lib/firmware/intel/sof/. In my case there  already was a file sof-cnl.ri.
I got the latest  version (1.4.2) from https://github.com/thesofproject/sof/releases/ (file sof-cnl-v1.4.2.ri, cnl stands for cannon lake) and copied it to /lib/firmware/intel/sof/sof-cnl.ri

I added two lines into /etc/modprobe.d/blacklist.conf:

blacklist snd_hda_intel
blacklist snd_soc_skl

after next reboot my laptop switched to SOF. Sound was working but still no subwoofer. Microphone was detectable now but was not working. Interestingly microphone registered input when headphone jack was plugged in and music was on.

I came across another post about SOF and lenovo hardware by DaveOber.
I took following configuration from his instruction:
First create a directory /usr/share/alsa/ucm/sof-skl_hda_card/.
Put following text into /usr/share/alsa/ucm/sof-skl_hda_card/HiFi:

# Use case Configuration for skl-hda-card

SectionVerb {

 EnableSequence [
  cdev "hw:sofsklhdacard"
  cset "name='Master Playback Switch' on"
  cset "name='Capture Switch' on"
  
 ]

 DisableSequence [
  cdev "hw:sofsklhdacard"
 ]

        Value {
        }
}


SectionDevice."HDMI1" {
        Comment "HDMI1/DP1 Output"

#        ConflictingDevice [
                # "Headset"
#        ]

        EnableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='hif5-0 Jack Switch' on"
                cset "name='Pin5-Port0 Mux' 1"
        ]

        DisableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='Pin5-Port0 Mux' 0"
                cset "name='hif5-0 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,3"
                PlaybackChannels "2"
                JackControl "HDMI/DP, pcm=11 Jack"
                # JackHWMute "Headset"
        }
}

SectionDevice."HDMI2" {
        Comment "HDMI2/DP2 Output"

#        ConflictingDevice [
                # "Headset"
#        ]

        EnableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='hif6-0 Jack Switch' on"
                cset "name='Pin6-Port0 Mux' 2"
        ]

        DisableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='Pin6-Port0 Mux' 0"
                cset "name='hif6-0 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,4"
                PlaybackChannels "2"
                JackControl "HDMI/DP, pcm=12 Jack"
                # JackHWMute "Headset"
        }
}

SectionDevice."HDMI3" {
        Comment "HDMI3/DP3 Output"

#        ConflictingDevice [
                # "Headset"
#        ]

        EnableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='hif7-0 Jack Switch' on"
                cset "name='Pin7-Port0 Mux' 3"
        ]

        DisableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='Pin7-Port0 Mux' 0"
                cset "name='hif7-0 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,5"
                PlaybackChannels "2"
                JackControl "HDMI/DP, pcm=13 Jack"
                # JackHWMute "Headset"
        }
}


SectionDevice."Headphone" {
 Comment "Headphone"

 #ConflictingDevice [
        #        "Speaker"
        #]
 
 EnableSequence [
  cdev "hw:sofsklhdacard"
  cset "name='Headphone Playback Volume' 80"
  #cset "name='Headphone Mic Boost Volume' 1"
  cset "name='Headphone Playback Switch' on"
 ]

 DisableSequence [
  cdev "hw:sofsklhdacard"
  cset "name='Headphone Playback Switch' off"
 ]

 Value {
  PlaybackPCM "hw:sofsklhdacard,0"
  PlaybackChannels "2"
  #JackHWMute "Speaker"
  JackName "sof-skl_hda_card Headphone"
  JackType "gpio"
  JackSwitch "12"
  JackControl "Headphone Jack"
 }
}

SectionDevice."Speaker" {
        Comment "Speaker"

        #ConflictingDevice [
        #        "Headphone"
        #]

        EnableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='Speaker Playback Switch' on"
                cset "name='Speaker Playback Volume' 80"
        ]

        DisableSequence [
                cset "name='Speaker Playback Switch' off"
        ]

        Value {
  PlaybackPCM "hw:sofsklhdacard,0"
  JackHWMute "Headphone"
                PlaybackChannels "2"
        }
}

SectionDevice."Bass Speaker" {
        Comment "Bass Speaker"

#       ConflictingDevice [
#                "Headphone"
#        ]

        EnableSequence [
                cdev "hw:sofsklhdacard"
                cset "name='Bass Speaker Playback Switch' on"
  cset "name='Speaker Playback Switch' on"
  cset "name='Speaker Playback Volume' 80"
        ]

        DisableSequence [
                cset "name='Speaker Playback Switch' off"
                cset "name='Bass Speaker Playback Switch' off"
        ]
        Value {
                PlaybackPCM "hw:sofsklhdacard,0"
                JackHWMute "Headphone"
                PlaybackChannels "2"
        }
}

SectionDevice."Headset" {
 Comment "Headset Mic"

        ConflictingDevice [
                "DMIC Stereo"
        ]

        EnableSequence [
                cdev "hw:sofsklhdacard"
#  cset "name='Headphone Mic Boost Volume' 1"
#  cset "name='Capture Switch' on"
        ]

        DisableSequence [
                cdev "hw:sofsklhdacard"
#  cset "name='Capture Switch' off"
        ]

        Value {
                CapturePCM "hw:0,0"
                CaptureChannels "2"
  JackControl "Mic Jack"
#  JackHWMute "DMIC Stereo"
        }
}

SectionDevice."Dmic" {
        Comment "DMIC Stereo"

        ConflictingDevice [
                "Headset Mic"
        ]

        EnableSequence [
                cdev "hw:sofsklhdacard"
#  cset "name='Capture Switch' on"
                cset "name='PGA10.0 10 Master Capture Volume' 75"
        ]

        DisableSequence [
                cdev "hw:sofsklhdacard"
#  cset "name='Capture Switch' off"
        ]

        Value {
                CapturePCM "hw:0,6"
                CaptureChannels "2"
#  JackHWMute "Headset Mic"
        }
}

Whenever I  was plugging and unplugging headphones my system would switch to the last device which in Dave's confing was HDMI, so I rearranged the entries and put HDMI entries higher, now I always have Bass Speaker as  a default one.

And then create a file /usr/share/alsa/ucm/sof-skl_hda_card/sof-skl_hda_card.conf
and put there

SectionUseCase."HiFi" {
 File "HiFi"
 Comment "Play HiFi quality Music"
}

Now you can run

pulseaudio --kill; sudo alsactl kill rescan; pulseaudio --start

and enjoy working microphone and subwoofer. You can compare the  sound when you choose Speaker or Bass Speaker as a sound device. The difference is  stunning.

I also added two lines to /etc/pulse/daemon.conf

 enable-lfe-remixing = yes
 lfe-crossover-freq = 250


It is hard to say it is  doing anything though.

The last issue is that whenever I plug and unplug  headphones volume in alsamixer goes to 35. Have not solved this issue yet.

I also noticed that there was some hissing from the speakers. I could solve it by changing microphone gain in alsamixer to zero. Interestingly microphone still works, but whenever I run the app which uses microphone hissing reappears. Hope it will be properly solved in the next versions of the driver.

Nautilus tweaks

Nautilus is quite limited out of the box and lacks some useful features:

1) To pin a folder to the left panel (bookmarks) just go to the folder and press Ctrl+D.


2) Nautilus path as tiles with folder names but it is not possible to edit the path or copy. If you press Ctrl+L Nautilus will switch to classical path representation, you can edit it, or copy with Ctrl+A; Ctrl+C;
copy/edit path

3) It is common to do something in the terminal in the current folder. In KDE Dolphin one can easily either open a new terminal window with F4 or open a terminal in the bottom of the Dolphin window with Shift+F4. Unfortunately there is no such feature in Nautilus. Fortunately it can be added.

4)Very often I want to create an empty document in the current folder but there is no such option. It can be easily fixed by creating a template for an empty document via
touch ~/Templates/"Untitled Document"
Now this option appears in the context menu at right click.
It can also be done with a keyboard shortcut.

Tuesday, 4 February 2020

Ubuntu Linux on Lenovo Yoga S940

I installed Ubuntu Linux (19.10) on my new laptop Lenovo Yoga S940 at first it seemed everything worked but then I realised there were some serious issues, see the summary below:
1) touchpad: did not work after reboot (fix)
2) sleep: laptop would randomly wake up from sleep (fix)
3) multimedia  keys: volume control buttons would get stuck and drive sound volume to 0% or 100%, other multimedia keys work properly. (fix)
4) built-in microphone: did not work (still does not work). But the external microphone works. Built in microphone requires Sound Open Firmware. (fix)
5) WiFi: works out of the box
6) graphics: works OOTB
7) HiDPI scaling: works out of the box
8) sound: 4 speakers work out of the box, but subwoofer does not work. I fixed it by switching to Sound Open Firmware.
9) Battery life is not very good, it is about 4 to 5 hours. Partially it is because of 4k display. However the  main battery consumer in my case is the web browser. Currently web browsers on Linux do not support GPU acceleration which leads to very high processor load.
10) Battery  conservation mode: works.

NB: Author of the blog is not responsible for  any damage experiments may cause. You perform manipulations on your own risk.

Ubuntu Linux on Lenovo Yoga S940: volume control key press repeats until volume goes to maximum or minimum

I encountered a strange  problem with functional keys for volume control on my Lenovo Yoga S940 under Ubuntu Linux 19.10. Whenever I would increase or  decrease the sound volume if I hold the key pressed long enough for the OS to register the  repeat  it would repeat the key press even after I have  released the button until the volume goes to 100% or 0% correspondingly to the key which was  pressed. Be careful with experimenting, 100% volume can damage your hearing! Author of the blog is not responsible for  any damage experiments may cause.

The issue was present in both modes of functional keys i.e. when the multimedia control is primary and F1-F12 are accessible through Fn key or opposite. One can change it in BIOS. I personally prefer when F1-F10 is set as primary and multimedia keys require Fn. Interestingly only volume control keys were affected, screen brightness control worked as expected.

Search on the internet lead me to this post on Stack Overflow. After reading the post I tried to press any other key while volume was going up and down and the additional keypress stopped the process which  reassured me that I had the same problem.

I followed  the advice posted  on Stack Overflow. Obviously I had another  model of the laptop and I had to edit the hardware  info.

The command "cat /sys/class/dmi/id/modalias" gave me the information about my hardware. I created a file /lib/udev/hwdb.d/99-keyboard-lenovo-vol-fix.hwdb
and inserted following lines:
"# Fix for volume keys on Lenovo Yoga S940
evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO:pn81Q7*:pvrLenovoYogaS940*
 KEYBOARD_KEY_a0=!mute
 KEYBOARD_KEY_ae=!volumedown
 KEYBOARD_KEY_b0=!volumeup"

 The next step was to run these two commands as root:
systemd-hwdb update
udevadm trigger --verbose --sysname-match="event*"


Now volume control buttons work as expected.

The model identifier  of the laptop with 8th gen CPU was pn81Q7, for 10th gen it seems to be pn81Q8. One can try to use pn*

Ubuntu Linux on Lenovo Yoga S940: touchpad stops working after reboot

I installed Ubuntu linux 19.10 on Lenovo Yoga S940 and it seemed that everything worked out of the box. However after a reboot touchpad stopped working. Further reboots did not fix the situation. However if I booted live version of Ubuntu linux from USB stick and did NOT do any changes on the hard drive and then rebooted and loaded Ubuntu linux installed on hard drive touchpad was working again. This was a very strange bug for me. I did not understand how booting from live cd can affect the OS on the hard drive when I did not write anything to it.

Interestingly touchpad in live version of Ubuntu linux worked only if I changed some settings in BIOS. Any, for example boot order or functional keys mode. For me it seems like a combination of bugs in BIOS and kernel module.

Second annoying problem was sleep mode. Laptop would randomly wakes up when the lid was closed. See the solution in my post.

Interestingly the solution of a sleep problem partially solves the issue with the touchpad. If we never reboot and touchpad would not stop working. However we want to be able to reboot, for example for the update of the kernel.

 I spent a lot of time trying to fix the touchpad but the issue persisted. dmesg showed message "i2c_designware some id: controller timed out". It was clear that the problem is with the driver of i2c bus.

 I found out similar problem. It suggested that somehow laptop gets to ACPI state S4 during reboot and i2c bus get's stuck and probably it has some memory. My hypothesis is that when we change BIOS settings the i2c bus get's reset and that's the reason why it works in the live version of ubuntu. I tried everything: adding kenel parameters like acpi=noacpi, acpi=force, acpi=noirq as was suggested on forums for this issue on other laptops. Nothing works and noirq also disabled the keyboard. 

I read everything about not working touchpads and found following article. Suggested solution for Lenovo Y700 was to blacklist the module pata_legacy. The issue with Y700 touchpad was completely different but I still decided to give it a try since the touchpad in my laptop was also from Elan. I edited the file 

/etc/modprobe.d/blacklist 

and added the line blacklist pata_legacy Surprisingly it solved the problem with touchpad. I have no idea how pata_legacy might interact with i2c modules but happy that it works now.  

Alternatively to editing /etc/modprobe.d/blacklist one can add modprobe.blacklist=pata_legacy to kernel parameters in grub config file.

Update: I noticed that when I reboot using the button in the unity top bar everything works fine, but if I do sudo  reboot in the terminal touchpad stops working again, but I can reset it using poweroff command from unity UI. Interestingly poweroff button in KDE does not switch the computer off. Perhaps they use slightly different commands which interacts with bugs in BIOS.