[Gta04-owner] [PATCH 2/3] ASoC: twl4030: allow voice port to be connected externally.
Dr. H. Nikolaus Schaller
hns at goldelico.com
Wed Nov 19 11:00:09 CET 2014
Am 18.11.2014 um 03:56 schrieb NeilBrown <neilb at suse.de>:
> On Sun, 16 Nov 2014 19:00:42 +0100 "Dr. H. Nikolaus Schaller"
> <hns at goldelico.com> wrote:
>> 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
>>>>> I see that there are 3 dai-links:
>>>>> 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"?
>>>>> 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:
>>> 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.
> The hso driver (drivers/net/usb/hso.c) which gives access to the Option modem
> already provides an rfkill device. It implements it via:
> static int hso_rfkill_set_block(void *data, bool blocked)
> struct hso_device *hso_dev = data;
> int enabled = !blocked;
> int rv;
> if (hso_dev->usb_gone)
> rv = 0;
> rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0),
> enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0,
> return rv;
Yes I know that there is some rfkill implemented by the HSO driver.
> I'm hoping that does something useful. Do we have docs that would confirm
> that those messages (0x82 and 0x81) do, or does anyone know enough about
> the USB protocol to know more about that this might mean?
Unfortunately no. Not even in the under NDA docs I have. There appears to be
some additional protocol to directly interface using packets.
And, even worse I did not see any effect when I tried (but my observations may
not be reliable).
The next thing to consider is that this is a very GTA04/OPTION specific thing
and no solution for other Modems which use the ttyACM (without any rfkill support).
And I still think the problem to be solved (powering up modems connected to
USB and GPIOs) is always the same, so that we should look for a solution that
serves multiple different modem modules.
>> 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.
> Presumably this uses drivers/usb/class/cdc-acm.c?
> * USB Abstract Control Model driver for USB modems and ISDN adapters
> That appears to present a tty interface, so the same basic approach could
Yes. But again it needs intensively modifying another usb-tty glue driver.
>> 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
>> * USB
>> * PCM
>>> 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.
> And you are very welcome to following any implementation path you choose.
> Just because I don't think it is the best idea, doesn't mean you shouldn't
> make it work and make it useful (and maybe even prove me wrong :-).
>>> 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.
> The modem can be programmed for other async notifications that SMS and
> VOICE (e.g. signal strength, cell-id) So there can be real value in keeping
> it open while-ever it is in-use (just like we do for GPS).
> But I'm sure that keeping the device on when no tty is open is a solvable
> problem if there is a real need.
Hm. This needs another bit of control. So it makes the solution even more complex.
>> 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).
> I think it is important that the connection between these modules is
> discoverable from user-space. It shouldn't be necessary to "know" that a
> particular audio interface relates to a particular USB tty device.
> This is something we don't yet have. I don't know how best to achieve it.
> Maybe it can be done with several separate drivers…
Currently the interfaces have names. The USB/tty are called /dev/ttyHS* and the sound
card has “modem” or “gtm601” in its name.
>> 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.
> The way the wifi chip works is that devicetree says a particular regulator
> needs to be turned on to see what is being that mmc interface. So it gets
> turned on a boot time and the wifi chip is found. As no-one wants the wifi
> device at that moment it is then turned off again, but the "wlan0" interface
> remains in existence.
> When you run "ifconfig wlan0 up", the device is powered on again.
> I see the same principle applying to the modem on the usb interface.
> "normal" usb is hot-plug so you cannot assume anything is there. But the USB
> interface in the GTA04 is hard-wired to the Option modem - so it isn't
> exactly normal.
> Devicetree could be told that an 'hso' device is attached so it can be probed
> at some point. It will power on the modem, check it is there, create the
> relevant device files (the 'hso0' network interface and the /dev/ttyHS*
> devices) and then turn it off. When someone does "ifconfig hso0 up" or opens
> a /dev/ttyHS* device, it gets turned back on.
Oops. This seems even more complex than what we have discussed so far.
It could indeed work like you describe for wifi/sdio.
What I don’t like there will be also present: the device is powered up at boot
time. Which is not good if the battery is nearly empty or has just started charging.
>>> 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?
> Given what Mark Brown said about machine drivers, maybe something like that
> is exactly the "right" way to go - I haven't looked more closely yet.
>> 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.
> So the line should normally be at '0'.
> To turn on you pulse high then low for 200ms.
> After some period that might be a few seconds the device has stablised and
> then a second high/low pulse of 200ms will kill RF and then eventually power
> down the device.
> That does seem to work (on the A4) - I wonder why I thought it didn't...
> Maybe I was thinking of the A3.
>>> 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?
> In the GTA04A4 schematic, Sheet 10/20, near the middle of the top of the
> sheet, it shows GPIO175 connected to a resistor/transistor network that I
> don't understand.
> GPIO186 is connected to the same network which connects to WWAN_RESET and
> ON_KEY on the GTM601.
Ah, I see. This was intended to be a feedback to the CPU so that it can know if the
modem is powered on. But it had wrong polarity. Therefore R1008 it is not installed
on any device and therefore not mentioned elsewhere.
> In the GA04A3 schematic, Sheet 10/19 GPIO175 is connected directly to
This was swapped with GPIO10 when moving from A3 to A4.
>> 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.
>>>>> 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?
>>>>> Gta04-owner mailing list
>>>>> Gta04-owner at goldelico.com
>>>> Gta04-owner mailing list
>>>> Gta04-owner at goldelico.com
More information about the Gta04-owner