This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Device tree for Cypress SPI FRAM on AM335x (TI SDK 7, monolithic kernel)

Hello,

I've got a problem while maintaining transition of my working project from TI Linux SDK version 6 to version 7 (i. e. kernel and bootloader). There is a Cypress FRAM chip (FM25, compatible with AT25 EEPROM) attached to SPI1 hardware interface, which fails to work with the following device tree node:

spi1: spi@481a0000 {
  pinctrl-names = "default";
  pinctrl-0 = <&spi1_pins>;

  status = "okay";

  fram@0 {
    reg = <0x0>;
    compatible = "atmel,at25", "cypress,fm25l16b";
    spi-max-frequency = <20000000>;

    pagesize = <256>;
    size = <2048>;
    address-width = <16>;
  };
};

The corresponding piece of initialization code from my machine board file that worked for me in SDK 6 is:

static struct spi_eeprom fram = {
  .byte_len  = SZ_16K / 8,
  .name      = "fm25l16b",
  .page_size = 256,
  .flags     = EE_ADDR2,
};

static struct spi_board_info am335x_spi1_slave_info[] = {
  {
    .modalias      = "at25",
    .platform_data = &fram,
    .max_speed_hz  = 20 * 1000 * 1000,
    .bus_num       = 2,
    .chip_select   = 0,
    .mode          = SPI_MODE_0,
  },
};

static void spi1_init(void)
{
  setup_pin_mux(spi1_pin_mux);
  spi_register_board_info(am335x_spi1_slave_info, ARRAY_SIZE(am335x_spi1_slave_info));
  return;
}

On SDK 6 based system, there was a "block" file available at path /sys/bus/spi/devices/spi2.0/eeprom, which could be used to access FRAM from userspace. On SDK 7 system with my device tree, there is a path /sys/bus/spi/devices/spi1.0, but there is no "eeprom" or similar "block" file.

Moreover, when I attempt to bind spi1.0 device to at25 driver by running the following command:

echo -n 'spi1.0' >/sys/bus/spi/drivers/at25/bind

I'm getting "write error: No such device" message. By the way, running

cat /sys/bus/spi/devices/spi1.0/modalias

gives me "spi:at25" instead of just "at25", which was returned by the corresponding "spi2.0" device in SDK 6.

I believe my problem is somehow related to the fact that MODULE_ALIAS("spi:at25") macro used in at25 module source code indirectly invokes __MODULE_INFO(...), which in turn expands to an useless unique struct definition, if the kernel module is configured as builtin (i. e. MODULE not defined, see include/linux/moduleparam.h).

A logical solution for this problem would be configuring this module as loadable, so that the information passed to MODULE_ALIAS(...) would actually be obtainable for the kernel. However, this isn't much of an option for my particular project due to a complex feature set (e. g. limited availability of root filesystem), so a monolithic kernel with all the necessary drivers built in would be much more preferable.

This way I'd like to ask whether someone might know an alternative solution which doesn't involve loadable modules or any major kernel patching, in some form or other.

Sincerely in advance,

Ilyas

  • Hi Ilyas,

    I will forward this to the SW team.

  • Hi,

    I'm sorry, it seems that my post should go into the Embedded Linux forum, not this one.

  • Hi Ilyas,

    Did you check:
    http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_SPI. For the compiling this driver in kernel or compiling as module you have to add this in a .config file and mark them. These changes you can make in a corresponding Kconfig file.

    BR
    Ivan

  • Hi Ivan,

    Sorry, but the wiki resource at URL given by you looks incomplete (no links, except for bindings sample - which is already included into device tree with am33xx.dtsi). At least I didn't find anything looking like a changes description or a patch for any Kconfig files.

    As for the .config file, there is a "CONFIG_EEPROM_AT25=y" line present, so the module is enabled already. I've performed the necessary configuration via

    export ARCH=arm
    export CROSS_COMPILE=arm-linux-gnueabihf-
    make tisdk_var-som-am33_defconfig
    make menuconfig

    The whole point of my post is that the built-in at25 driver is loaded (and even shown in sysfs) but it fails to "recognize" the hardware declared in the device tree.

  • It turns out that the problem is partially related to OF-style match table in the at25 driver - or rather, absence thereof. The following patch solves that part for me:

    Index: linux-3.12.10/drivers/misc/eeprom/at25.c
    ===================================================================
    --- linux-3.12.10.orig/drivers/misc/eeprom/at25.c
    +++ linux-3.12.10/drivers/misc/eeprom/at25.c
    @@ -462,10 +462,19 @@
     
     /*-------------------------------------------------------------------------*/
     
    +#ifdef CONFIG_OF
    +static const struct of_device_id at25_of_match[] = {
    +	{ .compatible = "atmel,at25" },
    +	{}
    +};
    +MODULE_DEVICE_TABLE(of, at25_of_match);
    +#endif
    +
     static struct spi_driver at25_driver = {
     	.driver = {
     		.name		= "at25",
     		.owner		= THIS_MODULE,
    +		.of_match_table	= of_match_ptr(at25_of_match),
     	},
     	.probe		= at25_probe,
     	.remove		= at25_remove,

    Another part of the problem is that SPI1 master clock for some weird reason refuses to work on my configuration. The pins used for SPI1 correspond to the interface's IO Set 10 for AM335x in the TI Pin Mux Utility:

    spi1_pins: pinmux_spi1_pins {
      pinctrl-single,pins = <
        0x164 (PIN_INPUT_PULLUP | MUX_MODE4)  /* ecap0_in_pwm0_out.spi1_sclk */
        0x168 (PIN_INPUT_PULLUP | MUX_MODE4)  /* uart0_ctsn.spi1_d0 */
        0x16c (PIN_INPUT_PULLUP | MUX_MODE4)  /* uart0_rtsn.spi1_d1 */
        0x19c (PIN_INPUT_PULLUP | MUX_MODE3)  /* mcasp0_ahclkr.spi1_cs0 */
      >;
    };

    I believe this is probably somehow related to some board-specific code in SDK 7 U-Boot, which configures ecap0_in_pwm0_out as uart3_txd (see board/ti/am335x/mux.c), however I can't be sure of that.

  • Hi Ilyas,

    Have you solved the issue for the cypress fram in Am335x? I also used the cypress fram, and it couldn't work. I check the each signal is no problem, but it still worked fail! If you already solved the issue, would you mind giving me some suggestion? Or give me your device tree file for the cpyress fram?