\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}% http://ctan.org/pkg/lm
\usepackage{minted}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage[normalem]{ulem}

\mode<presentation>
\usetheme{Bootlin}

\def\signed #1{{\leavevmode\unskip\nobreak\hfil\penalty50\hskip2em
  \hbox{}\nobreak\hfil(#1)
  \parfillskip=0pt \finalhyphendemerits=0 \endgraf}}

\newsavebox\mybox
\newenvironment{aquote}[1]
  {\savebox\mybox{#1}\begin{quotation}}
  {\signed{\usebox\mybox}\end{quotation}}

\title{IIO, a new kernel subsystem}
\authors{Maxime Ripard}
\institute{Bootlin}
\email{maxime.ripard@bootlin.com}
\slidesurl{https://bootlin.com/pub/conferences/}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{IIO, a new kernel subsystem}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\begin{frame}
  \frametitle{Outline}
  \tableofcontents
\end{frame}

\begin{frame}{Maxime Ripard}
  \begin{itemize}
  \item Embedded Linux engineer and trainer at Bootlin since
    2011
    \begin{itemize}
    \item Embedded Linux development: kernel and driver development,
      system integration, boot time and power consumption
      optimization, etc.
    \item Embedded Linux, Embedded Android and driver development
      training, with materials freely available under a Creative
      Commons license.
    \item \url{https://bootlin.com}
    \end{itemize}
  \item Contributor to Buildroot, a simple open-source embedded build
    system
  \end{itemize}
\end{frame}

\section{What is IIO ?}

\subsection{Definition}
\begin{frame}{IIO}
  \begin{itemize}
  \item A subsystem for Analog to Digital Converters (ADCs) and
    related hardwares (accelerometers, light sensors, gyroscopes), but
    also DACs
  \item Can be used on ADCs ranging from a SoC ADC to 100M samples/sec
    industrial ADCs
  \item Until recently, mostly focused on user-space abstraction with
    no in-kernel API for other drivers
  \end{itemize}
\end{frame}

\subsection{Current state in the kernel}
\begin{frame}{Current state in the kernel}
  \begin{itemize}
  \item Developed since 2009 by Jonathan Cameron
  \item Being developed in the \path{staging/} directory until it
    comes to an high quality code and a mature API
  \item It is now moving out of staging, one step at a time: first,
    basic features, then the support for advanced IIO features.
  \item Already has a lot of different hardware supports and drivers
    for them, mostly from Analog Devices Inc, but also drivers for
    Texas Instruments, Atmel, etc.
  \end{itemize}
\end{frame}

\section{Getting started}
\subsection{IIO device}
\begin{frame}
\frametitle{iio\_dev structure}
\begin{itemize}
  \item Main structure of all IIO drivers
  \item Holds informations about the device and the driver, such as :
  \begin{itemize}
    \item How much channels are available on the device ?
    \item What modes can the device operate in ?
    \item What hooks are available for this driver ?
  \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Allocate a new device}
\begin{minted}[fontsize=\footnotesize]{c}
struct iio_dev *idev = iio_allocate_device)
                                sizeof(struct at91_adc_state));
\end{minted}

  \begin{itemize}
  \item Allocates a struct iio\_dev, along with the private data of
    your driver
  \item Does all the basic initialisation
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Capture modes}
\begin{minted}[fontsize=\footnotesize]{c}
idev->modes = INDIO_DIRECT_MODE;
\end{minted}

Defines the mode of operations available for this device, to choose
between :\\
\begin{description}
  \item[INDIO\_DIRECT\_MODE] the device can operate using software triggers
  \item[INDIO\_BUFFER\_TRIGGERED] the device can use hardware triggers
  \item[INDIO\_BUFFER\_HARDWARE] the device has a hardware buffer
  \item[INDIO\_ALL\_BUFFER\_MODES] union of the two above
\end{description}
\end{frame}

\begin{frame}[fragile]
\frametitle{IIO infos}

\begin{minted}[fontsize=\footnotesize,frame=lines]{c}
static const struct iio_info at91_adc_info = {
        .driver_module = THIS_MODULE,
        .read_raw = &at91_adc_read_raw,
};
\end{minted}

