FreeBSD-11 has support for i2c on Wandboard.
The working boot image is here, and the boot log is here.
In order to enable it, there were three steps
- Enable the kernel options
- Update the files.imx6 file
- Create the DTS mappings
The kerne config for Wandboard-Quad is here, however, most of the kernel options for Wandboard Quad are in the IMX6 config. The kernel options to enable are:
device fsliic # Freescale i2c/iic device iic # iic protocol device iicbus # iic bus
The files files.imx6 contains the mappings between the devices in the conf file, and the files to compile for that device. In order to compile in the fsliic device for Freescale, I need to enable the mapping for it, so that /sys/arm/freescale/imx/i2c.c is compiled in.
arm/freescale/imx/i2c.c optional fsliic
Finally, I need to update the DTS files. The file wandboard-quad.dts contains the device mappings for wandboard quad. However, similar to the kernel configuration, all the real mappings are in imx6.dtsi. There are three i2c controllers on the wandboard quad, so I added these mappings:
i2c@021a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx-i2c"; reg = <0x021a0000 0x4000>; interrupt-parent = <&gic>; interrupts = <68>; }; i2c@021a4000 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx-i2c"; reg = <0x021a4000 0x4000>; interrupt-parent = <&gic>; interrupts = <69>; }; i2c@021a8000 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx-i2c"; reg = <0x021a8000 0x4000>; interrupt-parent = <&gic>; interrupts = <70>; };
The memory locations (0x21a000, 0x21a4000, 0x21a8000) as well as the interrupts (68,69,70) come from the IMX6 documentation. This line
compatible = "fsl,imx-i2c";
is the line that the i2c.c driver uses in probe() to determine that this hardware is a compatible Freescale IMX i2c device.
Once the kernel is compiled and started it will detect the 3 iic devices. The relevant lines from the boot log are:
iichb0: <I2C bus controller> mem 0x21a0000-0x21a3fff irq 68 on simplebus2 iicbus0: <OFW I2C bus> on iichb0 iic0: <I2C generic I/O> on iicbus0 iichb1: <I2C bus controller> mem 0x21a4000-0x21a7fff irq 69 on simplebus2 iicbus1: <OFW I2C bus> on iichb1 iic1: <I2C generic I/O> on iicbus1 iichb2: <I2C bus controller> mem 0x21a8000-0x21abfff irq 70 on simplebus2 iicbus2: <OFW I2C bus> on iichb2 iic2: <I2C generic I/O> on iicbus2
You should have 3 iic devices in the /dev/ directory
crw------- 1 root wheel 0x20 Jul 6 01:23 iic0 crw------- 1 root wheel 0x21 Jul 6 01:23 iic1 crw------- 1 root wheel 0x22 Jul 6 01:23 iic2
You can check which devices are specified in the dts file, using ofwdump.
root@wandboard:/dev # ofwdump -a Node 0x38: Node 0xa8: cpus Node 0xd4: cpu@0 Node 0x190: aliases Node 0x1bc: soc@00000000 Node 0x230: generic-interrupt-controller@00a00100 Node 0x2cc: mp_tmr0@00a00200 Node 0x348: l2-cache@00a02000 Node 0x3d0: aips@02000000 Node 0x458: ccm@020c4000 Node 0x4b4: anatop@020c8000 Node 0x520: timer@02098000 Node 0x594: gpio@0209c000 Node 0x668: gpio@020a0000 Node 0x71c: gpio@020a4000 Node 0x7f0: gpio@020a8000 Node 0x8a4: gpio@020ac000 Node 0x958: gpio@020b0000 Node 0xa0c: gpio@020b4000 Node 0xac0: serial@02020000 Node 0xb4c: serial@021e8000 Node 0xbdc: serial@021ec000 Node 0xc6c: serial@021f0000 Node 0xcfc: serial@021f4000 Node 0xd8c: usbphy@020c9000 Node 0xe2c: usbphy@020ca000 Node 0xed0: aips@02100000 Node 0xf58: ethernet@02188000 Node 0xfec: usb@02184000 Node 0x1088: usb@02184200 Node 0x1124: usb@02184400 Node 0x11b4: usb@02184600 Node 0x1244: usbmisc@02184800 Node 0x12c4: usdhc@02190000 Node 0x1368: usdhc@02194000 Node 0x1404: usdhc@02198000 Node 0x14a8: usdhc@0219c000 Node 0x1538: i2c@021a0000 Node 0x15d0: i2c@021a4000 Node 0x1668: i2c@021a8000 Node 0x1700: ocotp@021bc000 Node 0x1750: memory Node 0x1774: chosen
You can also check that the iic modules are compiled into the kernel, using kldstat
root@wandboard:/usr/home/tom # kldstat -v | grep iic 131 i2c/iicbus 13 iichb/iicbus 12 iicbus/iic 55 iichb/ofw_iicbus 54 iicbb/ofw_iicbus
Once you have a device connected to the wandboard, you can use the i2c command to access the devices.