<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.sound">
    <title>gmane.linux.sound</title>
    <link>http://blog.gmane.org/gmane.linux.sound</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1741"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1740"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1739"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1738"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1737"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1736"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1735"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1734"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1733"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1731"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1727"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1723"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1715"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1707"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1695"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1694"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1693"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1689"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1680"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.sound/1678"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1741">
    <title>I Await Your Response</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1741</link>
    <description>&lt;pre&gt;I have attached a very important letter to this mail. Read thoroughly and reply back.
&lt;/pre&gt;</description>
    <dc:creator>Chris Morgan</dc:creator>
    <dc:date>2013-05-14T15:51:56</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1740">
    <title>s3c2443-uda134x sound driver problem</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1740</link>
    <description>&lt;pre&gt;Hello

I need to write a driver for codec uda134 installed on plat with processor s3c2443. I use driver for uda134 that is already in the kernel 3.6 (s3c24xx-uda134x) and IIS driver (s3c24xx-i2s). IIS driver is not compatible with processor s3c2443, and I changed in that iis registers and a few functions (attching patch). I have a problem with sound output. When audio file is playing sound interrupts (using alsa 1.0.26). Here is a part of debug output (output1.txt). Time between end of enqueue and start of the next buffdone is about 0.5 second, but expected is about 0.1 second. It seems that problem is size of dma buffer. I tried to forcibly change size of buffer
in kernel/linux/sound/soc/samsung/dma.c, line 212

prtd-&amp;gt;dma_end = prtd-&amp;gt;dma_end - (prtd-&amp;gt;dma_end - prtd-&amp;gt;dma_start)/2;    

and interrupt disappeared, but sound distorted. Here is a part of debug output is such conditions (output2.txt). Here time bitween end of enqueue and start of the next buffdone satisfactory

What may be the cause and how to fix it? please help

&lt;/pre&gt;</description>
    <dc:creator>Oleg</dc:creator>
    <dc:date>2013-05-01T13:14:32</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1739">
    <title>s3c2443-uda134x sound driver problem</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1739</link>
    <description>&lt;pre&gt;Hello

I need to write a driver for codec uda134 installed on plat with processor s3c2443. I use driver for uda134 that is already in the kernel version 3.6 (s3c24xx-uda134x) and IIS driver (s3c24xx-i2s). IIS driver is not compatible with processor s3c2443, and I changed in that iis registers and a few functions (attching patch). I have a problem with sound output. When audio file is playing sound interrupts (using alsa 1.0.26). Here is a part of debug output (output1.txt). Time between end of enqueue and start of the next buffdone is about 0.5 second, but expected is about 0.1 second. It seems that problem is size of dma buffer. I tried to forcibly change size of buffer
in kernel/linux/sound/soc/samsung/dma.c, line 212

prtd-&amp;gt;dma_end = prtd-&amp;gt;dma_end - (prtd-&amp;gt;dma_end - prtd-&amp;gt;dma_start)/2;

and interrupt disappeared, but sound distorted. Here is a part of debug output is such conditions (output2.txt). Here time bitween end of enqueue and start of the next buffdone satisfactory

What may be the cause and how to fix it? please help

&lt;/pre&gt;</description>
    <dc:creator>Oleg</dc:creator>
    <dc:date>2013-05-01T12:22:06</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1738">
    <title>Trying to get surround sound working on my Dell L702x Laptop</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1738</link>
    <description>&lt;pre&gt;I have a Dell L702x Laptop with an Intel Cougar Point HD Audio 
soundcard. In windows you are able to put it in analog surround sound 
mode - that is you have 3 3.5mm jacks running as output with 2 channels 
each. I am trying to replicate this behaviour so I can use the card as a 
6 channel output device with jack audio and ardour


(my setup works in stereo mode - now if i could just get the card to 
show 6 channels instead of just 2 - heck even 4 channels would be an 
improvement)
What do I need to do to make this work?

relevant sound routing:
soundcard &amp;gt; alsa &amp;gt; jack &amp;gt; aurdour  &amp;lt; pulse

  (I basically route all my sound through aurdor for effects processing 
- then out to the soundcard)



I'm running on Fedora 18
Dell XPS 17 L702x
i7 2670qm
16GB ram
265GB ssd

# lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation 2nd Generation Core 
Processor Family DRAM Controller [8086:0104] (rev 09)
00:01.0 PCI bridge [0604]: Intel Corporation Xeon E3-1200/2nd Generation 
Core Processor Family PCI Express Root Port [8086:0101] (rev 09)
00:02.0 VGA compatible controller [0300]: Intel Corporation 2nd 
Generation Core Processor Family Integrated Graphics Controller 
[8086:0126] (rev 09)
00:16.0 Communication controller [0780]: Intel Corporation 6 Series/C200 
Series Chipset Family MEI Controller #1 [8086:1c3a] (rev 04)
00:1a.0 USB controller [0c03]: Intel Corporation 6 Series/C200 Series 
Chipset Family USB Enhanced Host Controller #2 [8086:1c2d] (rev 05)
00:1b.0 Audio device [0403]: Intel Corporation 6 Series/C200 Series 
Chipset Family High Definition Audio Controller [8086:1c20] (rev 05)
00:1c.0 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series 
Chipset Family PCI Express Root Port 1 [8086:1c10] (rev b5)
00:1c.1 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series 
Chipset Family PCI Express Root Port 2 [8086:1c12] (rev b5)
00:1c.3 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series 
Chipset Family PCI Express Root Port 4 [8086:1c16] (rev b5)
00:1c.4 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series 
Chipset Family PCI Express Root Port 5 [8086:1c18] (rev b5)
00:1c.5 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series 
Chipset Family PCI Express Root Port 6 [8086:1c1a] (rev b5)
00:1d.0 USB controller [0c03]: Intel Corporation 6 Series/C200 Series 
Chipset Family USB Enhanced Host Controller #1 [8086:1c26] (rev 05)
00:1f.0 ISA bridge [0601]: Intel Corporation HM67 Express Chipset Family 
LPC Controller [8086:1c4b] (rev 05)
00:1f.2 SATA controller [0106]: Intel Corporation 6 Series/C200 Series 
Chipset Family 6 port SATA AHCI Controller [8086:1c03] (rev 05)
00:1f.3 SMBus [0c05]: Intel Corporation 6 Series/C200 Series Chipset 
Family SMBus Controller [8086:1c22] (rev 05)
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device 
[10de:1246] (rev ff)
03:00.0 Network controller [0280]: Intel Corporation Centrino Wireless-N 
1030 [Rainbow Peak] [8086:008a] (rev 34)
04:00.0 USB controller [0c03]: NEC Corporation uPD720200 USB 3.0 Host 
Controller [1033:0194] (rev 04)
0a:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. 
RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 06)


# uname -a
Linux localhost 3.8.5-201.fc18.x86_64 #1 SMP Thu Mar 28 21:01:19 UTC 
2013 x86_64 x86_64 x86_64 GNU/Linux


# lspci -nn |grep Audio
00:1b.0 Audio device [0403]: Intel Corporation 6 Series/C200 Series 
Chipset Family High Definition Audio Controller [8086:1c20] (rev 05)

# lspci -vnn -d 8086:1c20
00:1b.0 Audio device [0403]: Intel Corporation 6 Series/C200 Series 
Chipset Family High Definition Audio Controller [8086:1c20] (rev 05)
     Subsystem: Dell Device [1028:0571]
     Flags: bus master, fast devsel, latency 0, IRQ 56
     Memory at f3c00000 (64-bit, non-prefetchable) [size=16K]
     Capabilities: [50] Power Management version 2
     Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
     Capabilities: [70] Express Root Complex Integrated Endpoint, MSI 00
     Capabilities: [100] Virtual Channel
     Capabilities: [130] Root Complex Link
     Kernel driver in use: snd_hda_intel

# rpm -qa |grep alsa
alsa-lib-1.0.26-2.fc18.i686
alsa-plugins-pulseaudio-1.0.26-2.fc18.x86_64
alsa-tools-firmware-1.0.26.1-1.fc18.x86_64
alsa-lib-1.0.26-2.fc18.x86_64
alsa-utils-1.0.26-1.fc18.x86_64
alsa-firmware-1.0.25-2.fc18.noarch
alsa-lib-devel-1.0.26-2.fc18.x86_64
wine-alsa-1.5.24-1.fc18.x86_64
bluez-alsa-4.101-6.fc18.x86_64

# rpm -qa |grep jack
jack-audio-connection-kit-dbus-1.9.9.5-1.fc18.x86_64
qjackmmc-4-5.fc18.x86_64
qjackctl-0.3.9-3.fc18.x86_64
jack-audio-connection-kit-example-clients-1.9.9.5-1.fc18.x86_64
jack-keyboard-2.7.1-2.fc18.x86_64
jack-audio-connection-kit-1.9.9.5-1.fc18.x86_64
pulseaudio-module-jack-2.1-6.fc18.x86_64
jack-audio-connection-kit-devel-1.9.9.5-1.fc18.x86_64
jack-rack-1.4.7-12.fc18.x86_64
vlc-plugin-jack-2.0.5-5.fc18.x86_64
jack_capture-0.9.61-2.fc18.x86_64

--
To unsubscribe from this list: send the line "unsubscribe linux-sound" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Kronos</dc:creator>
    <dc:date>2013-04-27T18:32:16</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1737">
    <title>[RFC] Sound/HID: wiimote: add speaker support</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1737</link>
    <description>&lt;pre&gt;Classic Wii Remotes provide a speaker on the device. We can stream PCM
data, mute and change volume via special protocol requests and remote
audio registers.

The device supports several different formats, but fully understood are
only signed 8-bit PCM and something that looks like 4-bit Yamaha ADPCM.
Theoretically, we can set data-rates from 183Hz up to 12MHz, but a
realistic range for Bluetooth l2cap is 1500-4000 Hz.

Data is streamed as 20bytes blocks and must be sent in a constant rate.
There is no way to read the current position. It would be way too slow,
anyway.

Signed-off-by: David Herrmann &amp;lt;dh.herrmann&amp;lt; at &amp;gt;gmail.com&amp;gt;
---
Hi

I'm reworking large parts of the HID Nintendo Wii Remote driver and wanted to
add speaker support. I have never worked with the sound subsystem until now
and need some help.

The Wii Remote is a Bluetooth gamepad that features a small speaker on the
remote. All information was gathered via reverse-engineering so I cannot tell
you any specifics about the hardware, sorry. What I figured out so far is how
to set up the speaker, stream data, set volume and mute the speaker.

Supported formats are:
  signed 8-bit PCM
  4-bit Yamaha ADPCM

I implemented only the 8-bit PCM as I couldn't figure out whether the kernel
supports the other format?

The wiiproto_* helpers in hid-wiimote-core.c are used to send the requests.
Data is streamed as 20-bytes packets and must be sent at a constant rate.

I would really appreciate if someone can have a look at hid-wiimote-speaker.c
and help me fill the gaps. I figured out how to write the basic snd_card
management and PCM setup, but I am stuck with buffer management now.

