[Armadillo:03967] Re: armadillo-500 sysfs経由でI2Cドライバ制御
日本電子システムテクノロジー/高木
email@hidden
2009年 1月 26日 (月) 17:51:40 JST
高木です。
お世話になっています。
> 木原 です。
> お世話になっています。
>
> 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 メーリングリストの案内