Linux device tree (AD5628) - linux

I am trying to use AD5628 Digital to analog converter on my raspberry Pi 3 board . I have enabled the driver for that (http://lxr.free-electrons.com/source/drivers/iio/dac/ad5064.c) in the Yocto kernel .
But when i opened the path /sys/bus/iio/devices/
Mentioned in (https://wiki.analog.com/resources/tools-software/linux-drivers/iio-dac/ad5446) i am not getting any device0.
I got to know that it is a Device tree issue , So i refereed some web sites (https://patchwork.kernel.org/patch/7374261/) and came to know that i need to add the following Device tree details
ad5628-1#4 {
compatible = "adi,ad5628-1";
reg = <4>;
spi-max-frequency = <10000000>;
adi,use-external-reference;
};
But i am not able to find where to add this information in the linux kernel . and how to enable the device tree for this so that my DAC device should be detected by Linux .
Any help regarding this issue will be greatly appreciated

How is the DAC connected to your RPi board ? (SPI/i2c.. ??), so you need to add the dac as part of that device.
For example, in the link which you mentioned the dac is connected to the SPI, so similarly on those lines you need add the DT nodes and also enable the driver in the kernel.
axi_spi_1: spi#42040000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "xlnx,axi-spi-1.02.a", "xlnx,xps-spi-2.00.a";
...
ad5446#0 {
compatible = "adi,ad5446";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpha;
spi-cpol;
vcc-supply = <&dac_vcc>;
};
};

Related

Simple GPIO Device Tree Example for Beaglebone Black Deb 10.3

My goal is to write a simple .dts file (to be compiled to .dtbo using DT 1.4.4) to configure a GPIO output on boot on a Beaglebone Black Rev C running Debian 10.3
I intend to place the .dtbo in /lib/firmware and then specify it in /boot/uEnv.txt
I understand some parts of the .dts file and have tried decompiling exisiting .dtbo files in /lib/firmware/ for guidance but none of them are a simple GPIO output example. A lot of online resources involve make and make install but I believe DT should be able to handle it by now right?
I was able to get the following to compile but with issue:
/* dtc -O dtb -o BB-P8_13-LED.dtbo -b 0 -# BB-P8_13-LED-00A0.dts */
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone-black";
/* identification */
part-number = "BB-P8_13-LED";
version = "00A0";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P8.13", /* GPIO_23 */
/* the hardware ip uses */
"gpio23";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
bb_gpio23_pin: pinmux_bb_gpio23_pin {
pinctrl-single,pins = < 0x024 0x07 >; /*P8_13 GPIO23 MODE7*/
};
};
};
fragment#1 {
target = <&gpio23>;
__overlay__ {
leds {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bb_gpio23_pin>;
compatible = "gpio-leds";
P8_13 {
label = "P8_13";
default-state = "on";
};
};
};
};
};
Q: Why does loading this .dtbo in /boot/uEnv.txt cause all other GPIOs to disappear from /sys/class/gpio/? I thought fragment0 was for excluding a single gpio, not all of them.
###Additional custom capes
uboot_overlay_addr4=/lib/firmware/BB-P8_13-LED-00A0.dtbo
Q: Where are the files for controlling the GPIO (for testing) or rather what can I add to my .dts file so the gpio23 still appears in /sys/class/gpio or even /sys/class/leds? Ultimately I want to be able to control this GPIO with Node-RED.
Q: Do I need to be consistent with my use of P8.13 vs. P8_13? I think I'm mixing up terminology used in .dts files that get compiled with make vs DT.
Q: I think my fragment#1 P8_13 child node is missing something to specify the gpio bank and active high/low setting. Something like "gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;" Where can I look to research which bank GPIO23 is in? What does the '19' mean in that statement?
So Dr. Derek Molly did a really nice job of laying this out and I was able to use the example in his repo. Here is a page he made for explaining how to configure GPIO at boot using Device Tree Overlays:
http://derekmolloy.ie/beaglebone/beaglebone-gpio-programming-on-arm-embedded-linux/
Even though his solution is for kernel 3.8 I was able to get the following to compile on 4.19
/* dtc -O dtb -o BB-P8_13-LED-00A0.dtbo -b 0 -# BB-P8_13-LED-00A0.dts */
/dts-v1/;
/plugin/;
/{
compatible = "ti,beaglebone-black";
part-number = "BB-P8_13-LED";
version = "00A0";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
pinctrl_test: BB-P8_13-LED {
pinctrl-single,pins = <
0x024 0x27 /* P8_13 9 PULLUP ENABLED OUTPUT MODE7 - The LED Output */
>;
};
};
};
fragment#1 {
target = <&ocp>;
__overlay__ {
test_helper: helper {
compatible = "bone-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_test>;
status = "okay";
};
};
};
};
All that needs to be edited for a different GPIO pin is the "0x024" (address offset) and the "0x27" to set various aspects of the GPIO like pullup vs. pulldown and pinmux mode. Derek Molly has an older version of his guide which has the table for building the pinmux binary values (that need to be converted to hex): http://derekmolloy.ie/gpios-on-the-beaglebone-black-using-device-tree-overlays/
Most of the information is available in the Beaglebone SRM which I should probably read at some point.
The .dts file in my first answer did not fix my problem. GPIO P8_13 still boots as an input. After more digging and testing I have discovered it is NOT possible to make a GPIO direction survive a reboot. It will always boot to the default and the best you can do is enable a pullup or pulldown resistor to keep the pin high or low until a custom service file (or program) can write to /sys/class/gpio/gpioXXX/direction. I even tried decompiling am335x-boneblack.dtb, editing it, and re-compiling with no luck.
This is sad and incredibly frustrating. What good is an output that flickers during reboot? Guess I'll have to compensate with fancy external circuitry.
Per the original question, you can author a dts file where the GPIO remains in /sys/gpio/class/. See the article I wrote below for an example that works this way.
https://takeofftechnical.com/beaglebone-black-led-control/

