Thursday, 30 June 2016

Using MAX14830 with Raspberry Pi 3

MAX14830 is SPI/I2C to quad UART converter IC. This IC works with Linux, tested on Raspberry Pi 3. To get it working we need to setup device tree for our hardware. I have MAX14830EVKIT from Maxim, all four serial ports of this kit were detected and are working.

1. You need following to create a test setup

1.1. Raspberry PI 3, you can use any other SBC which you have.

1.2. MAX14830EVKIT from Maxim or similar hardware.



1.3. Connector cable to connect RPi3 to MAX14830 dev kit


1.4. Complete hardware setup


2. Flash RPi3 with latest image. My uname -a gives following

root@raspberrypi:~# uname -a
Linux raspberrypi 4.4.11-v7+ #888 SMP Mon May 23 20:10:33 BST 2016 armv7l GNU/Linux
root@raspberrypi:~# cat /etc/debian_version
8.0

You will have to compile driver for your kernel or recompile kernel with max310 driver enabled.
Driver source is located at   kernel_source/drivers/tty/serial/max310x.c.

3. Install device tree compiler using
root@raspberrypi:~# apt-get install device-tree-compiler

4. Create DTS file to turn off spidev.
 I have file named spidev-off.dts with following contents.

/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";


        fragment@0 {
                target = <&spidev0>;
                __overlay__ {
                        status = "disabled";
                };
        };

        fragment@1 {
                target = <&spidev1>;
                __overlay__ {
                        status = "disabled";
                };
        };
};

5. Create DTS file to set clock of MAX14830. Change frequency as per your MAX14830 hardware.
Pl note this dts must be loaded ad boot time.
I have file named  max14830-clock.dts with following contents.

// Overlay for the Maxim max14830 clock
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";


        fragment@1 {
                target = <&clocks>;
                __overlay__ {
                        xtal36: xtal36@7 {
                                reg = <0x7>;
                                compatible = "fixed-clock";
                                #clock-cells = <0>;
                                clock-frequency = <3686400>;
                                clock-output-names = "xtal36";
                        };
                };
        };
};

6. Create DTS file for MAX14830.
I have file named max14830.dts with following content. Pl customize interrupts for your hardware.

// Overlay for the Maxim max14830
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";

        fragment@0 {
                target = <&spi0>;
                __overlay__ {
                        /* needed to avoid dtc warning */
                        #address-cells = <1>;
                        #size-cells = <0>;

                        status = "okay";


                        max14830_1: max14830_1@0 {
                                compatible = "maxim,max14830";
                                reg = <0>; /* CE0 */
                                clocks = <0x44>;
                                clock-names = "xtal";
                                spi-max-frequency = <12000000>;
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <&max14830_pins>;
                                interrupt-parent = <&gpio>;
                                interrupts = <17 0x2>; /* falling edge */
                        };
                };
        };

        fragment@1 {
                target = <&gpio>;
                __overlay__ {
                        max14830_pins: max_14830_pins {
                                brcm,pins = <4>;
                                brcm,function = <0>; /* in */
                                brcm,pull = <0>; /* none */
                        };
                };
        };

        __overrides__ {
                int_pin = <&max14830_1>, "interrupts:0",
                          <&max14830_pins>, "brcm,pins:0";
                speed   = <&max14830_1>, "spi-max-frequency:0";
        };
};

Pl note line    clocks = <0x44>  above. Number 0x44 is phandle in clock settings. You can find this number by using following command.
dtc -I fs /proc/device-tree | grep -A 4 xtal36

7. Now we have 3 dts files. Compile files using dtc compiler and place .dto files in /boot/overlays/
The reason for having three different file is that you can load spidev-off.dtbo and max14830-clock,dtbo at boot time and load/unload max14830.dtbo after boot with dtoverlay command. This helps in experimenting with max14830.dts code.
To compile dts file use following command
 dtc -@ -I dts max14830.dts -o /boot/overlays/max14830.dtbo


To load dtbo at boot time, append following lines to /boot/config.txt

dtoverlay=spidev-off
dtoverlay=max14830-clock

8. Reboot system and load max14830.dtbo file using following command
/opt/vc/bin/dtoverlay max14830
when  max14830.dtbo is loaded, kernel driver will also get loaded. If not do depmod -a and try again.

Now check that dtbo has been loaded and there are no errors reported. If everything goes well you will find 4 device entries(ttyMAX0-3) in /dev corresponding to 4 serial ports on your card.

9. If every thing works fine, create a single dts file and load it at boot time.

Thanks

*Special thanks to Rishabh, without his help it would not have been possible.