\begin{minted}[fontsize=\footnotesize,frame=lines]{c}
idev->info = &at91_adc_info;
\end{minted}

  \begin{itemize}
  \item Used to declare the hooks the core can use for this device
  \item Lot of hooks available corresponding to interactions the user
    can make through sysfs.
  \item \verb+read_raw+ for example is called to request a value from
    the driver. A bitmask allows us to know more precisely which type
    of value is requested, and for which channel if needed. It can be
    for example either the scale used to convert value returned to
    volts or the value in itself.
  \end{itemize}
\end{frame}

\begin{frame}{Basic design of the driver}
  \begin{center}
    \includegraphics[height=0.8\textheight]{read_raw.pdf}
  \end{center}
\end{frame}

\subsection{IIO channels}
\begin{frame}[fragile]
\frametitle{iio\_channels declaration}
\begin{minted}[fontsize=\footnotesize]{c}
struct iio_chan_spec *chan = kmalloc(sizeof(struct iio_chan_spec),
                                     GFP_KERNEL);
chan->type = IIO_VOLTAGE;
chan->indexed = 1;
chan->channel = 1;
chan->scan_type.sign = 'u';
chan->scan_type.realbits = 10;
chan->scan_type.storagebits = 16;
chan->info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT;

idev->channels = chan;
idev->num_channels = 1;
\end{minted}
\end{frame}

\begin{frame}[fragile]{Register the device}
\begin{minted}[fontsize=\footnotesize]{c}
iio_device_register(idev);
\end{minted}

\begin{itemize}
\item this is sufficient to have a basic IIO device driver
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Userspace API}

If we look at \path{/sys/bus/iio/devices/iio:deviceX}, we should have:
\begin{minted}{console}
$ ls /sys/bus/iio/devices/iio:deviceX
in_voltage0_raw
in_voltage_scale
name
$
\end{minted}

  \begin{itemize}
  \item reading in\_voltage0\_raw calls the read\_raw hook, with the
    mask set to 0, and the chan argument set with the iio\_chan\_spec
    structure corresponding to the the channel 0
  \item reading in\_voltage\_scale calls the read\_raw hook, with the
    mask set to IIO\_CHAN\_INFO\_SCALE
  \end{itemize}

\end{frame}

\section{Going further : Hardware triggers and buffers}
\subsection{Hardware Triggers}
\begin{frame}[fragile]
\frametitle{Hardware Triggers}

IIO exposes API so that we can :
  \begin{itemize}
  \item declare any given number of triggers
  \item choose which channels we want enabled for conversions
  \end{itemize}
  \begin{center}
    \includegraphics[height=0.6\textheight]{pollfunc.pdf}
  \end{center}
\end{frame}

\begin{frame}[fragile]
\frametitle{Kernel API}
  \begin{minted}[fontsize=\footnotesize, frame=lines]{c}
static const struct iio_trigger_ops at91_adc_trigger_ops = {
	.owner = THIS_MODULE,
	.set_trigger_state = &at91_adc_configure_trigger,
};
  \end{minted}

  \begin{minted}[fontsize=\footnotesize]{c}
struct iio_trigger *trig = iio_allocate_trigger("foo");
trig->ops = &at91_adc_trigger_ops;
iio_trigger_register(trig)
  \end{minted}

  \begin{itemize}
  \item Once again, we have hooks to declare
  \item These hooks are this time triggers-specific, so that we can
    have a function called when the trigger state changes.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Poll Function}
  \begin{itemize}
  \item function triggered at each conversion
  \item called through the functions \verb+iio_trigger_poll+ or
    \verb+iio_trigger_poll_chained+
  \item basically, its job is to feed retrieve data from the device
    and feed them into the buffer
  \item IIO uses the IRQ model, so the poll function has the same
    prototype than any other IRQ handler.
  \end{itemize}

  \begin{minted}[fontsize=\footnotesize]{c}
idev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
                                    &at91_adc_trigger_handler,
                                    IRQF_ONESHOT,
                                    idev,
                                    "foo");
  \end{minted}