I have a function called wiiproto_req_audio() which sends up to 20bytes of PCM
data to the device. However, I cannot figure out how to integrate that into the
snd_pcm object. The problem is that all other drivers I found have large DMA
buffers which are filled whenever an interrupt signals more data. However, I
don't have this setup but instead I need a timer (does the sound-core provide
that?) which causes the "copy" callback to be called with 20bytes of data at a
constant rate.

Any help welcome! And if this whole idea is stupid, please tell me! ;)

Thanks
David

 drivers/hid/Kconfig               |   3 +
 drivers/hid/Makefile              |   3 +
 drivers/hid/hid-wiimote-core.c    |  54 +++-
 drivers/hid/hid-wiimote-modules.c |   5 +
 drivers/hid/hid-wiimote-speaker.c | 539 ++++++++++++++++++++++++++++++++++++++
 drivers/hid/hid-wiimote.h         |  17 ++
 6 files changed, 619 insertions(+), 2 deletions(-)
 create mode 100644 drivers/hid/hid-wiimote-speaker.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e8ef86c..0b4d7e2 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -715,6 +715,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config HID_WIIMOTE
 the Wii U Gamepad) might be supported in the future. But currently
 support is limited to Bluetooth based devices.
 
+If Alsa sound support (CONFIG_SND) is enabled, this driver also provides
+a sound card interface for Wii Remote speakers.
+
 If unsure, say N.
 
 To compile this driver as a module, choose M here: the
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 8b7106b..d149e10 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -32,6 +32,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; hid-wiimote-y:= hid-wiimote-core.o hid-wiimote-modules.o
 ifdef CONFIG_DEBUG_FS
 hid-wiimote-y+= hid-wiimote-debug.o
 endif
+ifdef CONFIG_SND
+hid-wiimote-y+= hid-wiimote-speaker.o
+endif
 
 obj-$(CONFIG_HID_A4TECH)+= hid-a4tech.o
 obj-$(CONFIG_HID_ACRUX)+= hid-axff.o
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 906c146..53f1e88 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -17,6 +17,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;linux/module.h&amp;gt;
 #include &amp;lt;linux/mutex.h&amp;gt;
 #include &amp;lt;linux/spinlock.h&amp;gt;
+#include &amp;lt;linux/uaccess.h&amp;gt;
 #include "hid-ids.h"
 #include "hid-wiimote.h"
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -309,8 +310,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags)
 #define wiiproto_req_weeprom(wdata, os, buf, sz) \
 wiiproto_req_wmem((wdata), true, (os), (buf), (sz))
 
-static void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
-__u32 offset, const __u8 *buf, __u8 size)
+void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
+       __u32 offset, const __u8 *buf, __u8 size)
 {
 __u8 cmd[22];
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -359,6 +360,52 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom, __u32 offset,
 wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
+void wiiproto_req_speaker(struct wiimote_data *wdata, bool on)
+{
+__u8 cmd[2];
+
+cmd[0] = WIIPROTO_REQ_SPEAKER;
+cmd[1] = on ? 0x04 : 0x00;
+
+wiiproto_keep_rumble(wdata, &amp;amp;cmd[1]);
+wiimote_queue(wdata, cmd, sizeof(cmd));
+}
+
+void wiiproto_req_mute(struct wiimote_data *wdata, bool on)
+{
+__u8 cmd[2];
+
+cmd[0] = WIIPROTO_REQ_MUTE;
+cmd[1] = on ? 0x04 : 0x00;
+
+wiiproto_keep_rumble(wdata, &amp;amp;cmd[1]);
+wiimote_queue(wdata, cmd, sizeof(cmd));
+}
+
+/* must not be called from atomic contexts */
+int wiiproto_req_audio_user(struct wiimote_data *wdata,
+    void __user *buf, size_t len)
+{
+unsigned long flags;
+__u8 cmd[22];
+
+if (len &amp;gt; 20)
+len = 20;
+
+cmd[0] = WIIPROTO_REQ_AUDIO;
+cmd[1] = (len &amp;amp; 0xff) &amp;lt;&amp;lt; 3;
+
+if (copy_from_user(&amp;amp;cmd[2], buf, len))
+return -EFAULT;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+wiiproto_keep_rumble(wdata, &amp;amp;cmd[1]);
+wiimote_queue(wdata, cmd, sizeof(cmd));
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+return 0;
+}
+
 /* requries the cmd-mutex to be held */
 int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
 const __u8 *wmem, __u8 size)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -570,6 +617,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
 WIIMOD_LED4,
 WIIMOD_ACCEL,
 WIIMOD_IR,
