[Armadillo:03971] Re: armadillo-500 sysfs経由でI2Cドライバ制御
日本電子システムテクノロジー/高木
email@hidden
2009年 1月 26日 (月) 18:49:29 JST
高木です
お世話になっております。
> 木原 です。
> お世話になっています。
>
> 早々のご返信ありがとうございます。
>
>> コードは問題なさそうに見えますが・・・
>
> なにか欠けているようには思えないのですが・・・。
> 以前、read()とwrite()だけでデバドラをつくったときには、
> マルチプレクスサによる切り替え(Functionalモード:I2C1にする)
> を行ってから、通信処理を行っていましたが、
> こういった処理はsysfsが勝手にやってくれるんですよね?
Armadillo5x0付属のI2Cドライバを組込んでいれば初期化されているはずです。
i2c_armadillo5x0_probe関数内でgpio_i2c_active(pdev->id);が呼び出されています。
組み込んでいない場合は初期化されていないと思いますので
クロックの設定などもする必要があると思います。
>> まだ試していないようでしたら、カーネルコンフィグでI2Cのデバックを
>> 有効にしてみてはどうでしょうか
>
> トライしてみます。
>
> 以上
>
>
> ----- Original Message ----- From: "日本電子システムテクノロジー/高木"
> <email@hidden>
> To: "Armadillo series general discussion list"
> <email@hidden>
> Sent: Monday, January 26, 2009 5:51 PM
> Subject: [Armadillo:03967] Re: armadillo-500 sysfs経由でI2Cドライバ制御
>
>
>> 高木です。
>> お世話になっています。
>>
>>> 木原 です。
>>> お世話になっています。
>>>
>>> i2c_transfer()のソースを読みましたが、
>>> 弊社のセンサデバイスの仕様に従うと、
>>> i2c通信で、任意のレジスタのデータ受信を行う場合には
>>> ご教示いただいた処理で正常に受信が行われるように
>>> 思われます。
>>>
>>> /* buf[0]の内容を表示 */
>>> printk("RxData msgs[1].buf[0]=%x\n", buf[0]);
>>>
>>> しかし、実際テストしてみると、buf[0]は0xffになっていました。
>>
>> i2c_armadillo5x0_xferを読むと、
>> 受信動作時はI2Cデータレジスタの値をバッファに格納しています。
>> 0xffという固定の値を格納するような操作は見当たりませんし、
>> buf[0]は0x0で初期化しているので
>> 受信したデータが0xffだったのではないかと思います。
>>
>>> ハードウェア的要因を疑ってみたのですが、
>>> 以前、Linux標準関数を用いずにioremap(),write(),read()を
>>> 用いてi2c通信デバイスドライバを作成したことがあり、
>>> このデバドラを用いて、任意のレジスタへの書き込みと読み込みが
>>> できるか調べたのですが、両方とも正常に行われました。
>>> テスト環境に問題はないようです。
>>>
>>> i2c_probe()に成功はしているのですが、
>>> 本当に検出できているのか現在調査中です。
>>> ・・・なにが悪いのかさっぱり検討がつきません。
>>>
>>> 下記に現在用いているデバイスドライバを示しました。
>>
>> コードは問題なさそうに見えますが・・・
>> まだ試していないようでしたら、カーネルコンフィグでI2Cのデバックを
>> 有効にしてみてはどうでしょうか?
>>
>> probeやsend、recvなど実際に送っているデータなどが表示されるので
>> 何かヒントが見つかるかもしれません。
>>
>>
>>
>>
>>> #include <linux/module.h>
>>> #include <linux/kernel.h>
>>> #include <linux/fs.h>
>>> #include <linux/ioport.h>
>>> #include <asm/io.h>
>>> #include <linux/cdev.h>
>>> #include <asm/arch/mx31_pins.h>
>>> #include <asm/arch/gpio.h>
>>> #include <asm/uaccess.h>
>>>
>>> #define __KERNEL_SYSCALLS__
>>>
>>> static char* msg = "module [ECS_iMX31.ko]";
>>>
>>> #include <linux/moduleparam.h>
>>> #include <linux/platform_device.h>
>>> #include <linux/slab.h>
>>> #include <linux/i2c.h>
>>>
>>> #define DRIVER_NAME "i2ctest"
>>> #define REVISION "Rev.1 (2007/--/--)"
>>> #define AUTHOR "Atmark Techno, Inc."
>>> #define DESCRIPTION "TI TLV320AIC Audio codec driver"
>>>
>>> //#define DEBUG
>>> #undef DEBUG
>>> #if defined(DEBUG)
>>> #define DEBUG_FUNC() printk(DRIVER_NAME ": %s()\n",
>>> __FUNCTION__)
>>> #define DEBUG_INFO(args...) printk(DRIVER_NAME ": " args)
>>> #else
>>> #define DEBUG_FUNC()
>>> #define DEBUG_INFO(args...)
>>> #endif
>>> #define PRINT_INFO(args...) printk(KERN_INFO DRIVER_NAME ": " args)
>>> #define PRINT_DEBUG(args...) printk(KERN_DEBUG DRIVER_NAME ": " args)
>>> #define PRINT_ERR(args...) printk(KERN_ERR DRIVER_NAME ": " args)
>>>
>>> static int i2ctest_attach(struct i2c_adapter *adap);
>>> static int i2ctest_detach(struct i2c_client *client);
>>>
>>> static struct i2c_driver test_i2c_driver = {
>>> .driver = {
>>> .owner = THIS_MODULE,
>>> .name = DRIVER_NAME,
>>> },
>>> .id = 102,
>>> .attach_adapter = i2ctest_attach,
>>> .detach_client = i2ctest_detach,
>>> };
>>>
>>> static struct i2c_client test_i2c_client =
>>> {
>>> .name = "TEST I2C dev",
>>> .driver = &test_i2c_driver,
>>> };
>>>
>>> static unsigned short normal_i2c[] =
>>> {
>>> 0x1c, // 0x38/2=0x1c
>>> I2C_CLIENT_END
>>> };
>>>
>>> I2C_CLIENT_INSMOD;
>>>
>>> static DECLARE_MUTEX(mutex);
>>>
>>> #define ID_I2CTEST 102
>>>
>>> int
>>> i2ctest_RxData(char *rxData, int length)
>>> {
>>> int ret;
>>> u8 buf[2];
>>> struct i2c_msg msgs[2];
>>>
>>> buf[0] = 0;
>>> buf[1] = 0;
>>>
>>> msgs[0].addr = test_i2c_client.addr;
>>> msgs[0].len = 1;
>>> msgs[0].buf = rxData;
>>> msgs[0].flags = 0;
>>>
>>> msgs[1].addr = test_i2c_client.addr;
>>> msgs[1].len = 1;
>>> msgs[1].buf = buf;
>>> msgs[1].flags = I2C_M_RD ;
>>>
>>> ret = i2c_transfer(test_i2c_client.adapter, &msgs[0], 2);
>>>
>>> if(ret < 0){
>>> printk("i2c_transfer failed!!!\n");
>>> }
>>>
>>> printk("Ret = %d\n",ret);
>>> printk("RxData buf[0]=%x\n", buf[0]);
>>> printk("RxData msg[1].buf[0]=%x\n", msgs[1].buf[0]);
>>>
>>> return ret;
>>> }
>>>
>>> int
>>> i2ctest_TxData(char *txData, int length)
>>> {
>>> int ret;
>>> u8 buf[2];
>>> struct i2c_msg msgs[2];
>>>
>>> msgs[0].addr = test_i2c_client.addr;
>>> msgs[0].flags = 0;
>>> msgs[0].len = length;
>>> msgs[0].buf = txData;
>>>
>>> ret = i2c_transfer(test_i2c_client.adapter, msgs, 1);
>>>
>>> if(ret == 1){
>>> printk("TxData succedded!!!\n");
>>> }else if (ret >= 0){
>>> ret = -1;
>>> printk("TxData failed!!!\n");
>>> }
>>>
>>> return ret;
>>> }
>>>
>>>
>>> static int
>>> i2ctest_detect_client(struct i2c_adapter *adapter, int address, int
>>> kind)
>>> {
>>> int ret;
>>>
>>> test_i2c_client.adapter = adapter;
>>> test_i2c_client.addr = address;
>>>
>>> DEBUG_FUNC();
>>>
>>> printk("i2ctest_detect_client is called\n");
>>>
>>> ret = i2c_attach_client(&test_i2c_client);
>>> if (ret) {
>>> test_i2c_client.adapter = NULL;
>>> printk("i2c_detect_client() is failed!!!\n");
>>> return ret;
>>> }
>>>
>>> printk("i2c_detect_client() is succeeded!!!\n");
>>>
>>> return 0;
>>> }
>>>
>>> static int
>>> i2ctest_attach(struct i2c_adapter *adap)
>>> {
>>> int ret;
>>> char tx[2];
>>> char rx[2];
>>>
>>> rx[0]=0;
>>> rx[1]=0;
>>>
>>> DEBUG_FUNC();
>>>
>>> printk("i2ctest_attach is called\n");
>>>
>>> ret = i2c_probe(adap, &addr_data, &i2ctest_detect_client);
>>> printk("i2c_probe=%d\n", ret);
>>>
>>> // test
>>> tx[0] = 0xE1;
>>> tx[1] = 0x23;
>>> i2ctest_TxData(tx, 2);
>>>
>>> rx[0] = 0xE1;
>>> i2ctest_RxData(rx, 1);
>>>
>>> return ret;
>>> }
>>>
>>> static int
>>> i2ctest_detach(struct i2c_client *client)
>>> {
>>> int ret;
>>>
>>> DEBUG_FUNC();
>>> printk("kihara i2ctest_detach is called\n");
>>>
>>> ret = i2c_detach_client(client);
>>>
>>> if(ret)
>>> return ret;
>>>
>>> return 0;
>>> }
>>>
>>> static int __init
>>> i2ctest_init(void)
>>> {
>>> int ret;
>>>
>>> DEBUG_FUNC();
>>> printk("kihara i2ctest_init is called\n");
>>>
>>> ret = i2c_add_driver(&test_i2c_driver);
>>> if (ret) {
>>> PRINT_ERR("kihara Unable to register %s driver.\n", DRIVER_NAME);
>>> return ret;
>>> }
>>>
>>> PRINT_INFO(DESCRIPTION " [" REVISION "], (C) 2007 " AUTHOR "\n");
>>>
>>> return 0;
>>> }
>>>
>>> static void __exit
>>> i2ctest_exit(void)
>>> {
>>> DEBUG_FUNC();
>>> i2c_del_driver(&test_i2c_driver);
>>> }
>>>
>>> module_init(i2ctest_init);
>>> module_exit(i2ctest_exit);
>>>
>>> MODULE_AUTHOR(AUTHOR);
>>> MODULE_DESCRIPTION(DESCRIPTION);
>>> MODULE_LICENSE("GPL");
>>>
>>>
>>> 以上
>>>
>>>
>>
>> _______________________________________________
>> armadillo mailing list
>> email@hidden
>> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
>>
>
> _______________________________________________
> armadillo mailing list
> email@hidden
> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
>
>
armadillo メーリングリストの案内