Skip to content

Commit

Permalink
labs/sysdev-accessing-hardware: various improvements
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  • Loading branch information
tpetazzoni committed Sep 22, 2022
1 parent 6d07555 commit dd1d4e3
Showing 1 changed file with 93 additions and 29 deletions.
122 changes: 93 additions & 29 deletions labs/sysdev-accessing-hardware/sysdev-accessing-hardware.tex
Original file line number Diff line number Diff line change
Expand Up @@ -263,22 +263,29 @@ \subsection{Enabling an I2C bus}
i2c-0 i2c STM32F7 I2C(0x40012000) I2C adapter
\end{bashinput}
Oops, I2C5 is not listed here. However, could it have a wrong name?
Since \code{i2cdetect} shows the base addresses for the control
registers for each bus, let's check the datasheet for the SoC
\footnote{\url{https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-arm-based-32-bit-mpus-stmicroelectronics.pdf}}.
Look for \code{I2C5} and you will find that the I2C5 base register
address is \code{0x40015000}. That's different from the addresses
of already enabled I2C buses.
\code{i2c-0} is the I2C controller with registers at
\code{0x40012000}, which is \code{I2C1} in the STM32MP1
nomenclature. \code{i2c-1} is the I2C controller with registers at
\code{0x5c002000}, which is \code{I2C4} in the STM32MP1
nomenclature. Refer to the STM32MP1 memory map in the datasheet for
details. Pay attention to the numbering difference: \code{i2c-0},
\code{i2c-1} is the Linux numbering, based on the registration order
of enabled I2C busses. Here, because only I2C1 and I2C4 are enabled,
they are called \code{i2c-0} and \code{i2c-1}.
Using the datasheet for the SoC
\footnote{\url{https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-arm-based-32-bit-mpus-stmicroelectronics.pdf}},
we can find what is the base address of the registers for the
\code{I2C5} controller: it is \code{0x40015000}.
\subsection{Customizing the Device Tree}
Fortunately, I2C5 is already defined in the one of the DTS includes
used by the Device Tree for our board. In our case, that's in
\kfile{arch/arm/boot/dts/stm32mp151.dtsi}. Look by yourself in this
file, and you will find its definition, but with
\code{status = "disabled";}. This means that the device is not enabled
yet, and it's up to boards using it to do so.
file, and you will find its definition, but with \code{status =
"disabled";}. This means that this I2C controller is not enabled yet,
and it's up to boards using it to do so.
We could modify the \kfile{arch/arm/boot/dts/stm32mp157a-dk1.dts} file
for our board, but that's not a very good idea as this file is
Expand Down Expand Up @@ -306,10 +313,10 @@ \subsection{Customizing the Device Tree}
to see what happens when a device doesn't have associated pin
definitions yet.
A device like an I2C controller node is typically declared in the
DTSI files for the SoC, without pin settings.
A device like an I2C controller node is typically declared in the DTSI
files for the SoC, without pin settings as these are board
specific. Pin definitions are then usually defined at board level.
Pin definitions are then usually defined at board level.
In our case, we don't see such definitions, but they are actually
found in the \kfile{arch/arm/boot/dts/stm32mp15xx-dkx.dtsi}
file, shared between multiple stm32mp15 DK boards, which is included
Expand Down Expand Up @@ -403,7 +410,7 @@ \subsection{Adding and enabling an I2C device}
\end{itemize}
If you didn't do any mistake, your new device should be detected at
address 0x52:
address \code{0x52}:
\begin{bashinput}
# i2cdetect -r 1
Expand All @@ -422,34 +429,87 @@ \subsection{Adding and enabling an I2C device}
We will later compile an out-of-tree kernel module to support this device.
\section{Using kernel modules}
\section{Plugging a USB audio headset}
In the next labs, we are going to play audio using a USB audio headset.
Let's see whether our kernel supports such hardware by plugging the
headset provided by your instructor.
In the serial console, you should see messages confirming that the
USB device was detected. However, there should be no \code{/proc/asound}
directory yet, which exists when sound cards are in use.
Before plugging the device, look at the output of \code{lsusb}:
Actually, what we need to support a generic USB audio headset is
a kernel configured with \kconfig{CONFIG_SND_USB_AUDIO}. Look for this
parameter in the kernel configuration, and you should find that
it is enabled as a module.
\begin{bashinput}
# lsusb
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 002: ID 0424:2514
\end{bashinput}
So, instead of compiling the corresponding driver as a built-in, that's
a good opportunity to practice with kernel modules.
Now, when you plug the USB headset, a number of messages should appear
on the console, and running \code{lsusb} again should show an
additional device:
\begin{bashinput}
# lsusb
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 005: ID 1b1c:0a06
Bus 001 Device 002: ID 0424:2514
\end{bashinput}
The device of vendor ID \code{1b1c} and product ID \code{0a06} has
appeared.
The device also appears in \code{/sys/bus/usb/devices/}, in a
directory whose name depends on the topology of the USB bus. When the
device is plugged in the kernel messages show:
\begin{bashinput}
usb 1-1.1: new full-speed USB device number 3 using ehci-platform
\end{bashinput}
\subsection{Installing and using in-tree kernel modules}
So if we go in \code{/sys/bus/usb/devices/1-1.1}, we get the {\em
sysfs} representation of this USB device:
\begin{bashinput}
# cd /sys/bus/usb/devices/1-1.1
# cat idVendor
1b1c
# cat idProduct
0a06
# cat busnum
1
# cat devnum
6
# cat product
Raptor HS40
\end{bashinput}
However, while the USB device is detected, we currently do not have
any driver for this device, so no actual sound card is detected.
\section{Enabling, installing and using in-tree kernel modules}
Go back to the kernel source directory.
The Linux kernel has a generic driver supporting all USB audio devices
supporting the standard USB audio class. This driver can be enabled
using the \kconfig{CONFIG_SND_USB_AUDIO} configuration option. Look
for this parameter in the kernel configuration, and you should find
that it is already enabled as a module.
So, instead of compiling the corresponding driver as a built-in, that's
a good opportunity to practice with kernel modules.
Following details given in the lectures, compile the modules for your
kernel if necessary (in case you just compiled the \code{zImage} and
DTB files), and then install them in our NFS root filesystem
(\code{$HOME/__SESSION_NAME__-labs/tinysystem/nfsroot}).
(\code{$HOME/__SESSION_NAME__-labs/tinysystem/nfsroot}). Make sure to
also reinstall the kernel image, and reboot the board. Indeed, due to
the changes we have made to the kernel source code, the kernel version
is now \code{5.15.<x>-dirty}, the {\em dirty} indicating that the Git
working tree has uncommitted changes. The modules are therefore
installed in \code{/lib/modules/5.15.<x>-dirty/}, and the version of
the running Linux kernel must match this.
Once this is done, try to load the module that we need:
After rebooting, try to load the module that we need:
\begin{bashinput}
modprobe snd-usb-audio
Expand All @@ -458,6 +518,10 @@ \subsection{Installing and using in-tree kernel modules}
By running \code{lsmod}, see all the module dependencies that
were loaded too.
You can also see that a new USB device driver in
\code{/sys/bus/usb/drivers/snd-usb-audio}. This directory shows which
USB devices are bound to this driver.
You can check that \code{/proc/asound} now exists (thanks to loading
modules for the ALSA, the Linux sound subsystem), and that one sound
card is available:
Expand All @@ -474,7 +538,7 @@ \subsection{Installing and using in-tree kernel modules}
We cannot test the sound card yet, as we will need to build some
software first. Be patient, this is coming soon.
\subsection{Compiling and installing an out-of-tree kernel module}
\section{Compiling and installing an out-of-tree kernel module}
The next device we want to support is the I2C Nunchuk. There is a driver
in the kernel to support it when connected to a Wiimote controller, but
Expand Down Expand Up @@ -508,7 +572,7 @@ \subsection{Compiling and installing an out-of-tree kernel module}
make -C $HOME/__SESSION_NAME__-labs/kernel/linux \
M=$PWD \
INSTALL_MOD_PATH=$HOME/__SESSION_NAME__-labs/tinysystem/nfsroot \
modules_install
modules_install
\end{bashinput}
You can see that this installs out-of-tree kernel modules under
Expand Down

0 comments on commit dd1d4e3

Please sign in to comment.