-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Feature request - overlay for remapping audio to GPIO pins #1473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The preferred method is to rewrite the relevant section in dt-blob.bin (which is primarily Videocore-based GPIO setup on a per-model basis). The source DTS is here: https://github.com/raspberrypi/documentation/blob/master/configuration/images/dt-blob.dts and it's simple enough to change pin 40/45 to 12/13. Docs page here tells you how to insert the modified dt-blob: https://www.raspberrypi.org/documentation/configuration/pin-configuration.md |
I woudn't say it was preferred - the dt-blob is a monolithic monstrosity. Edit once and forever have to keep it up-to-date. All you have to do is choose a DT node that doesn't have an existing pinctrl section and add one - the "audio" node is the obvious one. It would look something like this (untested):
[ EDIT: |
Thanks for this @pelwell (sorry for the delay in replying!). Am I correct in thinking that I would use the code snippet as a .dts file, before compiling it to a .dtb (with the -@ argument to allow unresolved references), and then getting it onto the If I am getting any of this drastically wrong please let me know! |
@stefandz That looks broadly right, with the proviso that different models use different pins for PWM audio. Having said that, I haven't got it to work yet. For reasons I haven't managed to figure out the pinctrl section is being ignored or at least not taking effect. I'll report back when I make some progress. |
I have a tested setup for mapping the audio pins to 12, 13. There is also step by step instructions for creating the dt blob and programming it into an eeprom so it works as soon as the HAT is put on top of the RPi. See at the end of the page in http://discohat.com/miscap/. |
Thanks for the suggestion. By the looks of it I'd say that works almost by accident. What you are doing is enabling the PWM driver, which is not the same as the PWM audio driver - just basic perod+duty cycle stuff. But by getting it to request the PWM function on pins 12 & 13 you are achieving the objective. What I'm trying to do is get the pins assigned to the audio node. I'm also concerned that your overlay leaves the PWM functions multiply mapped, although it appears to be working for you. Once I've got pins allocated for the audio node I'll get the standard DTBs to request the per-platform standard pins, then all an overlay would have to do is overwrite those pin assignments. |
Thank you for the feedback. As a normal user I did not understand the difference between pwm and audio node. I have to change the src to use audio node instead. Perhaps later today when I get home. It would be nice to do things correctly. |
Thank you everyone for your valuable (and generous) time contributions to this. If there's anything I can be doing to help, please let me know! BTW, I really like your HAT, @karrika 👍 |
Duh! It really helps if you call the property I'll have a think about the best way to make this work on all platforms. My current proposal is:
|
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: #1473 Signed-off-by: Phil Elwell <[email protected]>
The firmware change for this went in at the end of last month. I've now pushed the DTB changes that define the audio_pins node for all the Pi models with audio outputs, to be picked up by the next build. With these in place, the overlay required to remap the output to 12 & 13 now looks like this:
Note that you can also disable the PWM output with an empty "brcm.pins" property. |
kernel: BCM270X_DT: Declare the audio PWM pins explicitly See: raspberrypi/linux#1473 kernel: Add support for Dion Audio LOCO DAC-AMP HAT See: raspberrypi/linux#1553 kernel: BCM270X_DT: Overlay to re-enable HW CS on SPI0 See: raspberrypi/linux#1547
kernel: BCM270X_DT: Declare the audio PWM pins explicitly See: raspberrypi/linux#1473 kernel: Add support for Dion Audio LOCO DAC-AMP HAT See: raspberrypi/linux#1553 kernel: BCM270X_DT: Overlay to re-enable HW CS on SPI0 See: raspberrypi/linux#1547
Thanks very much for this @pelwell (and everyone else involved). I will try testing this out today on as many platforms as I can get my hands on. |
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: #1473 Signed-off-by: Phil Elwell <[email protected]>
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: #1473 Signed-off-by: Phil Elwell <[email protected]>
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: #1473 Signed-off-by: Phil Elwell <[email protected]>
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: #1473 Signed-off-by: Phil Elwell <[email protected]>
@stefandz as a fix for your issue has been implemented, please try a firmware upgrade and confirm that is has been resolved by closing this issue. Thanks. |
@Ruffio will try to test this during the week - sorry for the delay at this end |
Tested and confirmed working on Raspberry Pi 2 B and Raspberry Pi 3. On the Zero, however, the audio channels are reversed - this is true for both versions 1.2 and 1.3. What is the recommended way of allowing for this - something within the overlay or loading different overlays for different models? I don't have access to a Pi 1 A+ or B+ for testing - should I expect those to behave like the Zero or the 2/3? Also, I am using a single .dtbo file for all testing, compiled on a Pi3 - is this best practice? Thank you for all your help on this so far, and apologies that it has taken me so long to get testing finished. |
On early Pis (Models A & B), onboard audio uses PWM0 to drive the left channel of the audio jack and PWM1 to drive the right. With the appearance of the B+ this mapping got reversed (essentially by accident), but the firmware has the ability to swap the channels over so the end result is correct. This swapping is controlled by the pin allocations as read from the dt-blob, either an external dt-blob.bin or the built-in default version, but PiZero normally has no audio jack so there is no swap. When you use the overlay, pins 12 and 13 are mapped to PWM0 and PWM0 respectively, so audio left should always be sent to 12 and right to 13 for all models EXCEPT that the above swapping is still applied because the firmware doesn't notice that it is no longer needed. The end result is that A+, B+, 2B and 3B have right on 12 and left on 13, while the other Pis have the channels the right way round. I'll have a think about a fix. |
Thanks for the explanation, @pelwell. I am just as happy to make the fix two overlays, one for the Zero and one for all other Pis if that helps (although from what you're saying, that might get broken in future updates). |
That's actually not an option because you can't map PWM0 to pin 13 and PWM1 to 12. You could use a custom dt-blob.bin, but that can lead to problems with future releases so is best avoided if possible. |
Ah sorry, my misunderstanding. I feel this might be useful to resolve for others who wish to have audio out on the Zero. Do let me know if I can help testing (I promise to be on it quicker this time around - although I am out on holiday for the last two weeks of August). |
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: #1473 Signed-off-by: Phil Elwell <[email protected]>
Since using this overlay gives the same L-R swapping as my cludgy bit of What's the best way to do this so that the overlay is automatically included if I (as a user) run |
The rpi-update firmware released on the 16th includes a fix for the L-R swap on 12 & 13 ("firmware: platform: Don't swap audio L&R if using GPIOs 12&13") - see if it works for you. I can't help you with Debian packaging matters - @XECDesign is our expert. We have always been very wary of editing config.txt during upgrades, but appending a line if it doesn't exist is about as safe as it gets. |
Thanks @pelwell - I shall ask @XECDesign. I wouldn't want to goof around with config.txt during an upgrade - merely ensure that the correct overlay is part of the latest upgrade / release and then appending a line if it doesn't exist as part of the Debian package postinst. I shall also test the L-R swap now - thanks again for everything. |
OK @pelwell - strangely now when I add this overlay to Am I doing something silly here? I am as up-to-date as |
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
kernel: BCM270X_DT: Declare the audio PWM pins explicitly See: raspberrypi/linux#1473 kernel: Add support for Dion Audio LOCO DAC-AMP HAT See: raspberrypi/linux#1553 kernel: BCM270X_DT: Overlay to re-enable HW CS on SPI0 See: raspberrypi/linux#1547
kernel: config: Enable SERIAL_SC16IS7XX_SPI See: raspberrypi/linux#1594 kernel: Added Overlay for Microchip MCP23S08/17 SPI gpio expanders See: raspberrypi/linux#1566 kernel: BCM270X_DT: Add audio_pins to CM dtb kernel: BCM270X_DT: Don't enable UART0 in CM3 dtb kernel: overlays: Add audremap overlay kernel: overlays: Add swap_lr and enable_jack to audremap See: raspberrypi/linux#1473 firmware: Raspi[Still|Vid]Yuv: Add option for just saving luma See: raspberrypi/userland#170 firmware: RaspiVidYuv: Add option of saving RGB data firmware: Only change I2C/GPIO pin functions when needed firmware: platform: Redo the audio remapping logic See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Closing due to lack of activity. Reopen if you feel this issue is still relevant. |
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
[ Upstream commit 9a5a90d ] __netif_receive_skb_list_ptype() leaves skb->next poisoned before passing it to pt_prev->func handler, what may produce (in certain cases, e.g. DSA setup) crashes like: [ 88.606777] CPU 0 Unable to handle kernel paging request at virtual address 0000000e, epc == 80687078, ra == 8052cc7c [ 88.618666] Oops[#1]: [ 88.621196] CPU: 0 PID: 0 Comm: swapper Not tainted 5.1.0-rc2-dlink-00206-g4192a172-dirty #1473 [ 88.630885] $ 0 : 00000000 10000400 00000002 864d7850 [ 88.636709] $ 4 : 87c0ddf0 864d7800 87c0ddf0 00000000 [ 88.642526] $ 8 : 00000000 49600000 00000001 00000001 [ 88.648342] $12 : 00000000 c288617b dadbee27 25d17c41 [ 88.654159] $16 : 87c0ddf0 85cff080 80790000 fffffffd [ 88.659975] $20 : 80797b20 ffffffff 00000001 864d7800 [ 88.665793] $24 : 00000000 8011e658 [ 88.671609] $28 : 80790000 87c0dbc0 87cabf00 8052cc7c [ 88.677427] Hi : 00000003 [ 88.680622] Lo : 7b5b4220 [ 88.683840] epc : 80687078 vlan_dev_hard_start_xmit+0x1c/0x1a0 [ 88.690532] ra : 8052cc7c dev_hard_start_xmit+0xac/0x188 [ 88.696734] Status: 10000404 IEp [ 88.700422] Cause : 50000008 (ExcCode 02) [ 88.704874] BadVA : 0000000e [ 88.708069] PrId : 0001a120 (MIPS interAptiv (multi)) [ 88.713005] Modules linked in: [ 88.716407] Process swapper (pid: 0, threadinfo=(ptrval), task=(ptrval), tls=00000000) [ 88.725219] Stack : 85f61c28 00000000 0000000e 80780000 87c0ddf0 85cff080 80790000 8052cc7c [ 88.734529] 87cabf00 00000000 00000001 85f5fb40 807b0000 864d7850 87cabf00 807d0000 [ 88.743839] 864d7800 8655f600 00000000 85cff080 87c1c00 0000006a 00000000 8052d96c [ 88.753149] 807a0000 8057adb8 87c0dcc8 87c0dc50 85cfff08 00000558 87cabf00 85f58c50 [ 88.762460] 00000002 85f58c00 864d7800 80543308 fffffff4 00000001 85f58c00 864d7800 [ 88.771770] ... [ 88.774483] Call Trace: [ 88.777199] [<80687078>] vlan_dev_hard_start_xmit+0x1c/0x1a0 [ 88.783504] [<8052cc7c>] dev_hard_start_xmit+0xac/0x188 [ 88.789326] [<8052d96c>] __dev_queue_xmit+0x6e8/0x7d4 [ 88.794955] [<805a8640>] ip_finish_output2+0x238/0x4d0 [ 88.800677] [<805ab6a0>] ip_output+0xc8/0x140 [ 88.805526] [<805a68f4>] ip_forward+0x364/0x560 [ 88.810567] [<805a4ff8>] ip_rcv+0x48/0xe4 [ 88.815030] [<80528d44>] __netif_receive_skb_one_core+0x44/0x58 [ 88.821635] [<8067f220>] dsa_switch_rcv+0x108/0x1ac [ 88.827067] [<80528f80>] __netif_receive_skb_list_core+0x228/0x26c [ 88.833951] [<8052ed84>] netif_receive_skb_list+0x1d4/0x394 [ 88.840160] [<80355a88>] lunar_rx_poll+0x38c/0x828 [ 88.845496] [<8052fa78>] net_rx_action+0x14c/0x3cc [ 88.850835] [<806ad300>] __do_softirq+0x178/0x338 [ 88.856077] [<8012a2d4>] irq_exit+0xbc/0x100 [ 88.860846] [<802f8b70>] plat_irq_dispatch+0xc0/0x144 [ 88.866477] [<80105974>] handle_int+0x14c/0x158 [ 88.871516] [<806acfb0>] r4k_wait+0x30/0x40 [ 88.876462] Code: afb10014 8c8200a 00803025 <9443000c> 94a20468 00000000 10620042 00a08025 9605046a [ 88.887332] [ 88.888982] ---[ end trace eb863d007da11cf1 ]--- [ 88.894122] Kernel panic - not syncing: Fatal exception in interrupt [ 88.901202] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]--- Fix this by pulling skb off the sublist and zeroing skb->next pointer before calling ptype callback. Fixes: 88eb194 ("net: core: propagate SKB lists through packet_type lookup") Reviewed-by: Edward Cree <[email protected]> Signed-off-by: Alexander Lobakin <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
[ Upstream commit 9a5a90d ] __netif_receive_skb_list_ptype() leaves skb->next poisoned before passing it to pt_prev->func handler, what may produce (in certain cases, e.g. DSA setup) crashes like: [ 88.606777] CPU 0 Unable to handle kernel paging request at virtual address 0000000e, epc == 80687078, ra == 8052cc7c [ 88.618666] Oops[#1]: [ 88.621196] CPU: 0 PID: 0 Comm: swapper Not tainted 5.1.0-rc2-dlink-00206-g4192a172-dirty #1473 [ 88.630885] $ 0 : 00000000 10000400 00000002 864d7850 [ 88.636709] $ 4 : 87c0ddf0 864d7800 87c0ddf0 00000000 [ 88.642526] $ 8 : 00000000 49600000 00000001 00000001 [ 88.648342] $12 : 00000000 c288617b dadbee27 25d17c41 [ 88.654159] $16 : 87c0ddf0 85cff080 80790000 fffffffd [ 88.659975] $20 : 80797b20 ffffffff 00000001 864d7800 [ 88.665793] $24 : 00000000 8011e658 [ 88.671609] $28 : 80790000 87c0dbc0 87cabf00 8052cc7c [ 88.677427] Hi : 00000003 [ 88.680622] Lo : 7b5b4220 [ 88.683840] epc : 80687078 vlan_dev_hard_start_xmit+0x1c/0x1a0 [ 88.690532] ra : 8052cc7c dev_hard_start_xmit+0xac/0x188 [ 88.696734] Status: 10000404 IEp [ 88.700422] Cause : 50000008 (ExcCode 02) [ 88.704874] BadVA : 0000000e [ 88.708069] PrId : 0001a120 (MIPS interAptiv (multi)) [ 88.713005] Modules linked in: [ 88.716407] Process swapper (pid: 0, threadinfo=(ptrval), task=(ptrval), tls=00000000) [ 88.725219] Stack : 85f61c28 00000000 0000000e 80780000 87c0ddf0 85cff080 80790000 8052cc7c [ 88.734529] 87cabf00 00000000 00000001 85f5fb40 807b0000 864d7850 87cabf00 807d0000 [ 88.743839] 864d7800 8655f600 00000000 85cff080 87c1c00 0000006a 00000000 8052d96c [ 88.753149] 807a0000 8057adb8 87c0dcc8 87c0dc50 85cfff08 00000558 87cabf00 85f58c50 [ 88.762460] 00000002 85f58c00 864d7800 80543308 fffffff4 00000001 85f58c00 864d7800 [ 88.771770] ... [ 88.774483] Call Trace: [ 88.777199] [<80687078>] vlan_dev_hard_start_xmit+0x1c/0x1a0 [ 88.783504] [<8052cc7c>] dev_hard_start_xmit+0xac/0x188 [ 88.789326] [<8052d96c>] __dev_queue_xmit+0x6e8/0x7d4 [ 88.794955] [<805a8640>] ip_finish_output2+0x238/0x4d0 [ 88.800677] [<805ab6a0>] ip_output+0xc8/0x140 [ 88.805526] [<805a68f4>] ip_forward+0x364/0x560 [ 88.810567] [<805a4ff8>] ip_rcv+0x48/0xe4 [ 88.815030] [<80528d44>] __netif_receive_skb_one_core+0x44/0x58 [ 88.821635] [<8067f220>] dsa_switch_rcv+0x108/0x1ac [ 88.827067] [<80528f80>] __netif_receive_skb_list_core+0x228/0x26c [ 88.833951] [<8052ed84>] netif_receive_skb_list+0x1d4/0x394 [ 88.840160] [<80355a88>] lunar_rx_poll+0x38c/0x828 [ 88.845496] [<8052fa78>] net_rx_action+0x14c/0x3cc [ 88.850835] [<806ad300>] __do_softirq+0x178/0x338 [ 88.856077] [<8012a2d4>] irq_exit+0xbc/0x100 [ 88.860846] [<802f8b70>] plat_irq_dispatch+0xc0/0x144 [ 88.866477] [<80105974>] handle_int+0x14c/0x158 [ 88.871516] [<806acfb0>] r4k_wait+0x30/0x40 [ 88.876462] Code: afb10014 8c8200a 00803025 <9443000c> 94a20468 00000000 10620042 00a08025 9605046a [ 88.887332] [ 88.888982] ---[ end trace eb863d007da11cf1 ]--- [ 88.894122] Kernel panic - not syncing: Fatal exception in interrupt [ 88.901202] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]--- Fix this by pulling skb off the sublist and zeroing skb->next pointer before calling ptype callback. Fixes: 88eb194 ("net: core: propagate SKB lists through packet_type lookup") Reviewed-by: Edward Cree <[email protected]> Signed-off-by: Alexander Lobakin <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
Make the audio driver's use of the PWM functions explicit. Overlays that want to use the PWM functionality for other purposes must disable the audio node. See: raspberrypi/linux#1473 Signed-off-by: Phil Elwell <[email protected]>
swap_lr causes the channels to be reversed, and enable_jack prevents the headphone output from being disabled. See: raspberrypi/linux#1473
Hello - this is a follow-up to me showing my ignorance on the forums (and PhilE - who I imagine is @pelwell here) suggesting that I post a request here.
I am trying to remap the PWM audio from the pins connected to the onboard 3.5mm socket to pins 32 and 33 on the GPIO socket. So far I was achieving this by adding the following to /boot/config.txt
dtoverlay=pwm-2chan,pin=12,pin2=13,func=4,func2=4
However, as Phil points out this loads the driver twice (I think) and certainly also leaves audio coming out of the 3.5mm socket. Would it be possible to ask for someone's help in writing an overlay that actually remaps the audio properly? (and that the user can disable if they would like audio back in the normal place)
All help gratefully received.
The text was updated successfully, but these errors were encountered: