Caleb Crome | 11 May 19:31 2011

Need general idea how to architect driver for multi-codec board

Hello All,
   I'm building a board with multiple TLV320AIC33 codecs on board, and I
don't know how I should architect the interface.

The board is set up to use TDM (16 channels on 1 TDM PORT), it has 16 input
and 16 output channels, all bonded together -- the hardware does not allow
different codecs to run at different speeds.

The board also includes several other widgets, like an I2C mux (to address
all 8 stereo codecs), a couple of power amplifiers, and a limited number of
ways the audio can be routed in or out.

My question is this:  I'm not sure how to architect the driver:

1)  Simply instantiate multiple TLV320IAC33 codec drivers, as the AIC33
driver is already written.
    This seems like it won't work because I'd end up with multiple
user-space 'cards', yet I want the card to appear as a single 16-channel
sound card.  Also, when you start one PCM interface for one codec, they
would all start automatically, which I imagine the linux system wouldn't
get.  Also, the PCM interface needs to be configured differently for each
codec (the TDM offset must be 0, 16, 32, 48, etc. bits).

2) rewrite the AIC33 driver to include all 8 codecs, including all the mixer
controls for each codec.  This is going to get REALLY big and ugly in the
user space mixer control -- there will be a zillion controls, most of which
are not really useful for this board.

3) rewrite the AIC33 driver to include all 8 codecs, but pare down the mixer
controls to just the ones that I care about.  If the card changes later, add
(Continue reading)

Mark Brown | 11 May 19:50 2011

Re: Need general idea how to architect driver for multi-codec board

On Wed, May 11, 2011 at 10:31:15AM -0700, Caleb Crome wrote:

> 1)  Simply instantiate multiple TLV320IAC33 codec drivers, as the AIC33
> driver is already written.

Yes.

>     This seems like it won't work because I'd end up with multiple
> user-space 'cards', yet I want the card to appear as a single 16-channel
> sound card.  Also, when you start one PCM interface for one codec, they

No, you shouldn't.  You'll end up with a single card.

> would all start automatically, which I imagine the linux system wouldn't
> get.  Also, the PCM interface needs to be configured differently for each
> codec (the TDM offset must be 0, 16, 32, 48, etc. bits).

The TDM stuff should be configured with the existing TDM API (you may
need to implement this in the CODEC driver).
Caleb Crome | 11 May 20:29 2011

Re: Need general idea how to architect driver for multi-codec board

Well, that does sound easier than rewriting the whole thing.  I'll give it a
go at instantiating multiple codecs.

Would this be 'substreams' or is that something else?

Sorry to be ignorant, but I'm a newbie to kernel development (I've
successfully brought up GPIOs and the I2C mux on my board, so I at least
have some simple stuff under my belt).

Thanks again,
  -Caleb

On Wed, May 11, 2011 at 10:50 AM, Mark Brown <
broonie <at> opensource.wolfsonmicro.com> wrote:

> On Wed, May 11, 2011 at 10:31:15AM -0700, Caleb Crome wrote:
>
> > 1)  Simply instantiate multiple TLV320IAC33 codec drivers, as the AIC33
> > driver is already written.
>
> Yes.
>
> >     This seems like it won't work because I'd end up with multiple
> > user-space 'cards', yet I want the card to appear as a single 16-channel
> > sound card.  Also, when you start one PCM interface for one codec, they
>
> No, you shouldn't.  You'll end up with a single card.
>
> > would all start automatically, which I imagine the linux system wouldn't
> > get.  Also, the PCM interface needs to be configured differently for each
(Continue reading)

Caleb Crome | 12 May 00:44 2011

Re: Need general idea how to architect driver for multi-codec board

Hi again,
   I've been poking through the soc-core.c and other soc files, and I'm
still at a bit of a loss how to add 8 cocdecs on 3 different I2C (virtual)
busses onto one card.

Do I set up my 'card'  with multiple codecs as multiple dai links?

