[Gta04-owner] [PATCH 2/3] ASoC: twl4030: allow voice port to be connected externally.

Dr. H. Nikolaus Schaller hns at goldelico.com
Sun Nov 16 19:00:42 CET 2014

Hi Neil,

Am 12.11.2014 um 06:37 schrieb NeilBrown <neilb at suse.de>:

> (cc list trimmed, as I don't think this is directly relevant to many of
> those listed).

indeed it appears as if we have to find a solution first, before we propose
something to LKML.

> On Mon, 10 Nov 2014 07:46:50 +0100 "Dr. H. Nikolaus Schaller"
> <hns at goldelico.com> wrote:
>> Am 10.11.2014 um 00:25 schrieb NeilBrown <neilb at suse.de>:
>>> On Sat, 8 Nov 2014 09:26:22 +0000 Mark Brown <broonie at kernel.org> wrote:
>>>> On Sat, Nov 08, 2014 at 11:38:03AM +1100, NeilBrown wrote:
>>>>> If voice port on twl4030 is not connected to a McBSP (or similar)
>>>>> then we cannot configure the format the way we normally do for a DAI.
>>>> Yes we can, you need to represent the DAI link to whatever else the
>>>> device is connected to in the driver like we do anything else - and in
>>>> any case this isn't a device specific issue so we shouldn't be doing
>>>> something driver specific to solve it.  Look at something like speyside.
>>> Hi Mark,
>>> thanks for the reply ... I might need a little bit more help though.
>>> I had a look at sound/soc/samsung/speyside.c, but I'm not entirely sure what
>>> I'm looking for.
>>> Presumably this is an audio processor not unlike the audio module in the
>>> twl4030.
>>> I see that there are 3 dai-links:
>>> Baseband
>>> Presumably "Baseband" is similar, in purpose at least, to the "voice"
>>> interface on the twl4030.
>>> Each dai-link has a "cpu_dai_name" and a "codec_dai_name", even though it
>>> appears that only "CPU-DSP" is connected to the CPU.  Maybe that naming is
>>> the source of some of my confusion.
>>> "Baseband" declares
>>>               .cpu_dai_name = "wm8996-aif2",
>>> so wm8996 is something with 2 audio interfaces, (aif), and this is the second
>>> one?  Maybe the  wm8996 is the audio module, so what is the "speyside"?
>>> http://opensource.wolfsonmicro.com/content/speyside-audio
>>> says it is a "reference platform".  Does that mean it is a board with a bunch
>>> of chips soldered onto it?  If it were a board it should be described by a
>>> dts file, not by a pile of C code (I thought), so I must be wrong about that.
>>> In my case, I have a board with a GSM module and the twl4030 module.  Each
>>> has an audio interface and these are connected.  I assume that I need to
>>> express this connection in the dts file.
>>> The GSM module doesn't currently appear in the dts file as it is usb-attached.
>>> However I've been thinking that we will need to add it so we can express
>>> power-on controls (twiddling some GPIOs).  So let's suppose we have the GSM
>>> module in the dts file (child of a USB interface)
>> It is a quite complex connection pattern and I am not sure if the modem is really
>> a logical child of the USB interface. Powering up/down the USB interface has nothing
>> to do with the modem power. Rather, it continues to operate if USB is suspended
>> and the modem notifies USB that it has become active.
>> The connections on this GTA04 board are:
>> Modem USB <—> CPU USB
>> Modem PCM <—> TWL4030 Voice <—> OMAP3 McBSP4 (yes, it is a 3-way connection)
>> Modem Power control <—> 1 or 2 GPIOs (depending on board variant)
>> The reason for the 3-way connection is that user space can chose if the GSM
>> voice is routed directly to the TWL codec (low latency, independent of CPU) or
>> goes through the CPU (e.g. for DTAM or voice scrambling by software) and
>> then through the other PCM link between the CPU and the TWL.
>> This is why I would make the McBSP4 a separate sound card.
>> And, this is why it needs some control and tri-state of the TWL4030 and OMAP3
>> McBSP4 since only one can provide a digital PCM stream to the modem.
>> One more thing to consider for a general solution is that there are modem modules
>> that communicate data through UART or SPI - but otherwise have a similar connection
>> for digital audio. So forcing the power control driver to be a subnode of USB doesn’t
>> appear general enough to me.
>> Finally, this connection pattern is not specific to this modem (OPTION GTM601) on this
>> GTA04 board. We plan to use a Gemalto PHS8  in the Pyra-Handheld and the Neo900
>> devices - but the general connection pattern as defined above remains the same.
>> So my proposal is to have a specific wwan-power driver for this type of modems.
>> And power control can and should be kept separately from USB (except the case
>> where only 1 GPIO exists and USB must be tapped to detect the modem power
>> state). You can find work in progress for this approach here:
>> <http://git.goldelico.com/?p=gta04-kernel.git;a=blob;f=drivers/misc/wwan-on-off.c;h=e13f47dbd734d14f4e38ea9cf622982dc3550212;hb=154bcd388a8f5bcc7fcf0e57e93b6388daa16980>
> I've had a few thoughts about this.
> I would certainly like a way to turn the modem on/off without poking at GPIOs.
> I'm not convinced that an 'rfkill' is the best interface though.  'rfkill'
> should be just for turning of 'rf'.  The modem does provide some (Limited)
> functionality without generating rf  (e.g. inspecting the address book on the
> SIM), and there is no reason to disable that when rf is not wanted.

