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.