I2C mux with PCA9543 in linux kernel

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C mux with PCA9543 in linux kernel

2,558 Views
cyrilgermaine
Contributor I


Hello,

I'm not sure where I can post this question.

I'm trying to use 2 audio codecs (same ones with same i2c slave addresses) with an PCA9543A, and I don't really know how to do it. So the alsa drivers will switch automatically between the 2 codecs, so they will be seen as 2 different audio cards.

In the init board, I think I have to :

- register the pca954x driver

- register the i2c-mux driver

- relate the pca954x to the i2c-mux and get the 2 created i2c sub-adapters

- and finaly instatiate 2 codec drivers with the i2c adapters

Example:

// Init board code

struct i2c_board_info i2c_info_pca954x[] = {

{

  I2C_BOARD_INFO("pca954x", 0x70),

  },

};

i2c_register_board_info(1, i2c_info_pca954x, ARRAY_SIZE(i2c_info_pca954x));

// How to register the i2c-mux driver?

// How to register the 2 codec drivers?

struct i2c_board_info i2c_info_codec[] = {

{

  I2C_BOARD_INFO("tlv320aic3x", 0x18),

  },

};

i2c_register_board_info(SUB_ADAPTER_1, i2c_info_codec, ARRAY_SIZE(i2c_info_codec));

i2c_register_board_info(NEW_ADAPTER_2, i2c_info_codec, ARRAY_SIZE(i2c_info_codec));

// Audio SOC code, declaration of the codecs

static struct snd_soc_dai_link davinci_codec1_dai = {

  .name = "TLV320AIC3X",

  .stream_name = "AIC3X",

  .cpu_dai_name = "davinci-mcbsp",

  .codec_dai_name = "tlv320aic3x-hifi",

  .init = aic3x_init,

  .codec_name = "tlv320aic3x-codec.SUB_ADAPTER_1-0018",

  .ops = &ops,

  .platform_name = "davinci-pcm-audio",

};

static struct snd_soc_dai_link davinci_codec2_dai = {

  .name = "TLV320AIC3X",

  .stream_name = "AIC3X",

  .cpu_dai_name = "davinci-mcbsp",

  .codec_dai_name = "tlv320aic3x-hifi",

  .init = aic3x_init,

  .codec_name = "tlv320aic3x-codec.SUB_ADAPTER_2-0018",

  .ops = &ops,

  .platform_name = "davinci-pcm-audio",

};

For now, when I register the pca954x driver, the pca954x_probe function is not even called, even if have the "i2c-core: driver [pca954x] registered" log.

Thank you in advance for your help.

0 Kudos
2 Replies

1,560 Views
cyrilgermaine
Contributor I

Ok for the i2x mux declaration, the i2c board info has to be "pca9543", not "pca954x". Now I have 2 more i2c adapters (#2 and #3), but I stil don't know how to connect my codec driver to them.

static struct i2c_board_info i2c_info_pca9543[] = {

  {

  I2C_BOARD_INFO("pca9543", 0x70),

  },

};

static struct i2c_board_info i2c_info_tlv320aic3x[] = {

  {

  I2C_BOARD_INFO("tlv320aic3x", 0x18),

  .platform_data = &i2c_tlv320aic3x_pdata,

  },

};

i2c_register_board_info(1, i2c_info_pca9543, ARRAY_SIZE(i2c_info_pca9543));

// This doesn't work, it freezes my console before starting Linux

//   i2c_adap = i2c_get_adapter(2);

//   i2c_new_device(i2c_adap, &i2c_info_tlv320aic3x[0]);

//   i2c_adap = i2c_get_adapter(3);

//   i2c_new_device(i2c_adap, &i2c_info_tlv320aic3x[0]);

/*

static struct snd_soc_dai_link davinci_codec1_dai = {

  .name = "TLV320AIC3X",

  .stream_name = "AIC3X",

  .cpu_dai_name = "davinci-mcbsp",

  .codec_dai_name = "tlv320aic3x-hifi",

  .init = elips_ol_3io_aic3x_init,

  .codec_name = "tlv320aic3x-codec.2-0018",

  .ops = &elips_ol_3io_ops,

  .platform_name = "davinci-pcm-audio",

};

static struct snd_soc_dai_link davinci_codec2_dai = {

  .name = "TLV320AIC3X",

  .stream_name = "AIC3X",

  .cpu_dai_name = "davinci-mcbsp",

  .codec_dai_name = "tlv320aic3x-hifi",

  .init = elips_ol_3io_aic3x_init,

  .codec_name = "tlv320aic3x-codec.3-0018",

  .ops = &elips_ol_3io_ops,

  .platform_name = "davinci-pcm-audio",

};

*/

0 Kudos

1,560 Views
cyrilgermaine
Contributor I

Done!

Here is how to do it:

static struct pca954x_platform_mode pca9543_mode[] = {

  { .adap_id = 2, },

  { .adap_id = 3, },

};

static struct pca954x_platform_data pca9543_data = {

  .modes = pca9543_mode,

  .num_modes = ARRAY_SIZE(pca9543_mode),

};

static struct i2c_board_info i2c_info_pca9543[] = {

  {

  I2C_BOARD_INFO("pca9543", 0x70),

  .platform_data = &pca9543_data,

  },

};

static struct i2c_board_info i2c_info_tlv320aic3x[] = {

  {

  I2C_BOARD_INFO("tlv320aic3x", 0x18),

  .platform_data = &i2c_tlv320aic3x_pdata,

  },

};

i2c_register_board_info(1, i2c_info_pca9543, ARRAY_SIZE(i2c_info_pca9543));

i2c_register_board_info(2, i2c_info_tlv320aic3x, ARRAY_SIZE(i2c_info_tlv320aic3x));

i2c_register_board_info(3, i2c_info_tlv320aic3x, ARRAY_SIZE(i2c_info_tlv320aic3x));

0 Kudos