现在加的一款camera gc2015和我们原先的ov2655的IIC地址一样,
但是id是不一样的,gc2015和ov2655实际只会贴一个。如果同时打开这两个配置,实际装的是gc2015,则一进camera
就报下面的错误:
10-17 08:30:17.409: ERROR/CameraHolder(588): modes supported for camera id 0 = 1
10-17 08:30:18.569: ERROR/CAM_FD(83): cam_conf open driver failed: device =/dev/msm_camera/config0: I/O error!
10-17 08:30:18.569: ERROR/CAM_FD(83): cam_conf: CAMERA_EXIT
10-17 08:30:18.569: ERROR/mm-camera(83): mm_camera_exec: config thread launch failed
10-17 08:30:18.569: ERROR/QualcommCameraHardware(83): startCamera: mm_camera_exec failed:
10-17 08:30:18.579: ERROR/QualcommCameraHardware(83): startCamera X: could not get snapshot sizes
10-17 08:30:18.579: ERROR/QualcommCameraHardware(83): createInstance: startCamera failed!
10-17 08:30:18.589: ERROR/CameraService(83): Fail to open camera hardware (id=0)
10-17 08:30:18.599: ERROR/CameraHolder(588): fail to connect Camera怀疑我们的驱动有问题
即使安装的是gc2015,但是文件系统下还是有ov2655的设备结点:
/sys/devices/platform/msm_camera_ov2655.0
/sys/devices/platform/msm_camera_gc2015.0/sys/bus/platform/devices/msm_camera_ov2655.0
/sys/bus/platform/devices/msm_camera_gc2015.0/sys/bus/platform/drivers/msm_camera_gc2015
/sys/bus/platform/drivers/msm_camera_ov2655
/sys/bus/platform/drivers/msm_camera_ov2655/msm_camera_ov2655.0初步想法是读到id不对时,就把相应的I2C的device和driver,camera的device和driver
删除,不知这思路是否正确?(虽然当前只有一款camera,我们所有兼容的camera都有对应的device和driver,可能驱动一开始搭的不是很严谨)