+WIIMOD_SPEAKER,
 WIIMOD_NULL,
 },
 [WIIMOTE_DEV_GEN10] = (const __u8[]){
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -582,6 +630,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
 WIIMOD_LED4,
 WIIMOD_ACCEL,
 WIIMOD_IR,
+WIIMOD_SPEAKER,
 WIIMOD_NULL,
 },
 [WIIMOTE_DEV_GEN20] = (const __u8[]){
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -595,6 +644,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
 WIIMOD_ACCEL,
 WIIMOD_IR,
 WIIMOD_BUILTIN_MP,
+WIIMOD_SPEAKER,
 WIIMOD_NULL,
 },
 [WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) {
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 4ce0e02..7acf721 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2072,6 +2072,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = {
 [WIIMOD_IR] = &amp;amp;wiimod_ir,
 [WIIMOD_BUILTIN_MP] = &amp;amp;wiimod_builtin_mp,
 [WIIMOD_NO_MP] = &amp;amp;wiimod_no_mp,
+#ifdef CONFIG_SND
+[WIIMOD_SPEAKER] = &amp;amp;wiimod_speaker,
+#else
+[WIIMOD_SPEAKER] = &amp;amp;wiimod_dummy,
+#endif
 };
 
 const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
diff --git a/drivers/hid/hid-wiimote-speaker.c b/drivers/hid/hid-wiimote-speaker.c
new file mode 100644
index 0000000..ecec5d9
--- /dev/null
+++ b/drivers/hid/hid-wiimote-speaker.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,539 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Driver for audio speakers of Nintendo Wii / Wii U peripherals
+ * Copyright (c) 2012-2013 David Herrmann &amp;lt;dh.herrmann&amp;lt; at &amp;gt;gmail.com&amp;gt;
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/*
+ * Audio Speakers
+ * Some Wii peripherals provide an audio speaker that supports 8bit PCM and
+ * some other mostly unknown formats. Not all setup options are known, but we
+ * know how to setup an 8bit PCM or 4bit ADPCM stream and adjust volume. Data
+ * is sent as 20bytes chunks and needs to be streamed at a constant rate.
+ */
+
+#include &amp;lt;linux/device.h&amp;gt;
+#include &amp;lt;linux/hid.h&amp;gt;
+#include &amp;lt;linux/mutex.h&amp;gt;
+#include &amp;lt;linux/spinlock.h&amp;gt;
+#include &amp;lt;sound/control.h&amp;gt;
+#include &amp;lt;sound/core.h&amp;gt;
+#include &amp;lt;sound/initval.h&amp;gt;
+#include &amp;lt;sound/pcm.h&amp;gt;
+#include &amp;lt;sound/pcm_params.h&amp;gt;
+#include "hid-wiimote.h"
+
+struct wiimote_speaker {
+struct snd_card *card;
+unsigned int online : 1;
+unsigned int mute : 1;
+__u8 volume;
+};
+
+enum wiimod_speaker_mode {
+WIIMOD_SPEAKER_MODE_PCM8,
+WIIMOD_SPEAKER_MODE_ADPCM4,
+};
+
+static int wiimod_speaker_enable(struct wiimote_data *wdata)
+{
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+if (!speaker-&amp;gt;online) {
+speaker-&amp;gt;online = 1;
+wiiproto_req_speaker(wdata, true);
+wiiproto_req_mute(wdata, speaker-&amp;gt;mute);
+}
+
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+return 0;
+}
+
+static void wiimod_speaker_disable(struct wiimote_data *wdata)
+{
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+if (speaker-&amp;gt;online) {
+speaker-&amp;gt;online = 0;
+wiiproto_req_speaker(wdata, false);
+}
+
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+}
+
+static void wiimod_speaker_set_mute(struct wiimote_data *wdata, bool mute)
+{
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+if (speaker-&amp;gt;mute != mute) {
+speaker-&amp;gt;mute = mute;
+if (speaker-&amp;gt;online)
+wiiproto_req_mute(wdata, mute);
+}
+
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+}
+
+static void wiimod_speaker_set_volume(struct wiimote_data *wdata, __u8 volume)
+{
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+if (speaker-&amp;gt;volume != volume) {
+speaker-&amp;gt;volume = volume;
+if (speaker-&amp;gt;online)
+wiiproto_req_wmem(wdata, false, 0xa20005, &amp;amp;volume,
+  sizeof(volume));
+}
+
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+}
+
+/* Change speaker configuration. \mode can be one of WIIMOD_SPEAKER_MODE_*,
+ * \rate is the PCM sample rate and \volume is the requested volume. */
+static int wiimod_speaker_setup(struct wiimote_data *wdata,
+__u8 mode, __u16 rate, __s16 volume)
+{
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+__u8 config[7], m, wmem;
+__u16 r;
+int ret;
+
+if (!rate)
+return -EINVAL;
+
+switch (mode) {
+case WIIMOD_SPEAKER_MODE_PCM8:
+r = 12000000ULL / rate;
+m = 0x40;
+break;
+case WIIMOD_SPEAKER_MODE_ADPCM4:
+r = 6000000ULL / rate;
+m = 0x00;
+break;
+default:
+return -EINVAL;
+}
+
+config[0] = 0x00;
+config[1] = m;
+config[2] = r &amp;amp; 0x00ff;
+config[3] = (r &amp;amp; 0xff00) &amp;gt;&amp;gt; 8;
+config[4] = volume &amp;amp; 0xff;
+config[5] = 0x00;
+config[6] = 0x00;
+
+wiimote_cmd_acquire_noint(wdata);
+
+/* mute speaker during setup and read/write volume field */
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+wiiproto_req_mute(wdata, true);
+if (volume &amp;lt; 0)
+config[4] = speaker-&amp;gt;volume;
+else
+speaker-&amp;gt;volume = volume;
+
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+/* power speaker */
+wmem = 0x01;
+ret = wiimote_cmd_write(wdata, 0xa20009, &amp;amp;wmem, sizeof(wmem));
+if (ret)
+goto out_unlock;
+
+/* prepare setup */
+wmem = 0x08;
+ret = wiimote_cmd_write(wdata, 0xa20001, &amp;amp;wmem, sizeof(wmem));
+if (ret)
+goto out_unlock;
+
+/* write configuration */
+ret = wiimote_cmd_write(wdata, 0xa20001, config, sizeof(config));
+if (ret)
+goto out_unlock;
+
+/* enable speaker */
+wmem = 0x01;
+ret = wiimote_cmd_write(wdata, 0xa20008, &amp;amp;wmem, sizeof(wmem));
+if (ret)
+goto out_unlock;
+
+/* unmute speaker after setup if not muted */
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+if (!speaker-&amp;gt;mute)
+wiiproto_req_mute(wdata, false);
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+out_unlock:
+wiimote_cmd_release(wdata);
+return ret;
+}
+
+/* PCM layer */
+
+static const struct snd_pcm_hardware wiimod_speaker_playback_hw = {
+.info = SNDRV_PCM_INFO_NONINTERLEAVED,
+.formats = SNDRV_PCM_FMTBIT_S8,
+.rates = SNDRV_PCM_RATE_CONTINUOUS,
+.rate_min = 1500,
+.rate_max = 4000,
+.channels_min = 1,
+.channels_max = 1,
+.buffer_bytes_max = 20,
+.period_bytes_min = 20,
+.period_bytes_max = 20,
+.periods_min = 1,
+.periods_max = 1,
+};
+
+static int wiimod_speaker_playback_open(struct snd_pcm_substream *substream)
+{
+struct wiimote_data *wdata = snd_pcm_chip(substream);
+struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
+
+runtime-&amp;gt;hw = wiimod_speaker_playback_hw;
+runtime-&amp;gt;private_data = wdata;
+
+return wiimod_speaker_enable(wdata);
+}
+
+static int wiimod_speaker_playback_close(struct snd_pcm_substream *substream)
+{
+struct wiimote_data *wdata = snd_pcm_chip(substream);
+
+wiimod_speaker_disable(wdata);
+
+return 0;
+}
+
+static int wiimod_speaker_playback_hw_params(struct snd_pcm_substream *subs,
+     struct snd_pcm_hw_params *hw)
+{
+/* TODO: anything to do here? */
+
+return 0;
+}
+
+static int wiimod_speaker_playback_hw_free(struct snd_pcm_substream *subs)
+{
+return 0;
+}
+
+static int wiimod_speaker_playback_prepare(struct snd_pcm_substream *subs)
+{
+struct wiimote_data *wdata = snd_pcm_chip(subs);
+struct snd_pcm_runtime *runtime = subs-&amp;gt;runtime;
+size_t buf_size, period_size, periods;
+int ret;
+
+/* TODO: If I have set the hw-params to a fixed 20 bytes buffer, do
+ * I actually need to do any computations here? */
+buf_size = frames_to_bytes(runtime, runtime-&amp;gt;buffer_size);
+period_size = frames_to_bytes(runtime, runtime-&amp;gt;period_size);
+periods = runtime-&amp;gt;periods;
+
+switch (runtime-&amp;gt;format) {
+case SNDRV_PCM_FMTBIT_S8:
+ret = wiimod_speaker_setup(wdata, WIIMOD_SPEAKER_MODE_PCM8,
+   runtime-&amp;gt;rate, -1);
+break;
+default:
+return -EINVAL;
+}
+
+return ret;
+}
+
+static int wiimod_speaker_playback_trigger(struct snd_pcm_substream *subs,
+   int cmd)
+{
+struct wiimote_data *wdata = snd_pcm_chip(subs);
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+switch (cmd) {
+case SNDRV_PCM_TRIGGER_RESUME:
+case SNDRV_PCM_TRIGGER_START:
+/* unmute device on start if not muted by user-space */
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+if (!speaker-&amp;gt;mute)
+wiiproto_req_mute(wdata, false);
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+break;
+case SNDRV_PCM_TRIGGER_SUSPEND:
+case SNDRV_PCM_TRIGGER_STOP:
+/* mute device when stopping transmission */
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+wiiproto_req_mute(wdata, true);
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+break;
+}
+
+return 0;
+}
+
+static snd_pcm_uframes_t wiimod_speaker_playback_pointer(struct snd_pcm_substream *subs)
+{
+struct wiimote_data *wdata = snd_pcm_chip(subs);
+unsigned long pos;
+
+/* There is no way to read the current position. Even if there was a
+ * way to do that, it would be so slow that it would be useless.
+ * TODO: Should we interpolate via a timer? Is this function actually
+ * needed? When is it called? */
+pos = 0;
+
+pos %= 20;
+
+return bytes_to_frames(subs-&amp;gt;runtime, pos);
+}
+
+static int wiimod_speaker_playback_copy(struct snd_pcm_substream *subs,
+int channel, snd_pcm_uframes_t pos,
+void __user *buf,
+snd_pcm_uframes_t count)
+{
+struct wiimote_data *wdata = snd_pcm_chip(subs);
+struct snd_pcm_runtime *runtime = subs-&amp;gt;runtime;
+
+count = frames_to_bytes(runtime, count);
+pos = frames_to_bytes(runtime, pos);
+
+/* TODO: copy from "buf" "count" bytes to "protobuf + pos"
+ * With the given hw-params, can pos be non-zero? Can count != 20?
+ * If not, should I simply send a 20byte frame to the device here? */
+
+return 0;
+}
+
+static int wiimod_speaker_playback_silence(struct snd_pcm_substream *subs,
+   int channel, snd_pcm_uframes_t pos,
+   snd_pcm_uframes_t count)
+{
+struct wiimote_data *wdata = snd_pcm_chip(subs);
+struct snd_pcm_runtime *runtime = subs-&amp;gt;runtime;
+
+count = frames_to_bytes(runtime, count);
+pos = frames_to_bytes(runtime, pos);
+
+/* TODO: set "count" bytes of "protobuf + pos" to zero
+ * Can "pos" actually be non-zero with the given hw-params? If not,
+ * can I simply send a 20byte zeroed frame to the remote device? */
+
+return 0;
+}
+
+/* TODO: is there a reason this cannot be "const"? */
+static struct snd_pcm_ops wiimod_speaker_playback_ops = {
+.open= wiimod_speaker_playback_open,
+.close= wiimod_speaker_playback_close,
+.ioctl= snd_pcm_lib_ioctl,
+.hw_params= wiimod_speaker_playback_hw_params,
+.hw_free= wiimod_speaker_playback_hw_free,
+.prepare= wiimod_speaker_playback_prepare,
+.trigger= wiimod_speaker_playback_trigger,
+.pointer= wiimod_speaker_playback_pointer,
+.copy= wiimod_speaker_playback_copy,
+.silence= wiimod_speaker_playback_silence,
+};
+
+/* volume control */
+
+static int wiimod_speaker_volume_info(struct snd_kcontrol *kcontrol,
+      struct snd_ctl_elem_info *info)
+{
+info-&amp;gt;type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+info-&amp;gt;count = 1;
+info-&amp;gt;value.integer.min = 0;
+info-&amp;gt;value.integer.max = 0xff;
+
+return 0;
+}
+
+static int wiimod_speaker_volume_get(struct snd_kcontrol *kcontrol,
+     struct snd_ctl_elem_value *val)
+{
+struct wiimote_data *wdata = snd_kcontrol_chip(kcontrol);
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+val-&amp;gt;value.integer.value[0] = speaker-&amp;gt;volume;
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+return 0;
+}
+
+static int wiimod_speaker_volume_put(struct snd_kcontrol *kcontrol,
+     struct snd_ctl_elem_value *val)
+{
+struct wiimote_data *wdata = snd_kcontrol_chip(kcontrol);
+unsigned long value;
+
+value = val-&amp;gt;value.integer.value[0];
+if (value &amp;gt; 0xff)
+value = 0xff;
+
+wiimod_speaker_set_volume(wdata, value);
+
+return 0;
+}
+
+static const struct snd_kcontrol_new wiimod_speaker_volume = {
+.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+.name = "PCM Playback Volume",
+.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+.info = wiimod_speaker_volume_info,
+.get = wiimod_speaker_volume_get,
+.put = wiimod_speaker_volume_put,
+};
+
+/* mute control */
+
+static int wiimod_speaker_mute_get(struct snd_kcontrol *kcontrol,
+   struct snd_ctl_elem_value *val)
+{
+struct wiimote_data *wdata = snd_kcontrol_chip(kcontrol);
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+unsigned long flags;
+
+spin_lock_irqsave(&amp;amp;wdata-&amp;gt;state.lock, flags);
+val-&amp;gt;value.integer.value[0] = !!speaker-&amp;gt;mute;
+spin_unlock_irqrestore(&amp;amp;wdata-&amp;gt;state.lock, flags);
+
+return 0;
+}
+
+static int wiimod_speaker_mute_put(struct snd_kcontrol *kcontrol,
+   struct snd_ctl_elem_value *val)
+{
+struct wiimote_data *wdata = snd_kcontrol_chip(kcontrol);
+
+wiimod_speaker_set_mute(wdata, val-&amp;gt;value.integer.value[0]);
+
+return 0;
+}
+
+/* TODO: Is *_IFACE_CARD the right interface? */
+static const struct snd_kcontrol_new wiimod_speaker_mute = {
+.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+.name = "PCM Playback Switch",
+.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+.info = snd_ctl_boolean_mono_info,
+.get = wiimod_speaker_mute_get,
+.put = wiimod_speaker_mute_put,
+};
+
+/* initialization and setup */
+
+static int wiimod_speaker_probe(const struct wiimod_ops *ops,
+struct wiimote_data *wdata)
+{
+int ret;
+struct wiimote_speaker *speaker;
+struct snd_card *card;
+struct snd_kcontrol *kcontrol;
+struct snd_pcm *pcm;
+
+/* create sound card device */
+ret = snd_card_create(-1, NULL, THIS_MODULE,
+      sizeof(struct wiimote_speaker), &amp;amp;card);
+if (ret)
+return ret;
+speaker = card-&amp;gt;private_data;
+
+wdata-&amp;gt;speaker = speaker;
+speaker-&amp;gt;card = card;
+speaker-&amp;gt;mute = 1;
+speaker-&amp;gt;volume = 0xff;
+strcpy(card-&amp;gt;driver, "hid-wiimote");
+strcpy(card-&amp;gt;shortname, "wiimote");
+strcpy(card-&amp;gt;longname, "Nintendo Wii Remote speaker");
+
+/* create volume control */
+kcontrol = snd_ctl_new1(&amp;amp;wiimod_speaker_volume, wdata);
+if (!kcontrol) {
+ret = -ENOMEM;
+goto err_free;
+}
+
+ret = snd_ctl_add(card, kcontrol);
+if (ret) {
+snd_ctl_free_one(kcontrol);
+goto err_free;
+}
+
+/* create mute control */
+kcontrol = snd_ctl_new1(&amp;amp;wiimod_speaker_mute, wdata);
+if (!kcontrol) {
+ret = -ENOMEM;
+goto err_free;
+}
+
+ret = snd_ctl_add(card, kcontrol);
+if (ret) {
+snd_ctl_free_one(kcontrol);
+goto err_free;
+}
+
+/* create PCM sub-device for playback */
+ret = snd_pcm_new(card, "Speaker", 0, 1, 0, &amp;amp;pcm);
+if (ret)
+goto err_free;
+
+snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+&amp;amp;wiimod_speaker_playback_ops);
+pcm-&amp;gt;private_data = wdata;
+
+/* register sound card */
+snd_card_set_dev(card, &amp;amp;wdata-&amp;gt;hdev-&amp;gt;dev);
+ret = snd_card_register(card);
+if (ret)
+goto err_free;
+
+return 0;
+
+err_free:
+snd_card_free(card);
+wdata-&amp;gt;speaker = NULL;
+return ret;
+}
+
+static void wiimod_speaker_remove(const struct wiimod_ops *ops,
+  struct wiimote_data *wdata)
+{
+struct wiimote_speaker *speaker = wdata-&amp;gt;speaker;
+
+if (!speaker)
+return;
+
+snd_card_free_when_closed(speaker-&amp;gt;card);
+wdata-&amp;gt;speaker = NULL;
+}
+
+const struct wiimod_ops wiimod_speaker = {
+.flags = 0,
+.arg = 0,
+.probe = wiimod_speaker_probe,
+.remove = wiimod_speaker_remove,
+};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 30caef5..4907bc7 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -148,6 +148,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct wiimote_data {
 struct timer_list timer;
 struct wiimote_ext *ext;
 struct wiimote_debug *debug;
+struct wiimote_speaker *speaker;
 
 union {
 struct input_dev *input;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -172,6 +173,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum wiimod_module {
 WIIMOD_IR,
 WIIMOD_BUILTIN_MP,
 WIIMOD_NO_MP,
+WIIMOD_SPEAKER,
 WIIMOD_NUM,
 WIIMOD_NULL = WIIMOD_NUM,
 };
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -208,9 +210,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum wiiproto_reqs {
 WIIPROTO_REQ_LED = 0x11,
 WIIPROTO_REQ_DRM = 0x12,
 WIIPROTO_REQ_IR1 = 0x13,
+WIIPROTO_REQ_SPEAKER = 0x14,
 WIIPROTO_REQ_SREQ = 0x15,
 WIIPROTO_REQ_WMEM = 0x16,
 WIIPROTO_REQ_RMEM = 0x17,
+WIIPROTO_REQ_AUDIO = 0x18,
+WIIPROTO_REQ_MUTE = 0x19,
 WIIPROTO_REQ_IR2 = 0x1a,
 WIIPROTO_REQ_STATUS = 0x20,
 WIIPROTO_REQ_DATA = 0x21,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -241,6 +246,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern void wiiproto_req_status(struct wiimote_data *wdata);
 extern void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel);
 extern void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags);
 extern void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags);
