2318|0

71

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

从2.6.20升级到2.6.28遇到的I2C错误 [复制链接]

我在进行把2.6.20内核中的camera模块移植到2.6.28内核过程中发现了以下问题,
该代码在2.6.20内核中可以正常运行。

在2.6.28内核中I2C设备驱动的编写方式是不是发生了改变?或者有什么新的要求?
请大大们不吝赐教。

部分代码如下:
=============================================================
ov2640_hw.c
=============================================================
#define I2C_DRIVERID_OV2640   (0)
#define        OV2640_ADDRESS        (0x60>>1)

struct i2c_driver ov2640_driver  =
{
        .driver = {
                .name        = "ov2640 i2c client driver",
        },
        .id                = I2C_DRIVERID_OV2640,
        .attach_adapter        = &i2c_ov2640_attach_adapter,
        .detach_client        = &i2c_ov2640_detach_client,
};

/* Unique ID allocation */
static struct i2c_client *g_client;
static unsigned short normal_i2c[] = {OV2640_ADDRESS, I2C_CLIENT_END };
I2C_CLIENT_INSMOD_1(OV2640);

static int i2c_ov2640_attach_adapter(struct i2c_adapter *adap)
{
        return i2c_probe(adap,&addr_data,i2c_ov2640_detect_client);
}

int i2c_ov2640_init(void)
{
        int ret;

        if ( (ret = i2c_add_driver(&ov2640_driver)) ) {
                printk(KERN_ERR "ov2640: Driver registration failed,"
                        "module not inserted.\n");
                return ret;
        }  

        return 0;
}

void i2c_ov2640_exit(void)
{
        i2c_del_driver(&ov2640_driver);
}

======================================================
i2c_core.c
======================================================
/* ----------------------------------------------------
* the i2c address scanning function
* Will not work for 10-bit addresses!
* ----------------------------------------------------
*/
static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind,
                             int (*found_proc) (struct i2c_adapter *, int, int))
{
        int err;

        /* Make sure the address is valid */
        if (addr < 0x03 || addr > 0x77) {
                dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
                         addr);
                return -EINVAL;
        }

        /* Skip if already in use */
        if (i2c_check_addr(adapter, addr))
                return 0;

        /* Make sure there is something at this address, unless forced */
        if (kind < 0) {
                if (i2c_smbus_xfer(adapter, addr, 0, 0, 0,
                                   I2C_SMBUS_QUICK, NULL) < 0)
                        return 0;

                /* prevent 24RF08 corruption */
                if ((addr & ~0x0f) == 0x50)
                        i2c_smbus_xfer(adapter, addr, 0, 0, 0,
                                       I2C_SMBUS_QUICK, NULL);
        }

        /* Finally call the custom detection function */
        err = found_proc(adapter, addr, kind);
        /* -ENODEV can be returned if there is a chip at the given address
           but it isn't supported by this chip driver. We catch it here as
           this isn't an error. */
        if (err == -ENODEV)
                err = 0;

        if (err)
                dev_warn(&adapter->dev, "Client creation failed at 0x%x (%d)\n",
                         addr, err);
        return err;
}


int i2c_probe(struct i2c_adapter *adapter,
              const struct i2c_client_address_data *address_data,
              int (*found_proc) (struct i2c_adapter *, int, int))
{
        int i, err;
        int adap_id = i2c_adapter_id(adapter);

        /* Force entries are done first, and are not affected by ignore
           entries */
        if (address_data->forces) {
                const unsigned short * const *forces = address_data->forces;
                int kind;

                for (kind = 0; forces[kind]; kind++) {
                        for (i = 0; forces[kind] != I2C_CLIENT_END;
                             i += 2) {
                                if (forces[kind] == adap_id
                                 || forces[kind] == ANY_I2C_BUS) {
                                        dev_dbg(&adapter->dev, "found force "
                                                "parameter for adapter %d, "
                                                "addr 0x%02x, kind %d\n",
                                                adap_id, forces[kind][i + 1],
                                                kind);
                                        err = i2c_probe_address(adapter,
                                                forces[kind][i + 1],
                                                kind, found_proc);
                                        if (err)
                                                return err;
                                }
                        }
                }
        }

        /* Stop here if we can't use SMBUS_QUICK */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
                if (address_data->probe[0] == I2C_CLIENT_END
                 && address_data->normal_i2c[0] == I2C_CLIENT_END)
                        return 0;

                dev_dbg(&adapter->dev, "SMBus Quick command not supported, "
                        "can't probe for chips\n");
                return -EOPNOTSUPP;
        }

        /* Probe entries are done second, and are not affected by ignore
           entries either */
        for (i = 0; address_data->probe != I2C_CLIENT_END; i += 2) {
                if (address_data->probe == adap_id
                 || address_data->probe == ANY_I2C_BUS) {
                        dev_dbg(&adapter->dev, "found probe parameter for "
                                "adapter %d, addr 0x%02x\n", adap_id,
                                address_data->probe[i + 1]);
                        err = i2c_probe_address(adapter,
                                                address_data->probe[i + 1],
                                                -1, found_proc);
                        if (err)
                                return err;
                }
        }

        /* Normal entries are done last, unless shadowed by an ignore entry */
        for (i = 0; address_data->normal_i2c != I2C_CLIENT_END; i += 1) {
                int j, ignore;

                ignore = 0;
                for (j = 0; address_data->ignore[j] != I2C_CLIENT_END;
                     j += 2) {
                        if ((address_data->ignore[j] == adap_id ||
                             address_data->ignore[j] == ANY_I2C_BUS)
                         && address_data->ignore[j + 1]
                            == address_data->normal_i2c) {
                                dev_dbg(&adapter->dev, "found ignore "
                                        "parameter for adapter %d, "
                                        "addr 0x%02x\n", adap_id,
                                        address_data->ignore[j + 1]);
                                ignore = 1;
                                break;
                        }
                }
                if (ignore)
                        continue;

                dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
                        "addr 0x%02x\n", adap_id,
                        address_data->normal_i2c);
                err = i2c_probe_address(adapter, address_data->normal_i2c,
                                        -1, found_proc);
                if (err)
                        return err;
        }

        return 0;
}
===========================================================

我发现,在执行到i2c_probe的时候出现以下问题:
i2c: error: exhausted retries
i2c: error: exhausted retries
i2c: msg_num: 0 msg_idx: -2000 msg_ptr: 0
i2c: msg_num: 0 msg_idx: -2000 msg_ptr: 0
i2c: ICR: 000007e0 ISR: 00000002
i2c: log: i2c: ICR: 000007e0 ISR: 00000002

经定位发现是在执行到以下语句出现的错误
        if (i2c_smbus_xfer(adapter, addr, 0, 0, 0,
                                   I2C_SMBUS_QUICK, NULL) < 0)

点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表