This is something I have not really thought of.

On the other hand the airplane mode is not necessarily a hardware switch or
gpio that is easily controlled by the kernel through a rfkill driver, but some
AT command. Having a rfkill driver that sends (device specific) AT commands
obviously goes far beyond the concept of a kernel driver.

So I am not sure if rfkill can be used as „RF“ kill at all.

Therefore, I think the mis-use to control modem-power might be justified.
Because it is a well established interface and can easily be adapted to
different modems  without changing the user space code.

> The most general mechanism for turning power on/off that is used in the
> kernel is simply that power is turned on when the device is used,

That would be fine, but IMHO in this case it is impossible for the kernel to know
„the device is is used". Unless user-space tells so on some secondary channel.

> and turned
> of when it is not in use.  Applying that logic to usb-devices is not entirely
> straight forward but I think it is worth exploring.
> Normally when the  power is removed from a USB device it disappears
> completely.  Any /dev/XXX etc device that it created is removed.
> That makes it difficult to start using the device.


> However there is a feature in the Linux  USB stack called "usb persist",
> described in Documentation/usb/persist.txt.
> The focus of this it to allow devices to "persist" over system suspend/resume
> when the bus  would be powered off.  The idea is that when the  bus comes
> back on, the devices are  enumerated, and if one is found that "exactly"
> matches a "persistent" device that was there previously, then it is assumed
> to be the same device and the cycle is treated as "reset" instead of "detach"
> followed by "attach".
> I would  like to try to enable  the same thing for runtime-pm suspend/resume.
> i.e. when the last /dev/ttyHS*

Hm. This assumes that there *is* a /dev/ttyHS*.

This is only for the GTM601 because Option has provided such a driver.

For the PHS8 planned to be used in future devices like Pyra and Neo900
this is simply a standard ACM (? i have not checked the name) interface.

So modifying these drivers might break compatibility with non-modem USB
clients that use the same USB standard protocol.

Anyways this would mean that each modem needs a very different driver,
although all of them have the same type of interface:

* power-on/off trigger
* optionally some feedback line
* wakeup interrupt for incoming SMS or calls

> device is closed, the hso driver tells the usb
> bus that everything is inactive, and the usb bus powers down.  That tells
> the hso driver to power down, and it fiddles with the GPIO lines as required.
> The hso device would be marked to persisted so the  devices remain.

Now, I get your general idea:

* a device is powered on only if there is a user space client that accesses it
* access is detected through an open() for some control interface

This is indeed a good approach for fully automatic power management.
But it might be very difficult to implement.

So the question is if we need a fully-automatic solution, or if a simpler and
still general solution is sufficient.

Since I am always in favour of the KISS principle to get something in the
next weeks/months instead of a general solution in some years: I am clearly
in favour of the second choice.

> When /dev/ttyHS* is re-opened, the hso driver powers up the modem and then
> tells the USB bus it is needed again so it wakes up.  It then finds exactly
> the same hso device and so everything "just works“.

This assumes that there is always some daemon running exactly as long as we want
to have the modem turned on.

But assume the modem is handled differently: a daemon (to read incoming SMS or call)
is started (e.g. by udev) each time the modem reports a 3g wakeup event. Like a USB
memory drive is only mounted when it is plugged in.

Then the modem must be placed into a situation where it remains powered on while there
is no client for any /dev/tty.

This is why I prefer a modular approach. One driver for each sub-interface… I.e. one
for USB (exists - does not need a change), one for PCM (sound/DAI links) - and one
missing piece for power control (which makes the modem register through standard
USB „I have been plugged in“ mechanisms).

Unfortunately the virtual-gpio solution is not finding enough friends. Maybe, because
it is too simple, too easy to understand but not 100% „correct“ :)

> That's the theory anyway.  There is a long way from theory to practice, and
> thing may well change on the way.