+extern void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
+      __u32 offset, const __u8 *buf, __u8 size);
+extern void wiiproto_req_speaker(struct wiimote_data *wdata, bool on);
+extern void wiiproto_req_mute(struct wiimote_data *wdata, bool on);
+extern int wiiproto_req_audio_user(struct wiimote_data *wdata,
+   void __user *buf, size_t len);
 extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
 const __u8 *wmem, __u8 size);
 extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -283,6 +294,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void wiidebug_deinit(void *u) { }
 
 #endif
 
+#ifdef CONFIG_SND
+
+extern const struct wiimod_ops wiimod_speaker;
+
+#endif
+
 /* requires the state.lock spinlock to be held */
 static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd,
 __u32 opt)
&lt;/pre&gt;</description>
    <dc:creator>David Herrmann</dc:creator>
    <dc:date>2013-04-20T18:07:53</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1736">
    <title>Hello,</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1736</link>
    <description>&lt;pre&gt;

Hello,
I have information for you about an unclaimed funds in my department.
Please get back to me if interested so I would brief you in details.
Email: mr.lan_lee&amp;lt; at &amp;gt;fengv.com
Regards,
Mr.Lan Lee 
--
To unsubscribe from this list: send the line "unsubscribe linux-sound" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Mr.Lan Lee</dc:creator>
    <dc:date>2013-03-13T20:15:25</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1735">
    <title>Please Refer to Attach Letter and Reply Urgently</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1735</link>
    <description>&lt;pre&gt;
 &lt;/pre&gt;</description>
    <dc:creator>Mrs. Mary  Kamal</dc:creator>
    <dc:date>2013-02-06T11:15:29</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1734">
    <title>From Mrs. Doris Kula</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1734</link>
    <description>&lt;pre&gt;PLEASE OPEN ATTACHMENT FOR MY LETTER TO YOU&lt;/pre&gt;</description>
    <dc:creator>From Mrs. Doris Kula</dc:creator>
    <dc:date>2013-02-05T13:37:18</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1733">
    <title>From Mrs. Doris Kula</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1733</link>
    <description>&lt;pre&gt;PLEASE OPEN ATTACHMENT FOR MY LETTER TO YOU&lt;/pre&gt;</description>
    <dc:creator>From Mrs. Doris Kula</dc:creator>
    <dc:date>2013-02-05T06:55:36</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1731">
    <title>From Mrs. Doris Kula</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1731</link>
    <description>&lt;pre&gt;PLEASE OPEN ATTACHMENT FOR MY LETTER TO YOU&lt;/pre&gt;</description>
    <dc:creator>From Mrs. Doris Kula</dc:creator>
    <dc:date>2013-02-04T12:50:44</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1727">
    <title>[PATCH 0/4] ASoC: atmel: fixes for working as module</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1727</link>
    <description>&lt;pre&gt;The following patches fixes the audio part when working as module

Bo Shen (4):
  ASoC: atmel_pcm: make it buildable as module
  ASoC: atmel_ssc_dai: remove error set private data
  ASoC: atmel_ssc_dai: correct sequence when unload
  ASoC: sam9g20_wm8731: disable clock and correct sequence when unload

 sound/soc/atmel/atmel-pcm.h      |    6 ++++--
 sound/soc/atmel/atmel_ssc_dai.c  |   12 +-----------
 sound/soc/atmel/sam9g20_wm8731.c |    6 +++---
 3 files changed, 8 insertions(+), 16 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Bo Shen</dc:creator>
    <dc:date>2013-01-31T03:53:36</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1723">
    <title>Sound/ARM/i.MX/SSI: fix SDMA starvation</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1723</link>
    <description>&lt;pre&gt;In cases when capturing is already running and someone enables also
playback, the SDMA unit of the i.MX SoC does not see an edge on its TX DMA
request line. This is due to the TX FIFOs are empty, and this request line is
active all the time, when the CCSR_SSI_SIER_TDMAE bit is set.
In this case also the TX FIFO underrun interrupt will flood the system forever.

To ensure the first edge happens after enabling the TX side of the SSI unit and
to trigger the SDMA unit successfully enable the CCSR_SSI_SIER_TDMAE on
demand only. To be sure, this patch does the same for the CCSR_SSI_SIER_RDMAE
(RX side) bit.

Signed-off-by: Juergen Beisert &amp;lt;jbe&amp;lt; at &amp;gt;pengutronix.de&amp;gt;

---
 sound/soc/fsl/fsl_ssi.c |   24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