static struct snd_soc_dai_link puppy_dai[] =
{
        {
                .name = "puppy",
                .stream_name = "puppy",
                .cpu_dai_name = "omap-mcbsp-dai.0",
                .platform_name = "omap-pcm-audio",
                .codec_dai_name = "tlv320aic3x-se-hifi",
                .codec_name = "tlv320aic3x-se-codec.4-0018",
                .ops = &puppy_ops,
        }, {
                .name = "puppy",
                .stream_name = "puppy",
                .cpu_dai_name = "omap-mcbsp-dai.0",
                .platform_name = "omap-pcm-audio",
                .codec_dai_name = "tlv320aic3x-se-hifi",
                .codec_name = "tlv320aic3x-se-codec.4-0019",
                .ops = &puppy_ops,
        },
...   6 more codecs ...
}

static struct snd_soc_card snd_soc_puppy = {
(Continue reading)

Caleb Crome | 26 May 23:23 2011

Re: Need general idea how to architect driver for multi-codec board

Hi Mark,
   You previously indicated that I can instantiate multiple tlv320aic33
drivers.  Can you please give me a clue how to do that?  I've been staring
at this for days, and I still don't really get how it's supposed to be done.

I tried adding the I2C devices, and it does get to the probe functions.
 However, when it comes to adding the mixer controls (SND_SOC_XXXX), it
fails because there are already controls with those names, like "Right PGA
Mixer" etc.  The alsa layer doesn't seem to allow multiple registrations of
the same control.  How do I give each instantiation a unique identifier?
 Since the tlv320aic33 has about 80 controls, I'm going to end up with over
600 controls in alsamixer.

Are there any examples in the world that show multiple codecs in the same
sound card that I can get a clue from?

Again, any help would be most welcome.

Thanks,
  -Caleb

On Wed, May 11, 2011 at 10:50 AM, Mark Brown <
broonie <at> opensource.wolfsonmicro.com> wrote:

> On Wed, May 11, 2011 at 10:31:15AM -0700, Caleb Crome wrote:
>
> > 1)  Simply instantiate multiple TLV320IAC33 codec drivers, as the AIC33
> > driver is already written.
>
> Yes.
(Continue reading)

Mark Brown | 27 May 03:27 2011

Re: Need general idea how to architect driver for multi-codec board

On Thu, May 26, 2011 at 02:23:03PM -0700, Caleb Crome wrote:

>    You previously indicated that I can instantiate multiple tlv320aic33
> drivers.  Can you please give me a clue how to do that?  I've been staring
> at this for days, and I still don't really get how it's supposed to be done.

With things like this it's always useful to look for other examples of
whatever it is you're doing - there's systems like speyside and rx51 in
mainline.

> fails because there are already controls with those names, like "Right PGA
> Mixer" etc.  The alsa layer doesn't seem to allow multiple registrations of
> the same control.  How do I give each instantiation a unique identifier?

Set up a snd_soc_codec_conf for each CODEC and assign a name_prefix to
it.  

>  Since the tlv320aic33 has about 80 controls, I'm going to end up with over
> 600 controls in alsamixer.

Yes.
Caleb Crome | 27 May 23:36 2011

Re: Need general idea how to architect driver for multi-codec board

Mark,
   Thanks, for the pointers.  I now have a gazillion controls in my
alsamixer :-)  The snd_soc_codec_conf works like a charm.

However, I'm still having problems getting the system set up with more than
2 channels.  the rx51 and speyside don't quite do the same thing as far as I
can tell:  the rx51 is close -- it very nearly brings up the 'b' codec in
the aic34, but I don't see how the TDM is set -- it appears to still be a
stereo configuration.

Do I need multiple snd_soc_dai_links when configuring?  In hw_params, I only
seem to get 1 codec dai_link, so I can't set the TDM slots there.

Or are the extra codecs in the daisy chain considered 'aux' devices?  I
guess I could set up the tdm slots in each of the snd_soc_aux_dev.init
functions.  But that callback init function has a snd_soc_dapm_context a
parameter, which doesn't seem to be the right place for setting tdm slots
and pin directions.

