Shallow Thoughts : : laptop

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sat, 12 Nov 2022

Limiting Battery Charge on a Lenovo Carbon X1

Ever since I got my Lenovo Carbon X1, I've wished there was some way to limit the battery charge. I keep it plugged in to a USB hub and external monitor most of the time, which means that the battery is at 100% for weeks on end. That isn't particularly good for lithium ion batteries: it's better for battery life to stop charging at around 80%.

Lots of laptops, including Dells and Apples, have a charge limit feature in their BIOS, but I searched through the CX1's BIOS several times and never found anything, so I'd resigned myself.. But just this week I accidentally stumbled on a way to set this at runtime!

Read more ...

Tags: , ,
[ 16:17 Nov 12, 2022    More linux/laptop | permalink to this entry | ]

Sun, 20 Mar 2022

Activate the Microphone on a Lenovo Carbon X1 Running Debian

When I bought my Carbon X1 laptop a few years ago, the sound card was new and not yet well supported by Linux. (I knew that before I bought, and decided it was a good gamble that support would improve soon.)

Early on, there was a long thread on Lenovo's forum discussing, in particular, how to get the microphone working. The key, apparently, was the SOF (Sound Open Firmware) support, which was standard in the 5.3 Linux kernel that came with Ubuntu 10.10, but needed an elaborate script to get working in earlier kernels.

It worked fine on Ubuntu. But under Debian, the built-in mic didn't work.

Read more ...

Tags: ,
[ 11:15 Mar 20, 2022    More linux/laptop | permalink to this entry | ]

Sun, 17 Sep 2017

Screen Brightness on an Asus 1015e (and other Intel-based laptops)

When I upgraded my Asus laptop to Stretch, one of the things that stopped working was the screen brightness keys (Fn-F5 and Fn-F6). In Debian Jessie they had always just automagically worked without my needing to do anything, so I'd never actually learned how to set brightness on this laptop. The fix, like so many things, is easy once you know where to look.

It turned out the relevant files are in /sys/class/backlight/intel_backlight. cat /sys/class/backlight/intel_backlight/brightness tells you the current brightness; write a number to /sys/class/backlight/intel_backlight/brightness to change it.

That at least got me going (ow my eyes, full brightness is migraine-inducing in low light) but of course I wanted it back on the handy function keys.

I wrote a script named "dimmer", with a symlink to "brighter", that goes like this:

#!/bin/zsh

curbright=$(cat /sys/class/backlight/intel_backlight/brightness)
echo dollar zero $0
if [[ $(basename $0) == 'brighter' ]]; then
  newbright=$((curbright + 200))
else
  newbright=$((curbright - 200))
fi
echo from $curbright to $newbright

sudo sh -c "echo $newbright > /sys/class/backlight/intel_backlight/brightness"

That let me type "dimmer" or "brighter" to the shell to change the brightness, with no need to remember that /sys/class/whatsit path. I got the names of the two function keys by running xev and typing Fn and F5, then Fn and F6. Then I edited my Openbox ~/.config/openbox/rc.xml, and added:

<keybind key="XF86MonBrightnessDown">
  <action name="Execute">
    <execute>dimmer<execute>
  </action>
</keybind>
<keybind key="XF86MonBrightnessUp">
  <action name="Execute">
    <execute>brighter<execute>
  </action>
</keybind>

Tags: ,
[ 19:57 Sep 17, 2017    More linux/laptop | permalink to this entry | ]

Fri, 30 Oct 2015

HDMI presentation setup on Linux, Part II: problems and tips

In Part I of HDMI Presentation Setup on Linux, I covered the basics of getting video and audio working over HDMI. Now I want to cover some finer-grained details: some problems I had, and ways to make it easier to enable HDMI when you need it.

Testing follies, delays, and screen blinking/flashing woes

While I was initially trying to get this working, I was using my own short sound clip (one of the alerts I use for IRC) and it wasn't working. Then I tried the test I showed in part I, $ aplay -D plughw:0,3 /usr/share/sounds/alsa/Front_Center.wav and that worked fine. Tried my sound clip again -- nothing. I noticed that my clip was mono and 8-bit while the ALSA sample was stereo and 16-bit, and I wasted a lot of time in web searches on why HDMI would play one and not the other.

Eventually I figured out that the reason my short clip wasn't playing was that there's a delay when switching on HDMI sound, and the first second two two of any audio may be skipped. I found lots of complaints about people missing the first few seconds of sound over HDMI, so this problem is quite common, and I haven't found a solution.

So if you're giving a talk where you need to play short clips -- for instance, a talk on bird calls -- be aware of this. I'm probably going to make a clip of a few seconds of silence, so I can play silence before every short clip to make sure I'm fully switched over to HDMI before the clip starts: aplay -D plughw:0,3 silence.wav osprey.wav