Index: linux.git/sound/soc/fsl/fsl_ssi.c
===================================================================
--- linux.git.orig/sound/soc/fsl/fsl_ssi.c
+++ linux.git/sound/soc/fsl/fsl_ssi.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -86,10 +86,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void write_ssi_mask(u32 __
 #endif
 
 /* SIER bitflag of interrupts to enable */
-#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
-    CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
-    CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
-    CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
+#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TIE | \
+    CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TUE1_EN | \
+    CCSR_SSI_SIER_RFRC_EN | CCSR_SSI_SIER_RIE | \
     CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
 
 /**
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -489,6 +488,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int fsl_ssi_hw_params(struct snd_
  *
  * The DMA channel is in external master start and pause mode, which
  * means the SSI completely controls the flow of data.
+ *
+ * To use the i.MX's SDMA unit it is important to create an edge on the
+ * corresponding request line. Otherwise the request will be ignored!
  */
 static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
    struct snd_soc_dai *dai)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -500,20 +502,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int fsl_ssi_trigger(struct snd_pc
 switch (cmd) {
 case SNDRV_PCM_TRIGGER_START:
 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-if (substream-&amp;gt;stream == SNDRV_PCM_STREAM_PLAYBACK)
+if (substream-&amp;gt;stream == SNDRV_PCM_STREAM_PLAYBACK) {
 write_ssi_mask(&amp;amp;ssi-&amp;gt;scr, 0,
 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
-else
+write_ssi_mask(&amp;amp;ssi-&amp;gt;sier, 0, CCSR_SSI_SIER_TDMAE);
+} else {
 write_ssi_mask(&amp;amp;ssi-&amp;gt;scr, 0,
 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
+write_ssi_mask(&amp;amp;ssi-&amp;gt;sier, 0, CCSR_SSI_SIER_RDMAE);
+}
 break;
 
 case SNDRV_PCM_TRIGGER_STOP:
 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-if (substream-&amp;gt;stream == SNDRV_PCM_STREAM_PLAYBACK)
+if (substream-&amp;gt;stream == SNDRV_PCM_STREAM_PLAYBACK) {
 write_ssi_mask(&amp;amp;ssi-&amp;gt;scr, CCSR_SSI_SCR_TE, 0);
-else
+write_ssi_mask(&amp;amp;ssi-&amp;gt;sier, CCSR_SSI_SIER_TDMAE, 0);
+} else {
 write_ssi_mask(&amp;amp;ssi-&amp;gt;scr, CCSR_SSI_SCR_RE, 0);
+write_ssi_mask(&amp;amp;ssi-&amp;gt;sier, CCSR_SSI_SIER_RDMAE, 0);
+}
 break;
 
 default:

&lt;/pre&gt;</description>
    <dc:creator>Juergen Beisert</dc:creator>
    <dc:date>2013-01-24T08:56:30</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1715">
    <title>[PATCH 0/2 v2] at91/ssc: fixes on ASoC tree for 3.8</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1715</link>
    <description>&lt;pre&gt;Hi Mark, Olof, Arnd,

This series goes on top of Linus' v3.8-rc3 and fixes an error that
we have while compiling DTBs for AT91:
ERROR (phandle_references): Reference to non-existent node or label
"pinctrl_ssc0_tx"

ERROR: Input tree has errors, aborting (use -f to force output)
make[3]: *** [arch/arm/boot/dts/at91sam9g20ek.dtb] Error 2

I have included pending material that is dealing with SSC and pinctrl. The
pinctrl part can be merged more easily now that the big pinctrl update for AT91
has been merged upstream.

This material was designed to enter Mark's fixes queue, but as discussed with
Olof, we can imagine merging everything through arm-soc or split the series (of
2 patches) and let them progress upstream separated (option that I do not like
even if I know that the consequences are not so dramatic).
So please, Olof, if you feel confortable with this series, tell us what you
prefer and we will make our best to make this material go forward...

Thanks for your help, best regards,

v2: - remove the fix for typo in SSC status property: already merged upstream

Bo Shen (2):
  ARM: at91/dts: add pinctrl support for SSC peripheral
  ASoC: atmel-ssc: add pinctrl selection to driver

 arch/arm/boot/dts/at91sam9260.dtsi | 18 ++++++++++++++++++
 arch/arm/boot/dts/at91sam9263.dtsi | 36 ++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9g45.dtsi | 36 ++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9n12.dtsi | 26 ++++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9x5.dtsi  | 32 +++++++++++++++++++++++++-------
 drivers/misc/atmel-ssc.c           |  8 ++++++++
 6 files changed, 149 insertions(+), 7 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Nicolas Ferre</dc:creator>
    <dc:date>2013-01-11T14:08:29</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1707">
    <title>[PATCH 0/3] at91/ssc: fixes on ASoC tree for 3.8</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1707</link>
    <description>&lt;pre&gt;Hi Mark,

This series goes on top of current Linus' git tree and fixes an error that
we have while compiling DTBs for AT91:
ERROR (phandle_references): Reference to non-existent node or label
"pinctrl_ssc0_tx"

ERROR: Input tree has errors, aborting (use -f to force output)
make[3]: *** [arch/arm/boot/dts/at91sam9g20ek.dtb] Error 2

I have included pending material that is dealing with SSC and pinctrl. The
pinctrl part can be merged more easily now that the big pinctrl update for AT91
has been merged upstream.
I have also included a typo patch that you have already taken as 315656b (ASoC:
atmel-ssc: change disable to disable in dts node) in your topic/atmel branch
but that was not described properly.

If you find it easier, I can provide you a git tree for this material: just
tell me...

Thanks for your help, best regards,


Bo Shen (3):
  ARM: at91/dts: fix typo in SSC status property
  ARM: at91/dts: add pinctrl support for SSC peripheral
  ASoC: atmel-ssc: add pinctrl selection to driver

 arch/arm/boot/dts/at91sam9260.dtsi | 18 +++++++++++++++++
 arch/arm/boot/dts/at91sam9263.dtsi | 40 ++++++++++++++++++++++++++++++++++++--
 arch/arm/boot/dts/at91sam9g45.dtsi | 40 ++++++++++++++++++++++++++++++++++++--
 arch/arm/boot/dts/at91sam9n12.dtsi | 26 +++++++++++++++++++++++++
 arch/arm/boot/dts/at91sam9x5.dtsi  | 32 +++++++++++++++++++++++-------
 drivers/misc/atmel-ssc.c           |  8 ++++++++
 6 files changed, 153 insertions(+), 11 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Nicolas Ferre</dc:creator>
    <dc:date>2012-12-17T11:23:23</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1695">
    <title>Open the attached file for Partnership &amp; Investment. Confidential.</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1695</link>
    <description>&lt;pre&gt;
&lt;/pre&gt;</description>
    <dc:creator>Mrs. Keyondria Nkiambi</dc:creator>
    <dc:date>2012-12-08T19:25:46</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1694">
    <title>[PATCH] ASoC: atmel-soc: make it buildable on other architectures</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1694</link>
    <description>&lt;pre&gt;Not very useful on non AT91/AVR32 platforms but it provides
more build coverage and prepares for ARM multiplatform.

Also fixes a couple of format type warnings.

Signed-off-by: Joachim Eastwood &amp;lt;manabian&amp;lt; at &amp;gt;gmail.com&amp;gt;
---

Hi,

Build tested on RM9200 and x86_64.

ARCH_AT91 depend is pushed down to the machine drivers
since they still relies on mach includes.

regards
Joachim Eastwood

 sound/soc/atmel/Kconfig         | 6 +++---
 sound/soc/atmel/atmel-pcm-pdc.c | 4 ++--
 sound/soc/atmel/atmel-pcm.c     | 2 +-
 sound/soc/atmel/atmel_ssc_dai.c | 2 --
 4 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index d1b691b..3fdd87f 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,6 +1,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 config SND_ATMEL_SOC
 tristate "SoC Audio for the Atmel System-on-Chip"
-depends on ARCH_AT91
+depends on HAS_IOMEM
 help
   Say Y or M if you want to add support for codecs attached to
   the ATMEL SSC interface. You will also need
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -24,7 +24,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config SND_ATMEL_SOC_SSC
 
 config SND_AT91_SOC_SAM9G20_WM8731
 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
-depends on ATMEL_SSC &amp;amp;&amp;amp; SND_ATMEL_SOC &amp;amp;&amp;amp; AT91_PROGRAMMABLE_CLOCKS
+depends on ARCH_AT91 &amp;amp;&amp;amp; ATMEL_SSC &amp;amp;&amp;amp; SND_ATMEL_SOC &amp;amp;&amp;amp; AT91_PROGRAMMABLE_CLOCKS
 select SND_ATMEL_SOC_PDC
 select SND_ATMEL_SOC_SSC
 select SND_SOC_WM8731
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -34,7 +34,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config SND_AT91_SOC_SAM9G20_WM8731
 
 config SND_AT91_SOC_AFEB9260
 tristate "SoC Audio support for AFEB9260 board"
-depends on ATMEL_SSC &amp;amp;&amp;amp; ARCH_AT91 &amp;amp;&amp;amp; MACH_AFEB9260 &amp;amp;&amp;amp; SND_ATMEL_SOC
+depends on ARCH_AT91 &amp;amp;&amp;amp; ATMEL_SSC &amp;amp;&amp;amp; ARCH_AT91 &amp;amp;&amp;amp; MACH_AFEB9260 &amp;amp;&amp;amp; SND_ATMEL_SOC
 select SND_ATMEL_SOC_PDC
 select SND_ATMEL_SOC_SSC
 select SND_SOC_TLV320AIC23
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index 6a293c7..054ea4d 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -159,7 +159,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
 
 pr_debug("atmel-pcm: "
 "hw_params: DMA for %s initialized "
-"(dma_bytes=%u, period_size=%u)\n",
+"(dma_bytes=%zu, period_size=%zu)\n",
 prtd-&amp;gt;params-&amp;gt;name,
 runtime-&amp;gt;dma_bytes,
 prtd-&amp;gt;period_size);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -201,7 +201,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
 int ret = 0;
 
 pr_debug("atmel-pcm:buffer_size = %ld,"
-"dma_area = %p, dma_bytes = %u\n",
+"dma_area = %p, dma_bytes = %zu\n",
 rtd-&amp;gt;buffer_size, rtd-&amp;gt;dma_area, rtd-&amp;gt;dma_bytes);
 
 switch (cmd) {
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index e99f181..3109db7 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -49,7 +49,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
 buf-&amp;gt;private_data = NULL;
 buf-&amp;gt;area = dma_alloc_coherent(pcm-&amp;gt;card-&amp;gt;dev, size,
 &amp;amp;buf-&amp;gt;addr, GFP_KERNEL);
-pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n",
+pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
 (void *)buf-&amp;gt;area, (void *)buf-&amp;gt;addr, size);
 
 if (!buf-&amp;gt;area)
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 1c76634..2755750 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -42,8 +42,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;sound/initval.h&amp;gt;
 #include &amp;lt;sound/soc.h&amp;gt;
 
-#include &amp;lt;mach/hardware.h&amp;gt;
-
 #include "atmel-pcm.h"
 #include "atmel_ssc_dai.h"
 
&lt;/pre&gt;</description>
    <dc:creator>Joachim Eastwood</dc:creator>
    <dc:date>2012-12-08T13:23:22</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1693">
    <title>[PATCH] ASoC: atmel-ssc: make it buildable on other architectures</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1693</link>
    <description>&lt;pre&gt;Not very useful on non AT91/AVR32 platforms but it provides
more build coverage and prepares for ARM multiplatform.

Also fixes a truncated warning that would come when
building on a 64-bit arch.

Signed-off-by: Joachim Eastwood &amp;lt;manabian&amp;lt; at &amp;gt;gmail.com&amp;gt;
---

Hi Mark,

Sending it to you since seem like you're the last one who
commited changes to the driver and the driver is mostly
used on ASoC.

Tested on RM9200 and build tested on x86_64.

regards
Joachim Eastwood

 drivers/misc/Kconfig     | 2 +-
 drivers/misc/atmel-ssc.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b151b7c..8f59d88 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -192,7 +192,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config ICS932S401
 
 config ATMEL_SSC
 tristate "Device driver for Atmel SSC peripheral"
-depends on AVR32 || ARCH_AT91
+depends on HAS_IOMEM
 ---help---
   This option enables device driver support for Atmel Synchronized
   Serial Communication peripheral (SSC).
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index 158da5a..0cee274 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -167,7 +167,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int ssc_probe(struct platform_device *pdev)
 
 /* disable all interrupts */
 clk_enable(ssc-&amp;gt;clk);
-ssc_writel(ssc-&amp;gt;regs, IDR, ~0UL);
+ssc_writel(ssc-&amp;gt;regs, IDR, -1);
 ssc_readl(ssc-&amp;gt;regs, SR);
 clk_disable(ssc-&amp;gt;clk);
 
&lt;/pre&gt;</description>
    <dc:creator>Joachim Eastwood</dc:creator>
    <dc:date>2012-12-08T12:46:41</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1689">
    <title>[PATCH 1/2] ASoC: atmel-pcm: split into two file</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1689</link>
    <description>&lt;pre&gt;This patch is split original atmel-pcm.c into new atmel-pcm.c and
atmel-pcm-pdc.c two files. The new atmel-pcm.c is the share routine
while will be used for pdc or dma transfer.

Using SND_ATMEL_SOC_PDC to select using PDC for audio transfer

Signed-off-by: Bo Shen &amp;lt;voice.shen&amp;lt; at &amp;gt;atmel.com&amp;gt;
---
 sound/soc/atmel/Kconfig         |    5 +
 sound/soc/atmel/Makefile        |    2 +
 sound/soc/atmel/atmel-pcm-pdc.c |  401 +++++++++++++++++++++++++++++++++++++++
 sound/soc/atmel/atmel-pcm.c     |  390 ++-----------------------------------
 sound/soc/atmel/atmel-pcm.h     |   21 +-
 sound/soc/atmel/atmel_ssc_dai.c |    4 +-
 6 files changed, 441 insertions(+), 382 deletions(-)
 create mode 100644 sound/soc/atmel/atmel-pcm-pdc.c

diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 397ec75..6051993 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -6,6 +6,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config SND_ATMEL_SOC
   the ATMEL SSC interface. You will also need
   to select the audio interfaces to support below.
 
+config SND_ATMEL_SOC_PDC
+tristate
+depends on SND_ATMEL_SOC
+
 config SND_ATMEL_SOC_SSC
 tristate
 depends on SND_ATMEL_SOC
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -17,6 +21,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config SND_ATMEL_SOC_SSC
 config SND_AT91_SOC_SAM9G20_WM8731
 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
 depends on ATMEL_SSC &amp;amp;&amp;amp; SND_ATMEL_SOC &amp;amp;&amp;amp; AT91_PROGRAMMABLE_CLOCKS
+select SND_ATMEL_SOC_PDC
 select SND_ATMEL_SOC_SSC
 select SND_SOC_WM8731
 help
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index a5c0bf1..2e37864 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,8 +1,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # AT91 Platform Support
 snd-soc-atmel-pcm-objs := atmel-pcm.o
+snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
 snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
 
 obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
+obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
 obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
 
 # AT91 Machine Support
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
new file mode 100644
index 0000000..1df64ba
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,401 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * atmel-pcm.c  --  ALSA PCM interface for the Atmel atmel SoC.
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2008 Atmel
+ *
+ * Authors: Sedji Gaouaou &amp;lt;sedji.gaouaou&amp;lt; at &amp;gt;atmel.com&amp;gt;
+ *
+ * Based on at91-pcm. by:
+ * Frank Mandarino &amp;lt;fmandarino&amp;lt; at &amp;gt;endrelia.com&amp;gt;
+ * Copyright 2006 Endrelia Technologies Inc.
+ *
+ * Based on pxa2xx-pcm.c by:
+ *
+ * Author:Nicolas Pitre
+ * Created:Nov 30, 2004
+ * Copyright:(C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include &amp;lt;linux/module.h&amp;gt;
+#include &amp;lt;linux/init.h&amp;gt;
+#include &amp;lt;linux/platform_device.h&amp;gt;
+#include &amp;lt;linux/slab.h&amp;gt;
+#include &amp;lt;linux/dma-mapping.h&amp;gt;
+#include &amp;lt;linux/atmel_pdc.h&amp;gt;
+#include &amp;lt;linux/atmel-ssc.h&amp;gt;
+
+#include &amp;lt;sound/core.h&amp;gt;
+#include &amp;lt;sound/pcm.h&amp;gt;
+#include &amp;lt;sound/pcm_params.h&amp;gt;
+#include &amp;lt;sound/soc.h&amp;gt;
+
+#include "atmel-pcm.h"
+
+
+/*--------------------------------------------------------------------------*\
+ * Hardware definition
+\*--------------------------------------------------------------------------*/
+/* TODO: These values were taken from the AT91 platform driver, check
+ * them against real values for AT32
+ */
+static const struct snd_pcm_hardware atmel_pcm_hardware = {
+.info= SNDRV_PCM_INFO_MMAP |
+  SNDRV_PCM_INFO_MMAP_VALID |
+  SNDRV_PCM_INFO_INTERLEAVED |
+  SNDRV_PCM_INFO_PAUSE,
+.formats= SNDRV_PCM_FMTBIT_S16_LE,
+.period_bytes_min= 32,
+.period_bytes_max= 8192,
+.periods_min= 2,
+.periods_max= 1024,
+.buffer_bytes_max= ATMEL_SSC_DMABUF_SIZE,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * Data types
+\*--------------------------------------------------------------------------*/
+struct atmel_runtime_data {
+struct atmel_pcm_dma_params *params;
+dma_addr_t dma_buffer;/* physical address of dma buffer */
+dma_addr_t dma_buffer_end;/* first address beyond DMA buffer */
+size_t period_size;
+
+dma_addr_t period_ptr;/* physical address of next period */
+
+/* PDC register save */
+u32 pdc_xpr_save;
+u32 pdc_xcr_save;
+u32 pdc_xnpr_save;
+u32 pdc_xncr_save;
+};
+
+/*--------------------------------------------------------------------------*\
+ * ISR
+\*--------------------------------------------------------------------------*/
+static void atmel_pcm_dma_irq(u32 ssc_sr,
+struct snd_pcm_substream *substream)
+{
+struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
+struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
+static int count;
+
+count++;
+
+if (ssc_sr &amp;amp; params-&amp;gt;mask-&amp;gt;ssc_endbuf) {
+pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
+substream-&amp;gt;stream == SNDRV_PCM_STREAM_PLAYBACK
+? "underrun" : "overrun",
+params-&amp;gt;name, ssc_sr, count);
+
+/* re-start the PDC */
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_disable);
+prtd-&amp;gt;period_ptr += prtd-&amp;gt;period_size;
+if (prtd-&amp;gt;period_ptr &amp;gt;= prtd-&amp;gt;dma_buffer_end)
+prtd-&amp;gt;period_ptr = prtd-&amp;gt;dma_buffer;
+
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr,
+   prtd-&amp;gt;period_ptr);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr,
+   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_enable);
+}
+
+if (ssc_sr &amp;amp; params-&amp;gt;mask-&amp;gt;ssc_endx) {
+/* Load the PDC next pointer and counter registers */
+prtd-&amp;gt;period_ptr += prtd-&amp;gt;period_size;
+if (prtd-&amp;gt;period_ptr &amp;gt;= prtd-&amp;gt;dma_buffer_end)
+prtd-&amp;gt;period_ptr = prtd-&amp;gt;dma_buffer;
+
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr,
+   prtd-&amp;gt;period_ptr);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr,
+   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
+}
+
+snd_pcm_period_elapsed(substream);
+}
+
+
+/*--------------------------------------------------------------------------*\
+ * PCM operations
+\*--------------------------------------------------------------------------*/
+static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
+struct snd_pcm_hw_params *params)
+{
+struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
+struct atmel_runtime_data *prtd = runtime-&amp;gt;private_data;
+struct snd_soc_pcm_runtime *rtd = substream-&amp;gt;private_data;
+
+/* this may get called several times by oss emulation
+ * with different params */
+
+snd_pcm_set_runtime_buffer(substream, &amp;amp;substream-&amp;gt;dma_buffer);
+runtime-&amp;gt;dma_bytes = params_buffer_bytes(params);
+
+prtd-&amp;gt;params = snd_soc_dai_get_dma_data(rtd-&amp;gt;cpu_dai, substream);
+prtd-&amp;gt;params-&amp;gt;dma_intr_handler = atmel_pcm_dma_irq;
+
+prtd-&amp;gt;dma_buffer = runtime-&amp;gt;dma_addr;
+prtd-&amp;gt;dma_buffer_end = runtime-&amp;gt;dma_addr + runtime-&amp;gt;dma_bytes;
+prtd-&amp;gt;period_size = params_period_bytes(params);
+
+pr_debug("atmel-pcm: "
+"hw_params: DMA for %s initialized "
+"(dma_bytes=%u, period_size=%u)\n",
+prtd-&amp;gt;params-&amp;gt;name,
+runtime-&amp;gt;dma_bytes,
+prtd-&amp;gt;period_size);
+return 0;
+}
+
+static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
+struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
+
+if (params != NULL) {
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_disable);
+prtd-&amp;gt;params-&amp;gt;dma_intr_handler = NULL;
+}
+
+return 0;
+}
+
+static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
+{
+struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
+struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
+
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_IDR,
+   params-&amp;gt;mask-&amp;gt;ssc_endx | params-&amp;gt;mask-&amp;gt;ssc_endbuf);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_disable);
+return 0;
+}
+
+static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
+int cmd)
+{
+struct snd_pcm_runtime *rtd = substream-&amp;gt;runtime;
+struct atmel_runtime_data *prtd = rtd-&amp;gt;private_data;
+struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
+int ret = 0;
+
+pr_debug("atmel-pcm:buffer_size = %ld,"
+"dma_area = %p, dma_bytes = %u\n",
+rtd-&amp;gt;buffer_size, rtd-&amp;gt;dma_area, rtd-&amp;gt;dma_bytes);
+
+switch (cmd) {
+case SNDRV_PCM_TRIGGER_START:
+prtd-&amp;gt;period_ptr = prtd-&amp;gt;dma_buffer;
+
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr,
+   prtd-&amp;gt;period_ptr);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr,
+   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
+
+prtd-&amp;gt;period_ptr += prtd-&amp;gt;period_size;
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr,
+   prtd-&amp;gt;period_ptr);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr,
+   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
+
+pr_debug("atmel-pcm: trigger: "
+"period_ptr=%lx, xpr=%u, "
+"xcr=%u, xnpr=%u, xncr=%u\n",
+(unsigned long)prtd-&amp;gt;period_ptr,
+ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr),
+ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr),
+ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr),
+ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr));
+
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_IER,
+   params-&amp;gt;mask-&amp;gt;ssc_endx | params-&amp;gt;mask-&amp;gt;ssc_endbuf);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_enable);
+
+pr_debug("sr=%u imr=%u\n",
+ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, SSC_SR),
+ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, SSC_IER));
+break;/* SNDRV_PCM_TRIGGER_START */
+
+case SNDRV_PCM_TRIGGER_STOP:
+case SNDRV_PCM_TRIGGER_SUSPEND:
+case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_disable);
+break;
+
+case SNDRV_PCM_TRIGGER_RESUME:
+case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
+   params-&amp;gt;mask-&amp;gt;pdc_enable);
+break;
+
+default:
+ret = -EINVAL;
+}
+
+return ret;
+}
+
+static snd_pcm_uframes_t atmel_pcm_pointer(
+struct snd_pcm_substream *substream)
+{
+struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
+struct atmel_runtime_data *prtd = runtime-&amp;gt;private_data;
+struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
+dma_addr_t ptr;
+snd_pcm_uframes_t x;
+
+ptr = (dma_addr_t) ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr);
+x = bytes_to_frames(runtime, ptr - prtd-&amp;gt;dma_buffer);
+
+if (x == runtime-&amp;gt;buffer_size)
+x = 0;
+
+return x;
+}
+
+static int atmel_pcm_open(struct snd_pcm_substream *substream)
+{
+struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
+struct atmel_runtime_data *prtd;
+int ret = 0;
+
+snd_soc_set_runtime_hwparams(substream, &amp;amp;atmel_pcm_hardware);
+
+/* ensure that buffer size is a multiple of period size */
+ret = snd_pcm_hw_constraint_integer(runtime,
+SNDRV_PCM_HW_PARAM_PERIODS);
+if (ret &amp;lt; 0)
+goto out;
+
+prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
+if (prtd == NULL) {
+ret = -ENOMEM;
+goto out;
+}
+runtime-&amp;gt;private_data = prtd;
+
+ out:
+return ret;
+}
+
+static int atmel_pcm_close(struct snd_pcm_substream *substream)
+{
+struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
+
+kfree(prtd);
+return 0;
+}
+
+static struct snd_pcm_ops atmel_pcm_ops = {
+.open= atmel_pcm_open,
+.close= atmel_pcm_close,
+.ioctl= snd_pcm_lib_ioctl,
+.hw_params= atmel_pcm_hw_params,
+.hw_free= atmel_pcm_hw_free,
+.prepare= atmel_pcm_prepare,
+.trigger= atmel_pcm_trigger,
+.pointer= atmel_pcm_pointer,
+.mmap= atmel_pcm_mmap,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * ASoC platform driver
+\*--------------------------------------------------------------------------*/
+#ifdef CONFIG_PM
+static int atmel_pcm_suspend(struct snd_soc_dai *dai)
+{
+struct snd_pcm_runtime *runtime = dai-&amp;gt;runtime;
+struct atmel_runtime_data *prtd;
+struct atmel_pcm_dma_params *params;
+
+if (!runtime)
+return 0;
+
+prtd = runtime-&amp;gt;private_data;
+params = prtd-&amp;gt;params;
+
+/* disable the PDC and save the PDC registers */
+
+ssc_writel(params-&amp;gt;ssc-&amp;gt;regs, PDC_PTCR, params-&amp;gt;mask-&amp;gt;pdc_disable);
+
+prtd-&amp;gt;pdc_xpr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr);
+prtd-&amp;gt;pdc_xcr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr);
+prtd-&amp;gt;pdc_xnpr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr);
+prtd-&amp;gt;pdc_xncr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr);
+
+return 0;
+}
+
+static int atmel_pcm_resume(struct snd_soc_dai *dai)
+{
+struct snd_pcm_runtime *runtime = dai-&amp;gt;runtime;
+struct atmel_runtime_data *prtd;
+struct atmel_pcm_dma_params *params;
+
+if (!runtime)
+return 0;
+
+prtd = runtime-&amp;gt;private_data;
+params = prtd-&amp;gt;params;
+
+/* restore the PDC registers and enable the PDC */
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr, prtd-&amp;gt;pdc_xpr_save);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr, prtd-&amp;gt;pdc_xcr_save);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr, prtd-&amp;gt;pdc_xnpr_save);
+ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr, prtd-&amp;gt;pdc_xncr_save);
+
+ssc_writel(params-&amp;gt;ssc-&amp;gt;regs, PDC_PTCR, params-&amp;gt;mask-&amp;gt;pdc_enable);
+return 0;
+}
+#else
+#define atmel_pcm_suspendNULL
+#define atmel_pcm_resumeNULL
+#endif
+
+static struct snd_soc_platform_driver atmel_soc_platform = {
+.ops= &amp;amp;atmel_pcm_ops,
+.pcm_new= atmel_pcm_new,
+.pcm_free= atmel_pcm_free,
+.suspend= atmel_pcm_suspend,
+.resume= atmel_pcm_resume,
+};
+
+int atmel_pcm_pdc_platform_register(struct device *dev)
+{
+return snd_soc_register_platform(dev, &amp;amp;atmel_soc_platform);
+}
+EXPORT_SYMBOL(atmel_pcm_pdc_platform_register);
+
+void atmel_pcm_pdc_platform_unregister(struct device *dev)
+{
+snd_soc_unregister_platform(dev);
+}
+EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister);
+
+MODULE_AUTHOR("Sedji Gaouaou &amp;lt;sedji.gaouaou&amp;lt; at &amp;gt;atmel.com&amp;gt;");
+MODULE_DESCRIPTION("Atmel PCM module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 40e17d1..e99f181 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -32,80 +32,25 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  */
 
 #include &amp;lt;linux/module.h&amp;gt;
-#include &amp;lt;linux/init.h&amp;gt;
-#include &amp;lt;linux/platform_device.h&amp;gt;
-#include &amp;lt;linux/slab.h&amp;gt;
 #include &amp;lt;linux/dma-mapping.h&amp;gt;
-#include &amp;lt;linux/atmel_pdc.h&amp;gt;
-#include &amp;lt;linux/atmel-ssc.h&amp;gt;
-
-#include &amp;lt;sound/core.h&amp;gt;
 #include &amp;lt;sound/pcm.h&amp;gt;
-#include &amp;lt;sound/pcm_params.h&amp;gt;
 #include &amp;lt;sound/soc.h&amp;gt;
-
 #include "atmel-pcm.h"
 
-
-/*--------------------------------------------------------------------------*\
- * Hardware definition
-\*--------------------------------------------------------------------------*/
-/* TODO: These values were taken from the AT91 platform driver, check
- * them against real values for AT32
- */
-static const struct snd_pcm_hardware atmel_pcm_hardware = {
-.info= SNDRV_PCM_INFO_MMAP |
-  SNDRV_PCM_INFO_MMAP_VALID |
-  SNDRV_PCM_INFO_INTERLEAVED |
-  SNDRV_PCM_INFO_PAUSE,
-.formats= SNDRV_PCM_FMTBIT_S16_LE,
-.period_bytes_min= 32,
-.period_bytes_max= 8192,
-.periods_min= 2,
-.periods_max= 1024,
-.buffer_bytes_max= 32 * 1024,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Data types
-\*--------------------------------------------------------------------------*/
-struct atmel_runtime_data {
-struct atmel_pcm_dma_params *params;
-dma_addr_t dma_buffer;/* physical address of dma buffer */
-dma_addr_t dma_buffer_end;/* first address beyond DMA buffer */
-size_t period_size;
-
-dma_addr_t period_ptr;/* physical address of next period */
-
-/* PDC register save */
-u32 pdc_xpr_save;
-u32 pdc_xcr_save;
-u32 pdc_xnpr_save;
-u32 pdc_xncr_save;
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Helper functions
-\*--------------------------------------------------------------------------*/
 static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
 int stream)
 {
 struct snd_pcm_substream *substream = pcm-&amp;gt;streams[stream].substream;
 struct snd_dma_buffer *buf = &amp;amp;substream-&amp;gt;dma_buffer;
-size_t size = atmel_pcm_hardware.buffer_bytes_max;
+size_t size = ATMEL_SSC_DMABUF_SIZE;
 
 buf-&amp;gt;dev.type = SNDRV_DMA_TYPE_DEV;
 buf-&amp;gt;dev.dev = pcm-&amp;gt;card-&amp;gt;dev;
 buf-&amp;gt;private_data = NULL;
 buf-&amp;gt;area = dma_alloc_coherent(pcm-&amp;gt;card-&amp;gt;dev, size,
-  &amp;amp;buf-&amp;gt;addr, GFP_KERNEL);
-pr_debug("atmel-pcm:"
-"preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
-(void *) buf-&amp;gt;area,
-(void *) buf-&amp;gt;addr,
-size);
+&amp;amp;buf-&amp;gt;addr, GFP_KERNEL);
+pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n",
+(void *)buf-&amp;gt;area, (void *)buf-&amp;gt;addr, size);
 
 if (!buf-&amp;gt;area)
 return -ENOMEM;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -113,258 +58,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
 buf-&amp;gt;bytes = size;
 return 0;
 }