A major issue is how to start this initially. The modem initially has no power,
so there is no USB device seen and no /dev/tty to connect to. So a user space
daemon can’t request the modem to be turned on.

Unless the /dev/tty interfaces are always instantiated. But how does that work
for a driver that is only loaded/instantiated after enumeration of a USB device?

So IMHO this reverses the way device specific drivers are handled by USB.

> With respect to device-tree, the representation in device-tree doesn't have
> to perfectly matter the code  organisation in Linux.  It is quite possible
> for one Linux  driver to implement several different device-tree node types
> and tune its behaviour accordingly.  There are  certainly cases of drivers
> which can connect to a USB buss or and SDIO buss and  maybe even an SPI or
> I2C buss.
> So describing a power manager as a child of a USB bus does not prevent it
> from also being described as the child of a UART on a different board.


> How the audio paths fit into all of this, I don't really know yet.  If they
> need to be described in devicetree, then describing a connection between a
> mcbsp and a child of a USB bus seems to make sense.  Exactly how the drivers
> access and use that information is a separate question.

I just wonder what is bad with the current „second/third sound card“ description
we have in non-DT board files?

The only real problem is the hw/sw-routing switch. This can IMHO be handled
through two different pinctrl states.

But again this might be against „DT must describe hardware“ and "a driver must
exist for physical hardware". This tri-state switch can’t be pinned down to some
chip. Rather it is combined from some flip-flops and driver transistors in the twl,
the modem and the CPU. So it is a driver for a combination of 3 chips…

In older kernels there was a dynamic call to set a DAI channel (or endpoint) to
tristate, but AFAIK it was removed now.

Sometimes it looks as if some maintainers have too strict principles.

>>> and the twl4030 as well
>>> (beneath an i2c interface).
>>> The twl4030 needs to know the master/polarity of the clk/frm lines.  The GSM
>>> module declares that these are.  So presumably we need some sort of linkage.
>>> Ahhhh... I found Documentation/devicetree/bindings/sound/simple-card.txt
>>> So I need to make the "voice" port on the twl4030 look like a "cpu" end of a
>>> dai-link, and create a "codec" end in the GSM module, and use "sound-dai" to
>>> point from the twl4030 to the GSM module.
>> What I wonder a little is that we have all these dai-links working since your 3.7
>> kernel for GTA04. Is it necessary to re-invent a solution or should we just make
>> the solution device tree compatible?
> That is exactly the goal.  But what exactly does "device tree compatible"
> mean in this context?  I'm not clear on that but I do have some pointers now
> that I can explore.

I would expect that everything we already have in the (sound) board file (e.g.
defining the DAI links) is converted to DT.

> On the side issue of exactly how to control the Option Modem in the GTA04a4,
> there are a couple of things I'm unclear on.
> 1/ When I was playing with this quite some  months ago, I concluded that I
>  couldn't actually power it down by manipulating GPIO186.
>  Toggling that would  bring it from 'off' to 'on', but to turn it off I had
>  to set GPIO186 to 0, then issue "AT$QCPWRDN".
>  Can you reliably turn it off just by toggling that line?

Yes. There is some timing constraint. There must be a 0-1-0 sequence.
The „1“ must be at least 200ms. After 200ms it kills RF - but the modem core stays
powered on. It really turns only off only if the line is returned to „0“. And after this it
might take up to 5 seconds.

What I don’t know is if it can be powered up while it is shutting down. So there
might also be some window where it ignores a second impulse on the gpio186.

> 2/ What is GPIO175 for?
>  Your driver does seem to touch it.  I cannot even be sure from the
>  schematic where it is an input or and output…

I am not sure where you did get the „gpio175" from?

It is planned for the GTA04A5 to have a „power is on“ feedback GPIO (something
we are also missing for the GPS receiver). It does not yet exist in GTA04A3/A4

The plan in the omap3-gta04a5.dts is to use some gpio15 from the twl4030.


> Thanks,
> NeilBrown
>>> Then I use frame-master, bitclock-master, bitclock-inversion, frame-inversion
>>> for the settings I need.
>>> I suspect I can make that work.
>>> Am I on the right track?
>>> Thanks,
>>> NeilBrown
>>> _______________________________________________
>>> Gta04-owner mailing list
>>> Gta04-owner at goldelico.com
>>> http://lists.goldelico.com/mailman/listinfo.cgi/gta04-owner
>> _______________________________________________
>> Gta04-owner mailing list
>> Gta04-owner at goldelico.com
>> http://lists.goldelico.com/mailman/listinfo.cgi/gta04-owner

More information about the Gta04-owner mailing list