Another problem, probably related, when first starting an audio file: the screen blinks brieftly off then on again, then blinks again a little while after the clip ends. ("Flicker" turns out to be a better term to use when web searching, though I just see a single blink, not continued flickering). It's possible this is something about my home TV, and I will have to try it with another monitor somewhere to see if it's universal. It sounds like kernel bug 51421: Enabling HDMI sound makes HDMI video flicker, but that bug was marked resolved in 2012 and I'm seeing this in 2015 on Debian Jessie.

Making HDMI the sound default

What a pain, to have to remember to add -D plughw:0,3 every time you play a sound. And what do you do for other programs that don't have that argument?

Fortunately, you can make HDMI your default sound output. Create a file in your home directory called .asoundrc with this in it (you may be able to edit this down -- I didn't try) and then all audio will go to HDMI:

pcm.dmixer {
  type dmix
  ipc_key 1024
  ipc_key_add_uid false
  ipc_perm 0660
  slave {
    pcm "hw:0,3"
    rate 48000
    channels 2
    period_time 0
    period_size 1024
    buffer_time 0
    buffer_size 4096
  }
}
 
pcm. !default {
  type plug
  slave.pcm "dmixer"
}

Great! But what about after you disconnect? Audio will still be going to HDMI ... in other words, nowhere. So rename that file:

$ mv .asoundrc asoundrc-hdmi
Then when you connect to HDMI, you can copy it back:
$ cp asoundrc-hdmi .asoundrc 

What a pain, you say again! This should happen automatically!

That's possible, but tricky: you have to set up udev rules and scripts. See this Arch Linux discussion on HDMI audio output switching automatically for the gory details. I haven't bothered, since this is something I'll do only rarely, when I want to give one of those multimedia presentations I sometimes contemplate but never actually give. So for me, it's not worth fighting with udev when, by the time I actually need HDMI audio, the udev syntax probably will have changed again.

Aliases to make switching easy

But when I finally do break down and design a multimedia presentation, I'm not going to be wanting to do all this fiddling in the presentation room right before the talk. I want to set up aliases to make it easy.

There are two things that need to be done in that case: make HDMI output the default, and make sure it's unmuted.

Muting can be done automatically with amixer. First run amixer with no arguments to find out the channel name (it gives a lot of output, but look through the "Simple mixer control" lines, or speed that up with amixer | grep control.

Once you know the channel name (IEC958 on my laptop), you can run: amixer sset IEC958 unmute The rest of the alias is just shell hackery to create a file called .asoundrc with the right stuff in it, and saving .asoundrc before overwriting it. My alias in .zshrc is set up so that I can say hdmisound on or hdmisound off (with no arguments, it assumes on), and it looks like this:

# Send all audio output to HDMI.
# Usage: hdmisound [on|off], default is on.
hdmisound() {
    if [[ $1 == 'off' ]]; then
        if [[ -f ~/.asoundrc ]]; then
            mv ~/.asoundrc ~/.asoundrc.hdmi
        fi
        amixer sset IEC958 mmute
    else
        if [[ -f ~/.asoundrc ]]; then
            mv ~/.asoundrc ~/.asoundrc.nohdmi
        fi
        cat >> ~/.asoundrc <<EOF
pcm.dmixer {
  type dmix
  ipc_key 1024
  ipc_key_add_uid false
  ipc_perm 0660
  slave {
    pcm "hw:0,3"
    rate 48000
    channels 2
    period_time 0
    period_size 1024
    buffer_time 0
    buffer_size 4096
  }
}
 
pcm. !default {
  type plug
  slave.pcm "dmixer"
}
EOF
        amixer sset IEC958 unmute
    fi
}

Of course, I could put all that .asoundrc content into a file and just copy/rename it each time. But then I have another file I need to make sure is in place on every laptop; I decided I'd rather make the alias self-contained in my .zshrc.

Tags: , ,
[ 11:57 Oct 30, 2015    More linux/laptop | permalink to this entry | ]

Tue, 27 Oct 2015

HDMI presentation setup on Linux, video and audio: Part I

For about a decade now I've been happily connecting to projectors to give talks. xrandr --output VGA1 --mode 1024x768 switches on the laptop's external VGA port, and xrandr --auto turns it off again after I'm disconnected. No fuss.

But increasingly, local venues are eschewing video projectors and instead using big-screen TVs, some of which offer only an HDMI port, no VGA. I thought I'd better figure out how to present a talk over HDMI now, so I'll be ready when I need to know.

Fortunately, my newest laptop does have an HDMI port. But in case it ever goes on the fritz and I have to use an older laptop, I discovered you can buy VGA to HDMI adaptors rather cheaply (about $10) on ebay. I bought one of those, tested it on my TV at home and it at least worked there. Be careful when shopping: you want to make sure you're getting something that takes VGA in and outputs HDMI, rather than the reverse. Ebay descriptions aren't always 100% clear on that, but if you check the gender of the connector in the photo and make sure it's right to plug into the socket on your laptop, you should be all right.

Once you're plugged in (whether via an adaptor, or native HDMI built into your laptop), connecting is easy, just like connecting with VGA:

xrandr --output HDMI1 --mode 1024x768

Of course, you can modify the resolution as you see fit. I plan to continue to design my presentations for a 1024x768 resolution for the forseeable future. Since my laptop is 1366x1024, I can use the remaining 342-pixel-wide swath for my speaker notes and leave them invisible to the audience.

But for GIMP presentations, I'll probably want to use the full width of my laptop screen. --mode 1366x768 didn't work -- that resolution wasn't available -- but running xrandr with no arguments got me a list of available resolutions, which included 1360x768. That worked fine and is what I'll use for GIMP talks and other live demos where I want more screen space.

Sound over HDMI

My Toastmasters club had a tech session where a few of us tried out the new monitor in our meeting room to make sure we could use it. One person was playing a video with sound. I've never used sound in a talk, but I've always wanted to find an excuse to try it. Alas, it didn't "just work" -- xrandr's video settings have nothing to do with ALSA's audio settings. So I had to wait until I got home so I could do web searches and piece together the answer.

First, run aplay -l , which should show something like this:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: STAC92xx Analog [STAC92xx Analog]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Find the device number for the HDMI device, which I've highlighted here: in this case, it's 3 (which seems to be common on Intel chipsets).

Now you can run a test:

$ aplay -D plughw:0,3 /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
If you don't hear anything, don't worry: the HDMI channel is probably muted if you've never used it before. Run either alsamixer or alsamixergui.

[alsamixergui with HDMI muted] [alsamixer] Now find the channel representing your HDMI connection. (HDMI must be plugged in for this to work.) In alsamixer, it's called S/PDIF; in alsamixergui, it's called IEC958. If you look up either of those terms, Wikipedia S/PDIF will tell you that S/PDIF is the Sony/Philips Digital Interconnect Format, a data protocol and a set of physical specifications. Those physical specifications appear to have nothing to do with video, and use connectors that are nothing like HDMI. So it doesn't make much sense. Just remember that if you see IEC958 or S/PDIF in ALSA, that's probably your HDMI channel.

In the alsamixergui screenshot, IEC958 is muted: you can tell because the little speaker icon at the top of the column is bright white. If it were unmuted, the speaker icon would be grey like most of the others. Yes, this seems backward. It's Linux audio: get used to obscure user interfaces.

In the alsamixer screenshot, the mutes are at the bottom of each column, and MM indicates a channel is muted (like the Beep channel in the screenshot). S/PDIF is not muted here, though it appears to be at zero volume. (The 00 doesn't tell you it's at zero volume; 00 means it's not muted. What did I say about Linux audio?) ALSA apparently doesn't let you adjust the volume of HDMI output: presumably they expect that your HDMI monitor will have its own volume control. If your S/PDIF is muted, you can use your right-arrow key to arrow over to the S/PDIF channel, then type m to toggle muting. You can exit alsamixer with Ctrl-C (Q and Ctrl-Q don't work).

Now try that aplay -D command again and see if it works. With any luck, it will (loudly).

A couple of other tests you might want to try:
speaker-test -t sine -f 440 -c 2 -s 1 -D hw:0,3
plays a sine wave. speaker-test -c 2 -r 48000 -D hw:0,3
runs a general speaker test sequence.

In Part II of Linux HDMI Presentations, I'll cover some problems I had, and how to write an alias to make it easy to turn HDMI audio on and off.

Tags: , ,
[ 14:36 Oct 27, 2015    More linux/laptop | permalink to this entry | ]

Mon, 04 Mar 2013

How to enable/disable laptop wireless hardware

My Lenovo laptop has a nifty button, Fn-F5, to toggle wi-fi and bluetooth on and off. Works fine, and the indicator lights (of which the Lenovo has many -- it's quite nice that way) obligingly go off or on.

But when I suspend and resume, the settings aren't remembered. The machine always comes up with wireless active, even if it wasn't before suspending.

Since wireless can be a drain on battery life, as well as a potential security issue, I don't want it on when I'm not actually using it. So I wanted a way to turn it off programmatically.

The answer, it turns out, is rfkill.

$ rfkill list
0: tpacpi_bluetooth_sw: Bluetooth
        Soft blocked: yes
        Hard blocked: no
0: phy0: Wireless LAN
        Soft blocked: yes
        Hard blocked: no
tells you what hardware is currently enabled or disabled.

To toggle something off,

$ rfkill block bluetooth
$ rfkill block wifi

Type rfkill -h for more details on arguments you can use.

Fn-F5 still works to enable or disable them together. I think this is being controlled by /etc/acpi/ibm-wireless.sh, though I can't find where it's tied to Fn-F5.

You can make it automatic by creating /etc/pm/sleep.d/. (That's on Ubuntu; of course, the exact file location may vary with distro and version.) To disable wireless on resume, do this:

#! /bin/sh

case "$1" in
  resume)
    rfkill block bluetooth
    rfkill block wifi
    ;;
esac
exit $?

Of course, you can also tie that into other things, like your current network scheme, or what wireless networks are visible (which you can get with iwlist wlan0 scan).

Tags: , , ,
[ 19:46 Mar 04, 2013    More linux/laptop | permalink to this entry | ]

Mon, 31 Oct 2011

Synaptics horizontal scrolling (and other touchpad configurations)

My new netbook (about which, more later) has a trackpad with areas set aside for both vertical and horizontal scrolling. Vertical scrolling worked out of the box on Squeeze without needing any extra fiddling. My old Vaio had that too, and I loved it.

Horizontal scrolling took some extra research. I was able to turn it on with a command:

synclient HorizEdgeScroll=1
(thank you, AbsolutelyTech). Then it worked fine, for the duration of that session.

But it took a lot more searching to find out the right place to set it permanently. Nearly every page you find on trackpad settings tells you to edit /etc/X11/xorg.conf. Distros haven't normally used xorg.conf in over three years! Sure, you can generate one, then edit it -- but surely there's a better way.

And there is. At least in Debian Squeeze and Ubuntu Natty, you can edit /usr/share/X11/xorg.conf.d/50-synaptics.conf and add this options line inside the "InputClass" section:

        options "HorizEdgeScroll" "1"
Don't forget the quotes, or X won't even start.

In theory, you can use this for any of the Synaptics driver options -- tap rate and sensitivity, even multitouch. Your mileage may vary -- horizontal scroll is the only one I've tested so far. But at least it's easier than generating and maintaining an xorg.conf file!

Tags: , ,
[ 16:20 Oct 31, 2011    More linux/laptop | permalink to this entry | ]

Sat, 27 Aug 2011

Vaio tips for Debian Squeeze

I switched to the current Debian release, "Squeeze", quite a few months ago on my Sony Vaio laptop. I've found that Squeeze, with its older kernel and good attention to power management (compared to the power management regressions in more recent kernels), gets much better battery life than either Arch Linux or Ubuntu on this machine. I'm using Squeeze as the primary OS at least until the other distros get their kernel power management sorted out.

I did have to solve a couple of minor problems when switching over, though.

Suspend/Resume quirks

The first problem was that my Vaio TX650 would freeze on resuming from suspend -- something that every other Linux distro has handled out of the box on this machine.

The solution turned out to be simple though non-obvious, apparently a problem with controlling power to the display:

sudo pm-suspend --quirk-dpms-on

That wasn't easy to find, but ever since then the machine has been suspending without a single glitch. And it's a true suspend, unlike Ubuntu Natty, which on this machine will use up a full battery if I leave it suspended all day -- Natty uses nearly as much power when suspended as it does running.

Adjusting screen brightness: debugging ACPI

Of course, once I got that sorted out, there were the usual collection of little changes I needed to make. Number one was that it didn't automatically handle brightness adjustment with the Fn-F5 and Fn-F6 keys.

It turned out my previous technique for handling the brightness keys didn't work, because the names of the ACPI events in /etc/acpi/events had changed. Previously, /etc/acpi/events/sony-brightness-down had contained references to the Sony I/O Control, or SPIC:

event=sony/hotkey SPIC 00000001 00000010
action=/etc/acpi/sonybright.sh down
That device didn't exist on Squeeze. To find out what I needed now, I ran acpi-listen and typed the function-key combos in question. That gave me the codes I needed. I changed the sony-brightness-down file to read:
event=video/brightnessdown BRTDN 00000087 00000000
action=/etc/acpi/sonybright.sh down

It's probably a good thing, changing to be less Sony-specific ... but as a user it's one of those niggling annoyances that I have to go chase down every time I upgrade to a new Linux version.

Tags: , , , , ,
[ 12:07 Aug 27, 2011    More linux/laptop | permalink to this entry | ]