-/*--------------------------------------------------------------------------*\
- * ISR
-\*--------------------------------------------------------------------------*/
-static void atmel_pcm_dma_irq(u32 ssc_sr,
-struct snd_pcm_substream *substream)
-{
-struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
-struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
-static int count;
-
-count++;
-
-if (ssc_sr &amp;amp; params-&amp;gt;mask-&amp;gt;ssc_endbuf) {
-pr_warning("atmel-pcm: buffer %s on %s"
-" (SSC_SR=%#x, count=%d)\n",
-substream-&amp;gt;stream == SNDRV_PCM_STREAM_PLAYBACK
-? "underrun" : "overrun",
-params-&amp;gt;name, ssc_sr, count);
-
-/* re-start the PDC */
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_disable);
-prtd-&amp;gt;period_ptr += prtd-&amp;gt;period_size;
-if (prtd-&amp;gt;period_ptr &amp;gt;= prtd-&amp;gt;dma_buffer_end)
-prtd-&amp;gt;period_ptr = prtd-&amp;gt;dma_buffer;
-
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr,
-   prtd-&amp;gt;period_ptr);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr,
-   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_enable);
-}
-
-if (ssc_sr &amp;amp; params-&amp;gt;mask-&amp;gt;ssc_endx) {
-/* Load the PDC next pointer and counter registers */
-prtd-&amp;gt;period_ptr += prtd-&amp;gt;period_size;
-if (prtd-&amp;gt;period_ptr &amp;gt;= prtd-&amp;gt;dma_buffer_end)
-prtd-&amp;gt;period_ptr = prtd-&amp;gt;dma_buffer;
-
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr,
-   prtd-&amp;gt;period_ptr);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr,
-   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
-}
-
-snd_pcm_period_elapsed(substream);
-}
-
-
-/*--------------------------------------------------------------------------*\
- * PCM operations
-\*--------------------------------------------------------------------------*/
-static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
-struct snd_pcm_hw_params *params)
-{
-struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
-struct atmel_runtime_data *prtd = runtime-&amp;gt;private_data;
-struct snd_soc_pcm_runtime *rtd = substream-&amp;gt;private_data;
-
-/* this may get called several times by oss emulation
- * with different params */
-
-snd_pcm_set_runtime_buffer(substream, &amp;amp;substream-&amp;gt;dma_buffer);
-runtime-&amp;gt;dma_bytes = params_buffer_bytes(params);
-
-prtd-&amp;gt;params = snd_soc_dai_get_dma_data(rtd-&amp;gt;cpu_dai, substream);
-prtd-&amp;gt;params-&amp;gt;dma_intr_handler = atmel_pcm_dma_irq;
-
-prtd-&amp;gt;dma_buffer = runtime-&amp;gt;dma_addr;
-prtd-&amp;gt;dma_buffer_end = runtime-&amp;gt;dma_addr + runtime-&amp;gt;dma_bytes;
-prtd-&amp;gt;period_size = params_period_bytes(params);
-
-pr_debug("atmel-pcm: "
-"hw_params: DMA for %s initialized "
-"(dma_bytes=%u, period_size=%u)\n",
-prtd-&amp;gt;params-&amp;gt;name,
-runtime-&amp;gt;dma_bytes,
-prtd-&amp;gt;period_size);
-return 0;
-}
-
-static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
-struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
-
-if (params != NULL) {
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_disable);
-prtd-&amp;gt;params-&amp;gt;dma_intr_handler = NULL;
-}
-
-return 0;
-}
-
-static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
-{
-struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
-struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
-
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_IDR,
-   params-&amp;gt;mask-&amp;gt;ssc_endx | params-&amp;gt;mask-&amp;gt;ssc_endbuf);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_disable);
-return 0;
-}
-
-static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
-int cmd)
-{
-struct snd_pcm_runtime *rtd = substream-&amp;gt;runtime;
-struct atmel_runtime_data *prtd = rtd-&amp;gt;private_data;
-struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
-int ret = 0;
-
-pr_debug("atmel-pcm:buffer_size = %ld,"
-"dma_area = %p, dma_bytes = %u\n",
-rtd-&amp;gt;buffer_size, rtd-&amp;gt;dma_area, rtd-&amp;gt;dma_bytes);
-
-switch (cmd) {
-case SNDRV_PCM_TRIGGER_START:
-prtd-&amp;gt;period_ptr = prtd-&amp;gt;dma_buffer;
-
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr,
-   prtd-&amp;gt;period_ptr);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr,
-   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
-
-prtd-&amp;gt;period_ptr += prtd-&amp;gt;period_size;
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr,
-   prtd-&amp;gt;period_ptr);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr,
-   prtd-&amp;gt;period_size / params-&amp;gt;pdc_xfer_size);
-
-pr_debug("atmel-pcm: trigger: "
-"period_ptr=%lx, xpr=%u, "
-"xcr=%u, xnpr=%u, xncr=%u\n",
-(unsigned long)prtd-&amp;gt;period_ptr,
-ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr),
-ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr),
-ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr),
-ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr));
-
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_IER,
-   params-&amp;gt;mask-&amp;gt;ssc_endx | params-&amp;gt;mask-&amp;gt;ssc_endbuf);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, SSC_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_enable);
-
-pr_debug("sr=%u imr=%u\n",
-ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, SSC_SR),
-ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, SSC_IER));
-break;/* SNDRV_PCM_TRIGGER_START */
-
-case SNDRV_PCM_TRIGGER_STOP:
-case SNDRV_PCM_TRIGGER_SUSPEND:
-case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_disable);
-break;
-
-case SNDRV_PCM_TRIGGER_RESUME:
-case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, ATMEL_PDC_PTCR,
-   params-&amp;gt;mask-&amp;gt;pdc_enable);
-break;
 
