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.

pinmux with 814x SDK 5.4.0.11

I am unable to set the pinmux using call to ti814x_mux_init()

Here is my board_mux structure:

static struct omap_board_mux board_mux[] __initdata = {
    TI814X_MUX(MLBP_DAT_P, FCN8),   /* GPIO1_09 */
    TI814X_MUX(MLBP_DAT_N, FCN8),   /* GPIO1_10 */
    TI814X_MUX(VIN0_D0,    FCN8),   /* GPIO1_11 */
    TI814X_MUX(VIN0_D1,    FCN8),   /* GPIO1_12 */
    TI814X_MUX(I2C1_SCL,   FCN1),   /* I2C[1] SCL */
    TI814X_MUX(I2C1_SDA,   FCN1),   /* I2C[1] SDA */
    TI814X_MUX(UART0_DCDN, FCN6),   /* I2C[2] SCL */
    TI814X_MUX(UART0_DSRN, FCN6),   /* I2C[2] SDA */
    TI814X_MUX(DCAN0_TX,   FCN6),   /* I2C[3] SDA */
    TI814X_MUX(DCAN0_RX,   FCN6),   /* I2C[3] SCL */
    { .reg_offset = OMAP_MUX_TERMINATOR },
};

A dump of the registers shows they are all set to 0x01.

If I set the registers directly  through the following code, I get the correct results. MUX_EVM() is a macro provided by the TI Pin Mux utility. All registers are set correctly.

static int user_pinmux_setup (void )
{
    /* reserve memory region for our use */
    if( request_mem_region( PMUXREG_BASE_ADDRESS, PINCNTL270,"user_gpio.ko") == NULL )
    {
        printk( KERN_CRIT
              "user_gpio::user_gpio_pinmux_setup: unable to reserve I/O memory address at 0x%x\n",PMUXREG_BASE_ADDRESS);
        return -EBUSY;
    }

       /* map physical memory */
        TI814X_CTRL_BASE = ioremap(PMUXREG_BASE_ADDRESS,PINCNTL270);

    /* call macro defined in pinmux.h */
        MUX_EVM();

        /* unmap physical memory */
        iounmap(TI814X_CTRL_BASE);

        /* release memory region */
        release_mem_region(PMUXREG_BASE_ADDRESS, PINCNTL270);


        return 0;
}

Also, once I am successful at setting the pinmux (using direct register writes), I cannot control the GPIO through the normal kernel driver calls (e.g. gpio_request(), gpio_direction_ouput(), etc). I have had this all working very successfully with the 816x SDK and the Netra EVM. I am able to control the GPIO through the sysfs interface with no problem using the 814x SDK and chipset.

So, is there an issue with the 814x SDK? I am trying to build the exact same code from the 816x environment in the 814x environment. Have the Linux libraries been implemented in the 814x environment?

As another datapoint, I have all 4 I2C busses working correctly, using simple Linux Read/Write/IOCTL calls into the driver. So, it appears as thought the Linux libraries work fine for I2C. But not GPIO.

Any help/thoughts  would be appreciated.

Thanks

  • I have partially solved my own problem. This was the problem with respect to not being able to control the output pins.

    In order to set/get pin values, I am using user_gpio.ko, which is provided in this post: http://e2e.ti.com/support/embedded/f/354/p/7633/30198.aspx#301. In this kernel module, the following design pattern is followed each time a request was made to either set an output pin, or read an input pin:

    1) gpio_request()

    2) gpio_direction_input() or gpio_direction_output()

    3) gpio_get_value() (if input). gpio_direction_output() would have already set the value

    4) gpio_free()

    The problem is the call to gpio_free(). This function causes a reset of the particular GPIO, which sets the direction back to input, hence putting the value of that pin back to a 0 state. My new solution is to perform all gpio_request() calls once at startup of user_gpio.ko (in the init function), and all gpio_free() calls at shutdown of the module (in the cleanup routine). This forces any user process that wants access to these GPIO to go through user_gpio.ko, which is desired behavior.

    Still looking for a solution as to why the call to ti814x_mux_init() is not working.

  • What are the definitions of FCNn? The code would suggest using OMAP_MUX_MODEn (where n is 0 to 7). The flags TI814X_PULL_DIS and TI814X_PULL_UP can be OR'ed in. Is CONFIG_OMAP_MUX defined?

  • I tried OMAP_MUX_MODEn. Same results. But in any event, I would expect the pinmux registers to be something other than. Still, I will try again.

    CONFIG_OMAP_MUX is defined. I checked to make sure.

    I did not OR in the other values.

    I will try these things and let you know. It will be a few days.

  • Hi Joseph,

    You should modify the board_mux array as follows:

    static struct omap_board_mux board_mux[] __initdata = {
        TI814X_MUX(MLBP_DAT_P, OMAP_MUX_MODE7),    /* GPIO1_09 */
        TI814X_MUX(MLBP_DAT_N, OMAP_MUX_MODE7), /* GPIO1_10 */
        TI814X_MUX(VIN0_D0, OMAP_MUX_MODE7),   /* GPIO1_11 */
        TI814X_MUX(VIN0_D1, OMAP_MUX_MODE7),   /* GPIO1_12 */
        TI814X_MUX(I2C1_SCL, OMAP_MUX_MODE0),   /* I2C[1] SCL */
        TI814X_MUX(I2C1_SDA, OMAP_MUX_MODE0),   /* I2C[1] SDA */
        TI814X_MUX(UART0_DCDN, OMAP_MUX_MODE5),   /* I2C[2] SCL */
        TI814X_MUX(UART0_DSRN, OMAP_MUX_MODE5),   /* I2C[2] SDA */
        TI814X_MUX(DCAN0_TX, OMAP_MUX_MODE5),   /* I2C[3] SDA */
        TI814X_MUX(DCAN0_RX, OMAP_MUX_MODE5),   /* I2C[3] SCL */
        { .reg_offset = OMAP_MUX_TERMINATOR },
    };

    Then you should modify the /arch/arm/mach-omap2/devices.c file, as it overwrites the settings in the board_mux:

    /*HDMI I2C scl and I2C sda Function 2*/
            /*omap_mux_init_signal("hdmi_ddc_scl_mux0",
                TI814X_PULL_UP | TI814X_INPUT_EN);*/
            /*omap_mux_init_signal("hdmi_ddc_sda_mux0",
                TI814X_PULL_UP | TI814X_INPUT_EN);*/

    /*omap_mux_init_signal("vin0_d0",
                    TI814X_PULL_DIS | TI814X_INPUT_EN);*/
            /*omap_mux_init_signal("vin0_d1",
                    TI814X_PULL_DIS | TI814X_INPUT_EN);*/

    //ti814x_d_can_init(0);

    Thus you have the correct settings till the end of the linux kernel source code. And you have to OR the other values in board_mux to set correctly the pull-up/down features, input buffers, etc.

    The problem now is that the firmware, and more precisely the HDMI part of it overwrites again the i2c1_scl/sda settings with the hdmi signals. And you end up with hdmi settings instead of i2c1_scl/sda. You can correct this from the user space, once the system is up.

    Best Regards,

    Pavel


  • Hi Joseph,

    One more option is to disable the automatically loading of the hdmi firmware (ti81xxhdmi.ko) in the init/boot process. You should update the <file system>/etc/init.d/load-hd-firmware.sh file as follows:

    # modprobe ti81xxhdmi

    Thus you will have the correct pin mux settings for i2c1_scl/sda.

    Best Regards,

    Pavel