Reading from uart

I am using am57x micro-controller and plugged my ublox neo-m8n gps to UART6. After putting uart6 in device tree as shown below, how can I know which file to read from? i couldn't find anything in /sys/class/.. how do i know which tty file the gps is writing to? Are there any uart native commands like the iscdetect and i2cget for i2c? Any help is appreciated
From dra7.dtsi:
uart6: serial#48068000 {
compatible = "ti,dra742-uart", "ti,omap4-uart";
reg = <0x48068000 0x100>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "uart6";
clock-frequency = <48000000>;
status = "disabled";
dmas = <&sdma_xbar 79>, <&sdma_xbar 80>;
dma-names = "tx", "rx";
};
From my device tree:
&uart6 {
pinctrl-names = "default";
pinctrl-0 = <&uart6_pins_default>;
status = "okay";
};
Never mind, after a lot of trial, I found out that it was writing to /dev/ttyS5. The link below helped me figure it out:
https://www.technexion.com/support/knowledgebase/using-a-serial-port-from-a-linux-shell/
If you are running linux and your serial device is detected by the kernel. It will print the message in the kernel log buffer where the device is attached.
If the device is not showing in /sys/class check the kernel logs using "dmesg" command after inserting the module. It will show error if kernel not able detect your device properly.

Adding touch screen driver to Wandboard, i2c device registration

First I must to tell you, I am not really from electronics background, I have very rough knowledge about Linux drivers, I2C, touch screens, etc.
Problem background
My Wandboard was previously working with Fusion 7 touch display worked with Prism touch screen driver, already provided by Wandboard.
As per my new requirement, I have got Ilitek touch screen which I am trying get it working with my Wandboard dual (i.MX6-Cortex-A9, Linux Kernel:3.0.35).
I got following Ilitek touch screen driver files under folder ilitek_limv3_0_9.
ilitek_lim.c
ilitek.h
ilitek_update.c
ilitek_i2c.idc
I compiled the driver into Linux kerenl as a built-in module, tried to run on the board but failed. The driver doesn't appear in /dev/input.
I debuged the kerenl code a bit, and found that the code doesn't reach to driver's probe function, instead it fails in device binding (i2c device registration). Just then I come to know about Device tree.
I looked into following dts files (which I believe my Wandboard is using), putting little i2c configuration present in the files here.
imx6qdl.dtsi
i2c1: i2c#021a0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a0000 0x4000>;
interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C1>;
status = "disabled";
};
i2c2: i2c#021a4000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a4000 0x4000>;
interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C2>;
status = "disabled";
};
i2c3: i2c#021a8000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
reg = <0x021a8000 0x4000>;
interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_I2C3>;
status = "disabled";
};
imx6qdl-wandboard.dtsi
&hdmi {
ddc-i2c-bus = <&i2c1>;
status = "okay";
};
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
codec: sgtl5000#0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&clks 201>;
VDDA-supply = <&reg_2p5v>;
VDDIO-supply = <&reg_3p3v>;
};
};
I see dts note entry for sgtl5000 which is audio codec which then appears as /dev/input/event0. But I don't find any entry for 'prism' driver, which actually runs perfectly on the board. Neither dts files nor board-files have entry for 'prism' driver. But I am sure it's using 'device-tree' approach.
Questions
As my Wandboard works fine with 'prism' driver and touch device, why I don't see device node entry for 'prism' in dts files ?
Is there any other way for 'i2c device registration' other than 'device-tree' and 'earlier board-file' approach ?
How could I get past with ilitek touch driver not getting i2c-matched/registered problem ?
Thanks in advance.

