Skip to contentSkip to conversation

i2c: virtual i2c adapter support

PATCH Felix Radensky 2 participants 5 messages Oct 26, 2008 – Oct 27, 2008 2 messages not in the archive I2C subsystem host drivers

lore
Share & tools
lore
#0 lore raw

Hi, Rodolfo

I've tried your patches with linux-2.6.27 kernel running on custom board with 460EX PowerPC. This board has two i2c buses and pca9548 switch on bus 0.

The 954x driver (compiled into the kernel) creates 8 virtual buses just fine. However devices behind the mux are not detected if I use the "recommended" way of doing things.

I have RTC (ds1338) and temp sensor (ds1625) on mux channel 4 (i.e virtual bus 6). What I did initially to add the following code to board init code:

struct board_i2c_info {
    int bus;
    int addr;
    char *id;
};
static struct board_i2c_info board_i2c_devices[] = {
    /* Bus  Addr       ID  */
    {6,     0x68,    "ds1338"},
    {6,     0x49,    "ds1625"},
};

static int board_i2c_init(void)

{
    int i;

    for (i = 0; i < ARRAY_SIZE(board_i2c_devices); i++) {
        struct i2c_board_info info = {};

        info.irq = -1;
        info.addr = board_i2c_devices[i].addr;
        if (strlcpy(info.type, board_i2c_devices[i].id,
                I2C_NAME_SIZE) >= I2C_NAME_SIZE)
            return -ENOMEM;

        i2c_register_board_info(board_i2c_devices[i].bus, &info, 1);
    }
}

arch_initcall(board_i2c_init);

This code is invoked by kernel before i2c bus and mux detection, but, as I said, RTC and sensor are not identified.

If I invoke the following code after creation of virtual adapters, things start working, but I don't like this solution

static int board_i2c_init(void)

{
    int i;
   
    for (i = 0; i < ARRAY_SIZE(board_i2c_devices); i++) {
        struct i2c_board_info info = {};
        struct i2c_adapter *adap;
 
       info.irq = -1;
        info.addr = board_i2c_devices[i].addr;
        if (strlcpy(info.type, board_i2c_devices[i].id,
                I2C_NAME_SIZE) >= I2C_NAME_SIZE)
            return -ENOMEM;

        adap = i2c_get_adapter(board_i2c_devices[i].bus);
        i2c_new_device(adap, &info);
    }
}

My question is: how can I register board i2c devices behind the mux in board init code, and make them properly identified when relevant drivers are loaded.

Thanks a lot.

Felix.

_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c

A message that is not in the archive (sent off-list or not yet received): 4904E6F3.50609-L1vi/lXTdtvUXIAPrk8Z/[email protected]

#2 lore raw
Quoted 5 lines · Felix Radensky

Hi, Rodolfo

I've tried your patches with linux-2.6.27 kernel running on custom board with 460EX PowerPC. This board has two i2c buses and pca9548 switch on bus 0.

Please, consider thay my patch has been *not* accepted into main line due a mutex problem... :'(

Quoted 3 lines

My question is: how can I register board i2c devices behind the mux in board init code, and make them properly identified when relevant drivers are loaded.

I have just defined the i2c devices behind the mux as connected to the new virtual adapters:

static int wr1100_adap_ids[] = {
        2, 3,
};
static struct pca954x_platform_data wr1100_i2cmux_adap_ids = {
        .adap_ids       = wr1100_adap_ids,
        .len            = ARRAY_SIZE(wr1100_adap_ids),
};
static struct i2c_board_info __initdata wr1100_i2c_devices[] = {
        {
                I2C_BOARD_INFO("pca9540", 0x70),
                .platform_data = &wr1100_i2cmux_adap_ids,
        },
};
static struct i2c_board_info __initdata wr1100_i2c_mux_devices[] = {
        {
                I2C_BOARD_INFO("bq27200", 0x55),
        },
};

Then into machine startup code:

        i2c_register_board_info(0, wr1100_i2c_devices,
                                        ARRAY_SIZE(wr1100_i2c_devices));
        i2c_register_board_info(2, wr1100_i2c_mux_devices,
                                        ARRAY_SIZE(wr1100_i2c_mux_devices));
        i2c_register_board_info(3, wr1100_i2c_mux_devices,
                                        ARRAY_SIZE(wr1100_i2c_mux_devices));

Ciao,

Rodolfo

Signature · 4 lines
GNU/Linux Solutions                  e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected]
Linux Device Driver                          [email protected]
Embedded Systems                     phone:  +39 349 2432127
UNIX programming                     skype:  rodolfo.giometti

_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c

#3 lore raw

Hi, Rodolfo

Quoted 4 lines · Rodolfo Giometti
Quoted 2 lines · Felix Radensky

Hi, Rodolfo

Quoted 9 lines
Quoted 4 lines

I've tried your patches with linux-2.6.27 kernel running on custom board with 460EX PowerPC. This board has two i2c buses and pca9548 switch on bus 0.