解决方案 »

  1.   

    这个明显是底层的驱动出问题了,device的I/O error
      

  2.   

    现在问题定位在board初始化时i2c
    的device创建失败导致:
    <3>[    0.240863] i2c i2c-0: Failed to register i2c client gc2015 at 0x30 (-16)<3>[    0.240883] i2c i2c-0: Can't create device at 0x30board文件中
    I2C_BOARD_INFO("ov2655", 0x30),
    I2C_BOARD_INFO("gc2015", 0x30), //0-0030
    好像linux中无法注册地址相同的I2C设备,上面的只有第一个可以注册,第二个无法注册。
    但是我这两个设备是不会同时存在系统上的,所以即使I2C地址一样,也不会冲突的。但是这是再board初始化时创建的device,无法probe中检测是否成功,所以没有办法删除其中的一个设备。有没遇到这个问题的?如何做自适应?

      

  3.   

    i2c是地址是统一编号的,不知道为什么会出现两个相同的slave addr,这两个设备因为不会同时出现在系统中,所以没有出现的那个,你就不用注册了,直接在代码中用/**/注销掉就可了,例如你要用ov2655,改成.
    I2C_BOARD_INFO("ov2655", 0x30);
    /*(I2C_BOARD_INFO("gc2015", 0x30);(你那怎么会是,)*/
      

  4.   

    1.关于I2C地址:
    一共就7it,这个地址是否是IC厂家随便定义的,还是有组织统一分配?
    2.要做设备的自适应,即使要用ov2655,还得保证是可以兼容gc2005的。
    3.I2C_BOARD_INFO这个地方是linux的I2C
    系统不让注册地址相同的的2个device,会 i2c_check_addr_busy检查是否此地址已被注册,若已经
    被注册,则注册失败。在想是否可以在驱动中共用此IIC DEVICE。。
      

  5.   

    1.我记的不是太清了,你可以查查这方面的资料,应该是有一个组织分的。
    2.不能用相同slave addr的设备,这里只能加一个,要想自适应只有改驱动了,找你们那边的软件工程师想办法改一下,应该不会太难。
    3.这就是不能用相同地址的原因。
      

  6.   

    应该是有组织分配的。
    我觉得不只是要改软件的问题,如果两个相同地址的设备都挂在iic总线上,单靠软件可能无法解决
      

  7.   

    如果是组织分配的,怎会重了呢,而且就7bit,就256个地址可以分?!
    已经说了是自适应,两个设备不会同时挂在总线上的!>>>>>>>不能用相同slave addr的设备,这里只能加一个,要想自适应只有改驱动了,找你们那边的软件工程师想办法改一下,应该不会太难。
    我就是那个软件工程师,就想问问驱动上怎么改,软件上肯定可以改的,两个设备又不会同时存在!
      

  8.   

    确实是有些问题没想过,我就谈谈我自己的想法。
    1.为什么会重复?
    刚才我查了一下你的这两个器件,ov2655和gc2015两个都是图像传感器,我想这应该不是巧合,这个什么组织会不会是按设备的功能进行编址的,毕竟在同一个硬件方案中出现有相同功能设备的可能性要小一些。
    2.驱动改写,要是我会怎么作?
    首先,I2C_BOARD_INFO("camera", 0x30);或者只是写一个platform_driver
    其次在pobe函数中想办法判断出到底是ov2655还是gc2015(这个应该是工作的重点,怎么能简单的判断出,又能比较充分的利用已有的代码),再加载他们不同的驱动。
      

  9.   

    谢谢yanjiashang, 已经解决,基本就是你说的方案。
    在board中只注册一个I2C device,在ov2655的驱动和gc2015的驱动中
    id_table都写同一个ID,不论贴的哪个,只要driver匹配device成功了,下一个driver肯定失败,如此便可自适应了。疑惑的是,测试了一下,driver匹配device时竟然是匹配id,而不是driver的name,如下:
    board中:
    I2C_BOARD_INFO("pca9534", 0x30);
    驱动文件中:
    static struct i2c_driver pca953x_driver = {
                    .driver = {
                            .name= "pca953x",//这个name竟然不会加入匹配规则????
                            },
                            .probe= pca953x_probe, //当有i2c_client和i2c_driver匹配时调用
                            .remove= pca953x_remove,//注销时调用
                            .id_table= pca953x_id,//匹配规则
            }; 
    static const struct i2c_device_id pca953x_id[] = {
                    { "pca9534", 8, },
                    { "pca9535", 16, },
       
            };匹配是i2c_driver 的id_table(i2c_device_id)而非driver.name和i2c_board_info 的type
     struct i2c_board_info {
             char            type[I2C_NAME_SIZE];
             unsigned short  flag
            unsigned short  addr;
             ...
    }
    一般是device的name和driver的name作为匹配规则,不知这个I2C的drvier.name还有何意义?
      

  10.   

    可以参考:
    i2c中i2c_add_driver中的一系列问题
      

  11.   

    能详细说一下吗?比如我现在有两个p-sensor设备,RXXX和TXXX,都用0x39为IIC地址,那么我在board文件中应该写什么?
    是I2C_BOARD_INFO("p-sensor", 0x39)吗?还是
    #ifdef _RXXX_
    I2C_BOARD_INFO(RXXX_NAME, 0x39)
    #else
    I2C_BOARD_INFO(TXXX_NAME, 0x39)
    #endif那么在驱动程序中应该怎么写?
    static struct i2c_driver rxxx_driver = {
        .driver = {                      /* device driver model driver */
            .name = RXXX_NAME,
        },
        .probe    = rxxx_probe,        /* callback for device binding */
        .remove   = rxxx_remove,       /* callback for device unbinding */
        .id_table = rxxx_id,           /* list of I2C devices supported by this driver */
    };
    static const struct i2c_device_id ps_als_id[] = {
        { RXXX_NAME, 0 }, 
        { }
    };

    static struct i2c_driver txxx_driver = {
        .driver = {                      /* device driver model driver */
            .name = TXXX_NAME,
        },
        .probe    = txxx_probe,        /* callback for device binding */
        .remove   = txxx_remove,       /* callback for device unbinding */
        .id_table = txxx_id,           /* list of I2C devices supported by this driver */
    };
    static const struct i2c_device_id ps_als_id[] = {
        { TXXX_NAME, 0 }, 
        { }
    };
    这样吗?
      

  12.   

    在board文件中是I2C_BOARD_INFO("p-sensor", 0x39)
    在驱动程序中TXXX_NAME,RXXX_NAME,都定义成"p-sensor"
      

  13.   


    多谢回复。那么这样系统在匹配的时候会匹配上哪个呢?
    比如我贴了TXXX的设备,是否当系统调用RXXX的probe会导致失败,然后自动识别成TXXX的设备呢?