Modifying the device tree for the Beaglebone Black

I have used Yocto to create a small linux image for the Beaglebone Black. I think I have most everything working like I want it, except I need access to UARTs 2 and 4. When I was using the standard Debian image, I did this with device tree overlays and capemgr. However, I found that the kernel built with Yocto doesn't have capemgr.
My options seem to be:
get the kernel to build with capemgr, or
modify the device tree file with the necessary changes.
Option 2 seems much easier.
The device tree overlays for the UARTs are here and here. I have gone about trying to include those in a couple ways.
I decompiled the device tree blob I had been using and tried to
include these files from there.
I downloaded the full set of dts files and tried to include the
UART device tree overlays in am335x-boneblack.dts.
Both approaches yield an error something like this:
Error: am335x-boneblack.dts:1.1-2 syntax error
FATAL ERROR: Unable to parse input tree
However, I noticed that I get a similar error when trying to compile am335x-boneblack.dts even without modifying it, so I'm likely not even doing that right. (Using the command dtc -I dts -O dtb -o result.dtb am335x-boneblack.dts)
Obviously I don't know what I'm doing. I suspect the device tree overlays have to be modified in some way to be used in the way I'm trying to use them. Or maybe I'm not doing the include right (just adding a #include to the top of the file).
Does anybody have any ideas what I might be doing wrong? Is what I'm trying to do even possible?
So I got this working by taking my device tree blob, decompiling it, and merging in sections from the device tree overlay files, and recompiling. I realized I needed uarts 1 and 2 instead of 2 and 4, so this is slightly different than my original problem.
To decompile the device tree blob:
dtc -I dtb -O dts -o am335x-boneblack.dts am335x-boneblack.dtb
I used the existing uart0 as an example to show me the right sections to work in.
I added a section for uart1 and uart2 in the pinmux section under the section for uart0. It now looks like this:
pinmux_uart0_pins {
pinctrl-single,pins = <0x170 0x30 0x174 0x0>;
linux,phandle = <0x27>;
phandle = <0x27>;
};
bb_uart1_pins: pinmux_bb_uart1_pins {
pinctrl-single,pins = <
0x184 0x20 /* P9.24 uart1_txd.uart1_txd OUTPUT */
0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd INPUT */
>;
};
bb_uart2_pins: pinmux_bb_uart2_pins {
pinctrl-single,pins = <
0x150 0x21 /okay* spi0_sclk.uart2_rxd | MODE1 */
0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */
>;
};
Then later, the serial sections need to be enabled and told what pins to use. I modified existing uart sections, and it now looks like this:
serial#44e09000 {
compatible = "ti,omap3-uart";
ti,hwmods = "uart1";
clock-frequency = <0x2dc6c00>;
reg = <0x44e09000 0x2000>;
interrupts = <0x48>;
status = "okay";
dmas = <0x26 0x1a 0x26 0x1b>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <0x27>;
};
serial#48022000 {
compatible = "ti,omap3-uart";
ti,hwmods = "uart2";
clock-frequency = <0x2dc6c00>;
reg = <0x48022000 0x2000>;
interrupts = <0x49>;
status = "okay";
dmas = <0x26 0x1c 0x26 0x1d>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&bb_uart1_pins>;
};
serial#48024000 {
compatible = "ti,omap3-uart";
ti,hwmods = "uart3";
clock-frequency = <0x2dc6c00>;
reg = <0x48024000 0x2000>;
interrupts = <0x4a>;
status = "okay";
dmas = <0x26 0x1e 0x26 0x1f>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&bb_uart2_pins>;
}
To recompile the device tree:
dtc -I dts -O dtb -o am335x-boneblack.dtb am335x-boneblack.dts
In short, I managed to get this working despite having little to no idea how device trees work.
I also needed to disable hdmi which I did by setting status equal to "disabled" in the hdmi section.

linux: spidev is not shown in /dev

I did the following steps in order to use spidev in Linux- kernel 3.14.28 compiled on arm imx6Q (SMARC board, by Yocto-Project):
In kernel configuration, I enabled SPIDEV: CONFIG_SPI_SPIDEV=y.
In device tree, I added the following lines:
&smarc_spi0 {
spidev#1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "linux, spidev";
spi-max-frequency = <20000000>;
reg = <1>;
};
};
I compiled my Linux successfully, and still can't see /dev/spidev0.1 appear in /dev folder.
Any idea?
I found out the problem: compatible string wasn't accurate..
I had extra space between "linux," and "spidev"..
The appropriate way is:
compatible = "linux,spidev";

Resources