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.

am335x 在 u-boot 階段 將 i2c 降速成10000

Other Parts Discussed in Thread: TCA6416A, TPS65910, TCA6416

Hi TI team

因某種原因我們必須要做改變,我知道在 u-boot 階段標準 i2c 速度為 100

但我們想要給 i2c1 降為10,這樣似乎還需要改變clock之類的,請問我該如何修改呢?

以下為 board.c:

    const struct dpll_params *get_dpll_ddr_params(void)
{
    struct am335x_baseboard_id header;

    enable_i2c0_pin_mux();
    i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);

}

以下為 omap24xx_i2c.c

   static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
{

          else {
        /* Standard and fast speed */
        fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);

        fsscll -= I2C_FASTSPEED_SCLL_TRIM;
        fssclh -= I2C_FASTSPEED_SCLH_TRIM;
        if (((fsscll < 0) || (fssclh < 0)) ||
            ((fsscll > 255) || (fssclh > 255))) {
            puts("Error : I2C initializing clock\n");
            return;
        }

        scll = (unsigned int)fsscll;
        sclh = (unsigned int)fssclh;
    }

}

  • 我已經成功將i2c_base 變成 I2C_BASE2 了,接下來就只剩如何在 u-boot 把 i2c 速度降為10。

  • 疑? 我發現就算我變成I2C_BASE2了,到u-boot 模式打 i2c dev,他出現 current bus is 0 ,如果我打 i2c dev 1 ,他會重開機,且還是出現 current bus is 0

    所以我要怎麼將 i2c1 降速呢?

    謝謝。

  • 你是要修改采样时钟吗?建议你先理清这个时钟的配置过程,然后明确每一步的配置在代码中是怎样实现的,这样比较容易找到问题。

    就像这个I2C的时钟配置,一般来说,都会从PRCM里面取一个clock源,然后在I2C模块内部有个分频器,能够进行分频,从而得到最终的采样时钟,如果你很明确原始的时钟频率和你想要的数值,那可以直接尝试修改在I2C模块内部的分频值,看是否能配到你想要的频率。在TRM手册的21.4.1 i2c registers里面,地址偏移量为B0的寄存器bit[7-0],应该就是这个分配值的配置。然后照着我上面说的思路,理清一下代码中是在哪里进行的配置,修改测试就好了。

  • 這類問題我已解決了,我發現我使用的 u-boot 不是 EZSDK ,重新移植後已解決遭遇的問題不用調i2c了,謝謝。

  • Hi Ti

    我又回到老問題了,在 u-boot 下 i2c dev 1  & i2c probe, 它沒掃到 TCA6416A (0x20) 這顆IC,我們強烈懷疑,I2C需要降速成 10000Hz (現階段為100000Hz),它才能掃到。

    你們曾建議我要修改時鐘頻率,我想釐清一下,你們說的時鐘頻率,是我問的速度嗎還是另有所指?

    /* Only handle standard, fast and high speeds */
        if ((speed != OMAP_I2C_STANDARD) &&
            (speed != OMAP_I2C_FAST_MODE) &&
            (speed != OMAP_I2C_HIGH_SPEED)) {
            printf("Error : I2C unsupported speed %d\n", speed);
            return;
        }

        psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;    <----- 是這個嗎?    謝謝。
        psc -= 1;

  •  i2c dev 1  和i2c probe这个应该是在Linux kernel下的驱动概念而不是u-boot下吧,我们EZSDK默认的I2C工作频率是100K,请问您是在EZSDK没做修改的情况下调通的么?

    100K的速率应该是能够识别到I2C设备的

  • Hi Jian

    我的確是在 u-boot (EZSDK6)下的

    U-Boot# i2c dev 1
    Setting bus to 1
    U-Boot# i2c probe
    Valid chip addresses: 2D 50
    U-Boot#

    因為我們的 device 都在 i2c1 上,所以我在 u-boot 有修改,在 u-boot/board/ti/am335x/board.c

    /* Initalize the board header */
    -       enable_i2c0_pin_mux();
    +       enable_i2c1_pin_mux();
    +       i2c_set_bus_num(1);
            i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);

    也在 u-boot/board/ti/am335x/mux.c

    +void enable_i2c1_pin_mux(void)
    +{
    +       configure_module_pin_mux(i2c1_pin_mux);
    +}

    在 u-boot/board/ti/am335x/board.h

    +void enable_i2c1_pin_mux(void);

    100K 的速率的確是能識別到設備,因為我們有其他客戶要求我們做硬體,它們的軟體有遇到 i2c 不穩的狀況,所以在 x-loader or u-boot 有將他降速,再恢復到100K也解決了不穩問題,且它們的軟體可以識別到0X20,所以我們懷疑也必須做到它們那樣,才可以識別到 0X20這設備。

    謝謝。

  • Hello TI

    我照了 Steven 的提示,去查看了 u-boot/dirvers/i2c/omap24xx_i2c.c 的 i2c_init()

    印出一些數值

    I2C_INTERNAL_SAMPLING_CLK is 12000000

    speed is 100k

    fsscll is 54

    fssclh is 54

    I2C_IP_CLK=48000000

    psc=3

    可能是要我依照上面數值,用 writew() 寫入 rigister,但是我不知道 10K 的時鐘頻率的 fsscll fssclh值 該是多少和如何使用 writew,懇請提示,謝謝。

  • Hi TI

    我將 writew(/*psc*/89, &i2c_base->psc);   用示波器量i2c速度有變慢,但仍然無法讀到 0x20(TCA6416A),請問我哪裡還可以去確認呢? 謝謝。

  • 这里PSC寄存器的含义是一个分频数值,参考I2C寄存器章节的21.4.1.22,实际分频值为PSC+1.

    你上面的改动,把PSC由3改成了89,其他的没有改变的话,那么输出的频率原先因为CLK/4, 现在变成了CLK/90,变成了原来的22.5分之一。原来如果是100K的话,现在4.44K左右。你可以用示波器测一下,看看推断是否正确。

    如果上面的结果没有问题,想改变为10K的话,则需要得到的时钟为CLK/40,那么PSC的值应该设置为39。

  • Hi Steven

    謝謝你,我大部分速度都試過了。

    我放棄在 u-boot 掃 0x20,現在試著在 kernel 底下,檢查了這顆 IC 的 IRQ 和 reset pin 腳,我們是 starter kit 的客製板,這是我的 patch

    --- a/arch/arm/mach-omap2/board-am335xevm.c
    +++ b/arch/arm/mach-omap2/board-am335xevm.c
    @@ -87,6 +87,7 @@
     #define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5
     #define AR8051_RGMII_TX_CLK_DLY                BIT(8)
     #define AR8035_PHY_ID 0x4dd072
    +#define TCA6416A_IRQ                   GPIO_TO_PIN(0,20)       
     
     static const struct display_panel disp_panel = {
            WVGA,
    @@ -2651,6 +2652,10 @@ static struct i2c_board_info /*__initdata*/ a
                    I2C_BOARD_INFO("tps65910", TPS65910_I2C_ID1),
                    .platform_data  = &am335x_tps65910_info,
            },
    +       {
    +               I2C_BOARD_INFO("tca6416-keypad", 0x20),
    +               .irq = OMAP_GPIO_IRQ(TCA6416A_IRQ),
    +       },
            /*{
                    I2C_BOARD_INFO("tlv320aic3x", 0x1b),
            },*/
    static void __init am335x_evm_init(void)
     {
    +       int ret;
            am33xx_cpuidle_init();
            am33xx_mux_init(board_mux);
            omap_serial_init();
    +       ret = gpio_request(20, "TCA6416A_IRQ");
    +       if (ret) {
    +               pr_err("-----------------------irq: %d\n", ret);
    +       }
            am335x_evm_i2c_init();
            omap_sdrc_init(NULL, NULL);
            usb_musb_init(&musb_board_data);

    也在 /sys/kernel/debug/      cat gpio

    GPIOs 0-31, gpio:
     gpio-20  (TCA6416A_IRQ        ) in  hi

    GPIOs 32-63, gpio:
     gpio-36  (am335x:EVM_SK:usr0  ) out lo
     gpio-37  (am335x:EVM_SK:usr1  ) out lo
     gpio-38  (am335x:EVM_SK:heartb) out lo
     gpio-39  (am335x:EVM_SK:mmc0  ) out lo

    GPIOs 64-95, gpio:

    GPIOs 96-127, gpio:
     gpio-104 (wlan_en             ) out lo
     gpio-117 (bt_en
                  ) out lo

    請問我這樣有錯誤嗎? 還是我還有哪裡可以確認? 謝謝。

  • 看你的驱动,你是要做一个I2C接口的键盘驱动吧,你的GPIO终端申请不用放在这个板级定义文件里的,可以直接放在I2C设备的probe()函数中的。

    我在我们SDK06的内核源代码中找到了你用的I2C键盘设备驱动,在\drivers\input\keyboard\tca6416-keypad.c,里面的tca6416_keypad_probe()已经登记了GPIO的中断了。

    对你这个应用我还是蛮感兴趣的,有什么进展及时更新啊

     

  • Hi Jian

    一切應該只是個誤會,我們目地是希望藉由 TCA6416A 增加GPIO還有用來控制output,將SPE339E這顆 IC 能夠用來把RS232 / RS422/RS485 做切換。

    我是個新手,在 board-am335xevm.c 中註冊的 i2c dirver 名字,是我以為的,後來討論結果是要選擇 pca953x 才是

    {
            I2C_BOARD_INFO("pca953x", 0x20),
            .irq = OMAP_GPIO_IRQ(TCA6416A_IRQ),
     },

    但目前 tca6416a 在 sdk6 讀不到就是了。

    順便想討教一下,一般 driver 中的 probe 函數,目地主要是做甚麼的? 能否簡單為我說明呢? 謝謝。

  • 请问实际使用的是TCA6416A这颗芯片么?如果TCA6416A用于扩展IO,具体的用法是什么呢?还需要IO中断么?

    probe()函数是在设备初始化的时候会调用的,主要是把驱动和文件系统的节点对应起来。

  • Hi Jian

    具體用法我還不清楚

    是不是擴展出來的 GPIO 不當作中斷 IO 的話,就不需要用到 irq ?  因為我 kernel 用 i2c-tool 掃不到 TCA6416A,但卻可以 dump 出 register 和 改 register 值

    。 所以我想直接用 i2c tool 來控制。這樣是不是就不需要用到 TCA6416A 的 driver ,也就不用設定 irq 了? 謝謝。

  • 能share下TCA6416A和主芯片连接的原理图么?一般是TCA6416A的IO有任何输入响应,会通过中断发给AM335x,然后通过I2C读取TCA6416A内部寄存器,再上报给Linux输入子系统。

    如果是做扩展IO,完全就是输出了,就应该不用中断了。

    你需要tca6416-keypad.c对照修改tca6416_keypad_probe()函数,来实现自己的功能。

  • Hi Jian

    以前有發生過我截部分電路圖放在這邊,被客戶質詢洩漏的疑慮。若你不介意,請給我您的 email 帳號,我寄給你。

    目前,我使用 sdk6 u-boot/drivers/ i2c/omap24xx_i2c.c 讀不到 i2c 上的 TCA6416A,換成 sdk7 的 omap24xx_i2c.c就可以讀到了,進入到 kernel,仍無法讀到TCA6416A,因為 kernel sdk6和sdk7架構差太大,不能單單只 replace i2c dirver,現在很困擾阿,請問有甚麼建義嗎?

    謝謝

  • 对于kernel,如果device和driver匹配正确,可以在probe()函数里面加一段I2C读写测试函数。

    我的邮箱:weeklyhao@sohu.com

  • Hi Jian

    我已經寄了。煩請確認。

    另外我在 user level 下 i2cdetect -y -r 2  不能偵測到 0x20,但可以 dump 出 0x20 的 registers

    如果我一修改 register ,再 i2cdetect 就可以偵測到 0x20。這甚麼原因呢?

    這是我在 kernel 下的 patch , 為TCA 註冊 i2c driver,但仍然讀取不到。請問我還該修改甚麼呢? 謝謝

    請忽略 option.c 的修改

  • 我看你的原理图用的是TCA6418,但是驱动是加入了CONFIG_GPIO_PCA953X和CONFIG_KEYBOARD_TCA6416,你是想用gpio-pca953x.c来实现吧?

    如果是gpio-pca953x.c,那么board-am335xevm.c中应加入:

    {
      I2C_BOARD_INFO("tca6416", 0x20),
    },

    然后在pca953x_probe()函数中加一段打印看看程序有没有执行到这里

  • Hi Jian

    很抱歉忘了告知,我前天已經解決了。

    {
      I2C_BOARD_INFO("tca6416", 0x20)
    ,

      .platform_data = &am3517evm_gpio_expander_info_0,   <--我還有加上這個
    },


    謝謝。

  • 最终是基于gpio-pca953x.c实现的扩展GPIO功能么?有没有对gpio-pca953x.c做什么改动呢?

  • 是,是擴展GPIO功能,擴展16根。 我沒有對 gpio-pca953x 做任何變動。