My 'machine_hw_params' function allows for 1 through 16 channels, and my
machine_startup function  calls snd_pcm_hw_contraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_CHANNELS, 1, 16) to allow for 16 channels.   But still
the only way I can get more than 2 channels from any user program (using
jackd), is to change the tlv320aic3x.c driver to set channels_max to 16,
which I'm pretty sure is not right.

It seems like I might need to do something like this in the hw_params
function:

int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
(Continue reading)

Mark Brown | 28 May 03:34 2011

Re: Need general idea how to architect driver for multi-codec board

On Fri, May 27, 2011 at 02:36:58PM -0700, Caleb Crome wrote:

> However, I'm still having problems getting the system set up with more than
> 2 channels.  the rx51 and speyside don't quite do the same thing as far as I
> can tell:  the rx51 is close -- it very nearly brings up the 'b' codec in
> the aic34, but I don't see how the TDM is set -- it appears to still be a
> stereo configuration.

There's an API for configuring TDM - snd_soc_dai_set_tdm slot.

> Do I need multiple snd_soc_dai_links when configuring?  In hw_params, I only

Yes, you will.  Or invent a new interface.  The current APIs provide
point to point links between interfaces.  If you're trying to do
something different then you'll need to extend the core to support what
you need.

> seem to get 1 codec dai_link, so I can't set the TDM slots there.

What makes you say that?

> Or are the extra codecs in the daisy chain considered 'aux' devices?  I

No.  aux devices have no digital links.  In addition to looking at the
existing code you'll also find a lot of background information if you
look through the revision control history...
Caleb Crome | 2 Jun 00:17 2011

Re: Need general idea how to architect driver for multi-codec board

Hi Again,
  Sorry to keep on this, but I'm really wedged.  I can't tell if I'm trying
to break new ground, or if I just don't know what I'm doing :-)  Or both
perhaps.

I've got my multi-codec card instantiating (only 4 codecs here for
simplicity -- there are really 8 total)

# insmod tlv320aic3x_se.ko   # <--- my custom version of aic3x driver.
# insmod puppy_machine.ko  # <-- my custom machinne interface with all my
dai-links and all.

# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: tlv320aic33se [tlv320aic33-se], device 0: tlv320aic33-se
tlv320aic3x-se-hifi-0 []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: tlv320aic33se [tlv320aic33-se], device 1: tlv320aic33-se
tlv320aic3x-se-hifi-1 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: tlv320aic33se [tlv320aic33-se], device 2: tlv320aic33-se
tlv320aic3x-se-hifi-2 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: tlv320aic33se [tlv320aic33-se], device 3: tlv320aic33-se
tlv320aic3x-se-hifi-3 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
(Continue reading)

Mark Brown | 3 Jun 10:48 2011

Re: Need general idea how to architect driver for multi-codec board

On Wed, Jun 01, 2011 at 03:17:10PM -0700, Caleb Crome wrote:

>   Sorry to keep on this, but I'm really wedged.  I can't tell if I'm trying
> to break new ground, or if I just don't know what I'm doing :-)  Or both
> perhaps.

Like I said in my last mail you're probably trying to break new ground
here.  You're trying to bind all the CODECs together and treat them as
one digital interface, currently the code does a series of point to
point links multiplexed on a bus only.

> I've got my multi-codec card instantiating (only 4 codecs here for
> simplicity -- there are really 8 total)

> # insmod tlv320aic3x_se.ko   # <--- my custom version of aic3x driver.

That's not a good sign...  If you've modified the driver you probably
want to look into submitting your modifications back upstream.
Caleb Crome | 4 Jun 01:35 2011

Re: Need general idea how to architect driver for multi-codec board

Okay,
   I finally got my system going -- in a *very* kludgy way.  I re-write
tlv320aic3x.c to include all the codecs.  Its nasty and ugly and horrible,
but it works with no changes to the kernel soc architecture.

Thanks for your help Mark!

I'll start another thread for proposed changes to the core so that this can
be done properly.

Thanks again,
  -Caleb

Gmane