-default:
-ret = -EINVAL;
-}
-
-return ret;
-}
-
-static snd_pcm_uframes_t atmel_pcm_pointer(
-struct snd_pcm_substream *substream)
-{
-struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
-struct atmel_runtime_data *prtd = runtime-&amp;gt;private_data;
-struct atmel_pcm_dma_params *params = prtd-&amp;gt;params;
-dma_addr_t ptr;
-snd_pcm_uframes_t x;
-
-ptr = (dma_addr_t) ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr);
-x = bytes_to_frames(runtime, ptr - prtd-&amp;gt;dma_buffer);
-
-if (x == runtime-&amp;gt;buffer_size)
-x = 0;
-
-return x;
-}
-
-static int atmel_pcm_open(struct snd_pcm_substream *substream)
-{
-struct snd_pcm_runtime *runtime = substream-&amp;gt;runtime;
-struct atmel_runtime_data *prtd;
-int ret = 0;
-
-snd_soc_set_runtime_hwparams(substream, &amp;amp;atmel_pcm_hardware);
-
-/* ensure that buffer size is a multiple of period size */
-ret = snd_pcm_hw_constraint_integer(runtime,
-SNDRV_PCM_HW_PARAM_PERIODS);
-if (ret &amp;lt; 0)
-goto out;
-
-prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
-if (prtd == NULL) {
-ret = -ENOMEM;
-goto out;
-}
-runtime-&amp;gt;private_data = prtd;
-
- out:
-return ret;
-}
-
-static int atmel_pcm_close(struct snd_pcm_substream *substream)
-{
-struct atmel_runtime_data *prtd = substream-&amp;gt;runtime-&amp;gt;private_data;
-
-kfree(prtd);
-return 0;
-}
-
-static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+int atmel_pcm_mmap(struct snd_pcm_substream *substream,
 struct vm_area_struct *vma)
 {
 return remap_pfn_range(vma, vma-&amp;gt;vm_start,
        substream-&amp;gt;dma_buffer.addr &amp;gt;&amp;gt; PAGE_SHIFT,
        vma-&amp;gt;vm_end - vma-&amp;gt;vm_start, vma-&amp;gt;vm_page_prot);
 }