\end{frame}

\subsection{Buffers}
\begin{frame}
\frametitle{Buffers}
\begin{itemize}
\item doesn't make much sense to have triggered captures without a
  buffer
\item Buffers and triggers are closely tied together in IIO
\item 2 types of buffers in IIO
  \begin{itemize}
  \item One relies on kfifo
  \item The other one is a ring buffer
  \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Allocate a buffer}
  \begin{itemize}
  \item in the latest code, if you want to use the IIO ring buffer,
    boiler plate code has been added so it's pretty straightforward.
    \begin{minted}[fontsize=\footnotesize]{c}
ret = iio_sw_rb_simple_setup(idev,
                             &iio_pollfunc_store_time,
                             &at91_adc_trigger_handler);
    \end{minted}
  \item Allocate the buffer, allocates the poll function, declares the
    device as supporting triggered capture, register the buffer
    against the core, etc
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Userspace API 1/3: Set up the capture}
  If we look at \path{/sys/bus/iio/devices/}, we should now have in
  addition to \path{iio:deviceX}:

\begin{minted}[fontsize=\footnotesize]{console}
$ ls /sys/bus/iio/devices/
iio:device0
trigger0
$ ls /sys/bus/iio/devices/iio:device0
buffer
scan_elements
trigger
$ ls /sys/bus/iio/devices/iio:device0/buffer
enabled length
$ ls /sys/bus/iio/devices/iio:device0/scan_elements
in_voltage0_en
in_voltage0_index
in_voltage0_type
$ ls /sys/bus/iio/devices/trigger0
name
$
\end{minted}

\end{frame}

\begin{frame}[fragile]{Userspace API 2/3: Start and stop a capture}
  \begin{minted}[fontsize=\footnotesize]{console}
$ echo 1 > \
    /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en
$ echo "foo" > \
    /sys/bus/iio/devices/iio:device0/trigger/current_trigger
$ echo 100 > /sys/bus/iio/devices/iio:device0/buffer/length
$ echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable
$ echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable
$ echo "" > \
    /sys/bus/iio/devices/iio:device0/trigger/current_trigger
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Userspace API 3/3: Get the capture results}
  \begin{itemize}
  \item IIO also exposes a character device to get the converted
    values: \path{/dev/iio:deviceX}
  \item You just have to read in it to get data
  \item Data are organized by chunks
    \begin{itemize}
    \item Example: You have 4 channels, plus a timestamp one. All are
      enabled except channel 2.\\
      \begin{center}
        \begin{tabular}{c|c|c|c|c|}
          & \multicolumn{3}{c}{Channels} & Timestamp\\
          \hline
          Index & 0 & 1 & 3 & \\
          \hline
          Size in bits & 16 & 16 & 16 & 64\\
          \hline
        \end{tabular}
      \end{center}
    \end{itemize}
  \item There is a program that provides a basic implementation and a
    good way to test your driver in the IIO documentation directory:
    \path{drivers/staging/iio/Documentation/generic_buffer.c}

\begin{minted}[fontsize=\footnotesize]{console}
# ./generic-buffer -n at91_adc -t at91_adc-dev0-external
\end{minted}
  \end{itemize}
\end{frame}

\section{Useful Resources}
\begin{frame}{Useful Resources}
  \begin{itemize}
  \item \path{drivers/staging/iio/Documentation}
  \item \path{drivers/staging/iio/iio_simple_dummy.c}
  \item \url{http://www.ohwr.org/projects/zio/wiki/Iio}
  \item \url{http://www.at91.com/linux4sam/bin/view/Linux4SAM/IioAdcDriver}
  \item \path{linux-iio@vger.kernel.org}
  \end{itemize}
\end{frame}

\section{Conclusion}
\begin{frame}{Conclusion}
  \begin{itemize}
  \item IIO is a nice subsystem to add ADCs and the like support
  \item Still under heavy development, but also really opens to
    changes and feedback
  \item Yet reliable enough to be used in production
  \end{itemize}
\end{frame}

\end{document}