Please, consider thay my patch has been *not* accepted into main line due a mutex problem... :'(

I didn't find any discussion on the mailing list. What mutex problem exactly ?

I find your patches very useful, and the concept of virtual buses very elegant.
Hopefully you can rework your patches and get them into mainline. I'm willing
to test new patch versions.

Quoted 30 lines
Quoted 4 lines

My question is: how can I register board i2c devices behind the mux in board init code, and make them properly identified when relevant drivers are loaded.

I have just defined the i2c devices behind the mux as connected to the new virtual adapters:

static int wr1100_adap_ids[] = {
        2, 3,
};
static struct pca954x_platform_data wr1100_i2cmux_adap_ids = {
        .adap_ids       = wr1100_adap_ids,
        .len            = ARRAY_SIZE(wr1100_adap_ids),
};
static struct i2c_board_info __initdata wr1100_i2c_devices[] = {
        {
                I2C_BOARD_INFO("pca9540", 0x70),
                .platform_data = &wr1100_i2cmux_adap_ids,
        },
};
static struct i2c_board_info __initdata wr1100_i2c_mux_devices[] = {
        {
                I2C_BOARD_INFO("bq27200", 0x55),
        },
};
Quoted 10 lines

Then into machine startup code:

        i2c_register_board_info(0, wr1100_i2c_devices,
                                        ARRAY_SIZE(wr1100_i2c_devices));
        i2c_register_board_info(2, wr1100_i2c_mux_devices,
                                        ARRAY_SIZE(wr1100_i2c_mux_devices));
        i2c_register_board_info(3, wr1100_i2c_mux_devices,
                                        ARRAY_SIZE(wr1100_i2c_mux_devices));

That works fine in my setup too. Thanks a lot for your help !!!

Quoted 5 lines

Ciao,

Rodolfo

Felix.

_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c

#4 lore raw
In reply to Rodolfo Giometti

Hi, Rodolfo

Quoted 4 lines · Rodolfo Giometti
Quoted 2 lines · Felix Radensky

Hi, Rodolfo

Quoted 9 lines
Quoted 4 lines

I've tried your patches with linux-2.6.27 kernel running on custom board with 460EX PowerPC. This board has two i2c buses and pca9548 switch on bus 0.

Please, consider thay my patch has been *not* accepted into main line due a mutex problem... :'(

I didn't find any discussion on the mailing list. What mutex problem exactly ?

I find your patches very useful, and the concept of virtual buses very elegant.
Hopefully you can rework your patches and get them into mainline. I'm willing
to test new patch versions.

Quoted 30 lines
Quoted 4 lines

My question is: how can I register board i2c devices behind the mux in board init code, and make them properly identified when relevant drivers are loaded.

I have just defined the i2c devices behind the mux as connected to the new virtual adapters:

static int wr1100_adap_ids[] = {
        2, 3,
};
static struct pca954x_platform_data wr1100_i2cmux_adap_ids = {
        .adap_ids       = wr1100_adap_ids,
        .len            = ARRAY_SIZE(wr1100_adap_ids),
};
static struct i2c_board_info __initdata wr1100_i2c_devices[] = {
        {
                I2C_BOARD_INFO("pca9540", 0x70),
                .platform_data = &wr1100_i2cmux_adap_ids,
        },
};
static struct i2c_board_info __initdata wr1100_i2c_mux_devices[] = {
        {
                I2C_BOARD_INFO("bq27200", 0x55),
        },
};
Quoted 10 lines

Then into machine startup code:

        i2c_register_board_info(0, wr1100_i2c_devices,
                                        ARRAY_SIZE(wr1100_i2c_devices));
        i2c_register_board_info(2, wr1100_i2c_mux_devices,
                                        ARRAY_SIZE(wr1100_i2c_mux_devices));
        i2c_register_board_info(3, wr1100_i2c_mux_devices,
                                        ARRAY_SIZE(wr1100_i2c_mux_devices));

That works fine in my setup too. Thanks a lot for your help !!!

Quoted 5 lines

Ciao,

Rodolfo

Felix.

_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c

A message that is not in the archive (sent off-list or not yet received): 4905A68D.7040708-L1vi/lXTdtvUXIAPrk8Z/[email protected]

#6 lore raw
Quoted 3 lines · Felix Radensky
Quoted 1 line

I didn't find any discussion on the mailing list. What mutex problem exactly ?

See this thread:

http://www.mail-archive.com/[email protected]/msg01535.html

Quoted 5 lines

I find your patches very useful, and the concept of virtual buses very elegant.
Hopefully you can rework your patches and get them into mainline. I'm willing
to test new patch versions.

No time to dedicate to... :'( maybe you can try to solve the issue! :P

Ciao,

Rodolfo

Signature · 4 lines
GNU/Linux Solutions                  e-mail: giometti-AVVDYK/kqiJWk0Htik3J/[email protected]
Linux Device Driver                          [email protected]
Embedded Systems                     phone:  +39 349 2432127
UNIX programming                     skype:  rodolfo.giometti

_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c