LAN966x I2C

SoC Resources

LAN966X SoC have 5 FLEXCOMs (Flexible Serial Communication Controller). In order to use the Flexcom I2C interface, a specific flexcom instance must be configured in I2C mode (this is sometimes also called Two-wire interface or TWI)

Kernel configurations

Following kernel config options should be enabled to use LAN966x I2C interface:

  • CONFIG_MFD_ATMEL_FLEXCOM - Flexcom driver config option.

  • CONFIG_I2C_AT91 - I2C driver config option.

  • Corresponding flash driver should be enabled. Below example explains I2C with a EEPROM device for which CONFIG_EEPROM_AT24 config option is required.

Devicetree Configuration

To use I2C interface, following configurations are required in device tree.

  • Each of the flexcom flx0, flx1, flx2, flx3 and flx4 nodes can be configured in I2C mode ATMEL_FLEXCOM_MODE_TWI to use I2C interface.

  • compatible string must be set to microchip,sam9x60-i2c.

  • reg property must be set with register address and length as <0x600 0x200>

  • GPIO pins for TXD, RXD should be configured to pinctrl-0 property.. List of possible pin mappings are as in below table:

FLEXCOM Node DT RXD node RXD pin DT TXD node TXD pin

flx0

fc0_a_rxd_pins

GPIO9

fc0_a_txd_pins

GPIO10

flx0

fc0_b_rxd_pins

GPIO25

fc0_b_txd_pins

GPIO26

flx0

fc0_c_rxd_pins

GPIO62

fc0_c_txd_pins

GPIO63

flx1

fc1_a_rxd_pins

GPIO12

fc1_a_txd_pins

GPIO13

flx1

fc1_b_rxd_pins

GPIO34

fc1_b_txd_pins

GPIO35

flx1

fc1_c_rxd_pins

GPIO47

fc1_c_txd_pins

GPIO48

flx2

fc2_a_rxd_pins

GPIO15

fc2_a_txd_pins

GPIO16

flx2

fc2_b_rxd_pins

GPIO44

fc2_b_txd_pins

GPIO45

flx3

fc3_a_rxd_pins

GPIO18

fc3_a_txd_pins

GPIO19

flx3

fc3_b_rxd_pins

GPIO52

fc3_b_txd_pins

GPIO53

flx3

fc3_c_rxd_pins

GPIO31

fc3_c_txd_pins

GPIO32

flx4

fc4_a_rxd_pins

GPIO21

fc4_a_txd_pins

GPIO22

flx4

fc4_b_rxd_pins

GPIO57

fc4_b_txd_pins

GPIO58

flx4

fc4_c_rxd_pins

GPIO65

fc4_c_txd_pins

GPIO66

  • interrupts property must set with interrupt details. Interrupt lines[CPU INTR] corresponding to a flexcom must be configured as defined in below table:

FLEXCOM ID Shared Peripheral Interrupt CPU INTR

flx0

80

48

flx1

81

49

flx2

82

50

flx3

83

51

flx4

84

52

Note that Shared peripheral interrupt lines start at index ID32. So, CPU INTR must be calculated as [Shared peripheral interrupt number - 32].

  • Input clock clocks property must be set to &nic_clk. Note that NIC clock(200Mhz) is clock used by AXI, AHB fabric and APB bridges which connects all th peripherals.

Example

Following example shows how a flexcom I2C should be defined in DT to use EEPROM device present on it:

flx2: flexcom@e0060000 {
    compatible = "atmel,sama5d2-flexcom";
    reg = <0xe0060000 0x100>;
    clocks = <&clks GCK_ID_FLEXCOM2>;
    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0xe0060000 0x800>;
    status = "disabled";

    i2c2: i2c@600 {
        compatible = "microchip,sam9x60-i2c";
        reg = <0x600 0x200>;
        interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
        dmas = <&dma0 AT91_XDMAC_DT_PERID(7)>,
               <&dma0 AT91_XDMAC_DT_PERID(6)>;
        dma-names = "tx", "rx";
        clocks = <&nic_clk>;
        #address-cells = <1>;
        #size-cells = <0>;
        status = "disabled";
    };
};

&gpio {
    fc2_b_pins: fc2-b-pins {
        /* RX, TX */
        pins = "GPIO_44", "GPIO_45";
        function = "fc2_b";
    };
};

&flx2 {
    atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
    status = "okay";

    i2c0: i2c@600 {

    pinctrl-0 = <&fc0_b_pins>;
        pinctrl-names = "default";
        atmel,fifo-size = <32>;
        i2c-analog-filter;
        i2c-digital-filter;
        i2c-digital-filter-width-ns = <35>;
        status = "okay";

        eeprom: eeprom@50 {
                compatible = "atmel,24c512";
                reg = <0x50>;
                pagesize = <128>;
                status = "okay";
        };
    };
};

UserSpace

Confirm instances are created

To confirm if i2c flash is created:

  • Check if flash device is created in /sys/bus/i2c/devices/ directory.

Example on how to use

Following example shows how to read/write to I2C eeprom device:

# dmesg | grep i2c
[    5.749296] at91_i2c e0060600.i2c: can't get DMA channel, continue without DMA support
[    5.757431] at91_i2c e0060600.i2c: Using FIFO (32 data)
[    5.763341] at91_i2c e0060600.i2c: recovery information incomplete
[    5.782333] at91_i2c e0060600.i2c: AT91 i2c bus driver (hw version: 0x820).
#
# dmesg | grep EEPROM
[    5.774793] at24 0-0050: 65536 byte 24c512 EEPROM, writable, 128 bytes/write
#
# cat /proc/interrupts | grep i2c
 32:      65538     GIC-0  82 Level     e0060600.i2c
#
# echo "02_09: Sunrise: Testing TWI on Drop_7C. I2C EEPROM is detected and able
to read it" > /sys/bus/i2c/devices/0-0050/eeprom
#
#
# more /sys/bus/i2c/devices/0-0050/eeprom | od -c
0000000   0   2   _   0   9   :       S   u   n   r   i   s   e   :
0000020   T   e   s   t   i   n   g       T   W   I       o   n       D
0000040   r   o   p   _   7   C   .       I   2   C       E   E   P   R
0000060   O   M       i   s       d   e   t   e   c   t   e   d       a
0000100   n   d       a   b   l   e       t   o       r   e   a   d
0000120   i   t  \n   K   b   i   t   )       S   e   r   i   a   l
0000140   E   l   e   c   t   r   i   c   a   l   l   y       E   r   a
0000160   s   a   b   l   e       P   R   O   M  \n 377 377 377 377 377
0000200 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
*
0010400 377 377 377 377 377   V 377 377 377 377 377 377 377 377 377 377
0010420 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
*
0011000 377   T   h   i   s       i   s       C   P   U       T   W   I
0011020       M   a   s   t   e   r       m   o   d   e       t   e   s
0011040   t  \0 377 377 377 377 377 377 377 377 377 377 377 377 377 377
0011060 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
*
0011400  \0 021   "   3   D   U   f   w 210 231 252 273 314 335 356 377
0011420 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
*
0200000
#