+EXPORT_SYMBOL_GPL(atmel_pcm_mmap);
 
-static struct snd_pcm_ops atmel_pcm_ops = {
-.open= atmel_pcm_open,
-.close= atmel_pcm_close,
-.ioctl= snd_pcm_lib_ioctl,
-.hw_params= atmel_pcm_hw_params,
-.hw_free= atmel_pcm_hw_free,
-.prepare= atmel_pcm_prepare,
-.trigger= atmel_pcm_trigger,
-.pointer= atmel_pcm_pointer,
-.mmap= atmel_pcm_mmap,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * ASoC platform driver
-\*--------------------------------------------------------------------------*/
 static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
 
-static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
+int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
 struct snd_card *card = rtd-&amp;gt;card-&amp;gt;snd_card;
 struct snd_pcm *pcm = rtd-&amp;gt;pcm;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -376,6 +82,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
 card-&amp;gt;dev-&amp;gt;coherent_dma_mask = DMA_BIT_MASK(32);
 
 if (pcm-&amp;gt;streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
 ret = atmel_pcm_preallocate_dma_buffer(pcm,
 SNDRV_PCM_STREAM_PLAYBACK);
 if (ret)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -383,8 +90,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
 }
 
 if (pcm-&amp;gt;streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-pr_debug("atmel-pcm:"
-"Allocating PCM capture DMA buffer\n");
+pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
 ret = atmel_pcm_preallocate_dma_buffer(pcm,
 SNDRV_PCM_STREAM_CAPTURE);
 if (ret)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -393,8 +99,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
  out:
 return ret;
 }
+EXPORT_SYMBOL_GPL(atmel_pcm_new);
 
-static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
+void atmel_pcm_free(struct snd_pcm *pcm)
 {
 struct snd_pcm_substream *substream;
 struct snd_dma_buffer *buf;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -413,78 +120,5 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
 buf-&amp;gt;area = NULL;
 }
 }
+EXPORT_SYMBOL_GPL(atmel_pcm_free);
 
-#ifdef CONFIG_PM
-static int atmel_pcm_suspend(struct snd_soc_dai *dai)
-{
-struct snd_pcm_runtime *runtime = dai-&amp;gt;runtime;
-struct atmel_runtime_data *prtd;
-struct atmel_pcm_dma_params *params;
-
-if (!runtime)
-return 0;
-
-prtd = runtime-&amp;gt;private_data;
-params = prtd-&amp;gt;params;
-
-/* disable the PDC and save the PDC registers */
-
-ssc_writel(params-&amp;gt;ssc-&amp;gt;regs, PDC_PTCR, params-&amp;gt;mask-&amp;gt;pdc_disable);
-
-prtd-&amp;gt;pdc_xpr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr);
-prtd-&amp;gt;pdc_xcr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr);
-prtd-&amp;gt;pdc_xnpr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr);
-prtd-&amp;gt;pdc_xncr_save = ssc_readx(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr);
-
-return 0;
-}
-
-static int atmel_pcm_resume(struct snd_soc_dai *dai)
-{
-struct snd_pcm_runtime *runtime = dai-&amp;gt;runtime;
-struct atmel_runtime_data *prtd;
-struct atmel_pcm_dma_params *params;
-
-if (!runtime)
-return 0;
-
-prtd = runtime-&amp;gt;private_data;
-params = prtd-&amp;gt;params;
-
-/* restore the PDC registers and enable the PDC */
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xpr, prtd-&amp;gt;pdc_xpr_save);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xcr, prtd-&amp;gt;pdc_xcr_save);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xnpr, prtd-&amp;gt;pdc_xnpr_save);
-ssc_writex(params-&amp;gt;ssc-&amp;gt;regs, params-&amp;gt;pdc-&amp;gt;xncr, prtd-&amp;gt;pdc_xncr_save);
-
-ssc_writel(params-&amp;gt;ssc-&amp;gt;regs, PDC_PTCR, params-&amp;gt;mask-&amp;gt;pdc_enable);
-return 0;
-}
-#else
-#define atmel_pcm_suspendNULL
-#define atmel_pcm_resumeNULL
-#endif
-
-static struct snd_soc_platform_driver atmel_soc_platform = {
-.ops= &amp;amp;atmel_pcm_ops,
-.pcm_new= atmel_pcm_new,
-.pcm_free= atmel_pcm_free_dma_buffers,
-.suspend= atmel_pcm_suspend,
-.resume= atmel_pcm_resume,
-};
-
-int atmel_pcm_platform_register(struct device *dev)
-{
-return snd_soc_register_platform(dev, &amp;amp;atmel_soc_platform);
-}
-EXPORT_SYMBOL(atmel_pcm_platform_register);
-
-void atmel_pcm_platform_unregister(struct device *dev)
-{
-snd_soc_unregister_platform(dev);
-}
-EXPORT_SYMBOL(atmel_pcm_platform_unregister);
-
-MODULE_AUTHOR("Sedji Gaouaou &amp;lt;sedji.gaouaou&amp;lt; at &amp;gt;atmel.com&amp;gt;");
-MODULE_DESCRIPTION("Atmel PCM module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index e6d67b3..6bd63b0 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,6 +36,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #include &amp;lt;linux/atmel-ssc.h&amp;gt;
 
+#define ATMEL_SSC_DMABUF_SIZE(64 * 1024)
+
 /*
  * Registers and status bits that are required by the PCM driver.
  */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -80,7 +82,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct atmel_pcm_dma_params {
 #define ssc_readx(base, reg)            (__raw_readl((base) + (reg)))
 #define ssc_writex(base, reg, value)    __raw_writel((value), (base) + (reg))
 
-int atmel_pcm_platform_register(struct device *dev);
-void atmel_pcm_platform_unregister(struct device *dev);
+int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd);
+void atmel_pcm_free(struct snd_pcm *pcm);
+int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+struct vm_area_struct *vma);
+
+#ifdef CONFIG_SND_ATMEL_SOC_PDC
+int atmel_pcm_pdc_platform_register(struct device *dev);
+void atmel_pcm_pdc_platform_unregister(struct device *dev);
+#else
+static inline int atmel_pcm_pdc_platform_register(struct device *dev)
+{
+return 0;
+}
+static inline void atmel_pcm_pdc_platform_unregister(struct device *dev)
+{
+}
+#endif
 
 #endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 7932c05..1705614 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -729,7 +729,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int asoc_ssc_init(struct device *dev)
 goto err;
 }
 
-ret = atmel_pcm_platform_register(dev);
+ret = atmel_pcm_pdc_platform_register(dev);
 if (ret) {
 dev_err(dev, "Could not register PCM: %d\n", ret);
 goto err_unregister_dai;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -745,7 +745,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; err:
 
 static void asoc_ssc_exit(struct device *dev)
 {
-atmel_pcm_platform_unregister(dev);
+atmel_pcm_pdc_platform_unregister(dev);
 snd_soc_unregister_dai(dev);
 }
 
&lt;/pre&gt;</description>
    <dc:creator>Bo Shen</dc:creator>
    <dc:date>2012-11-28T03:46:12</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1680">
    <title>KINGDOM NELSON</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1680</link>
    <description>&lt;pre&gt;&lt;/pre&gt;</description>
    <dc:creator>KINGDOM NELSON</dc:creator>
    <dc:date>2012-11-23T06:48:24</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1678">
    <title>[PATCH 0/3] ASoC: atmel-pcm: add dma support</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1678</link>
    <description>&lt;pre&gt;This patch series is intend to add dma support for atmel pcm which is
based on snd soc dmaengine pcm framework

Bo Shen (3):
  ASoC: snd_dmaengine_pcm: add inline empty function
  ASoC: atmel-pcm: prepare for adding dma support
  ASoC: atmel-pcm: add dma support

 include/sound/dmaengine_pcm.h   |   53 +++++++++
 sound/soc/atmel/atmel-pcm.c     |  247 ++++++++++++++++++++++++++++++++++-----
 sound/soc/atmel/atmel-pcm.h     |    4 +-
 sound/soc/atmel/atmel_ssc_dai.c |   30 ++---
 4 files changed, 292 insertions(+), 42 deletions(-)

&lt;/pre&gt;</description>
    <dc:creator>Bo Shen</dc:creator>
    <dc:date>2012-11-23T06:14:14</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.sound/1675">
    <title>Fund transfer.</title>
    <link>http://comments.gmane.org/gmane.linux.sound/1675</link>
    <description>&lt;pre&gt;
Open the attachment file for fund transfer/confidential.

&lt;/pre&gt;</description>
    <dc:creator>David</dc:creator>
    <dc:date>2012-11-22T15:06:37</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.sound">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.sound</link>
  </textinput>
</rdf:RDF>
