Alsa-devel
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
September 2018
- 98 participants
- 235 discussions
Hi Scott,
(C.Ced to alsa-devel, ffado-devel)
On Sep 7 2018 23:01, Scott Bahling wrote:
> I recently got my hands on a FW-1884 and would like to get it working in
> Linux. I'm mostly interested in using the control interface which should
> support several midi control interface protocols like Mackie Control or
> Mackie HUI. From the user manual it appears that the host computer needs to
> set the registers on the FW-1884 to switch modes (they reference Windows
> applications).
>
> I see that you have recently been working on user space support asynchronous
> commands to such devices. The hinawa_utils code has some beginnings of
> support for setting options on the Tascam devices and I have just started
> playing with that.
Thanks for your suggestion.
At present, the most of features on control surface of FW-1884 are not
available, especially for fader, knob and start/stop buttons.
In data transmission between system and devices on IEEE 1394 bus,
both of asynchronous transactions and isochronous packet streams are
available. In a case of TASCAM FireWire series, messages via MIDI
physical interface is bypassed to asynchronous transaction, while
messages generated on control surface are bypassed to isochronous
packets, multiplexed with PCM frames.
When enabling multiplexing messages to isochronous packet,
demultiplexer should be implemented to ALSA firewire-tascam driver,
but not yet. You can see my initial RFC in alsa-devel[1]. This patch
enables userspace applications to perform the demultiplexing, however
this idea easily brings cache-coherency problems due to page mapping
between kernel/userspace and impossible to be applied. We need to
investigate another idea to achieve the demultiplexing in kernel land.
As another option, according to page 26 in 'TASCAM FW-1884 Owner's
Manual', when programming Keys to port 1-4, system could receive MIDI
messages from control surface of FW-1884. However, I've not investigated
it.
> How are you determining the registers and flags? Do you have documentation,
> or are you reverse engineering? Do you know the registers and flags for
> setting the control protocol?
>
> If you have any hints on how figure out the proper registers and flags I'm
> happy to contribute to the work you have started and help support more
> functions of the FW-1884.
User manuals are documents to which we can refer. The most vendors
licenses their drivers/software with EULA and in most cases it can't
allow users to binary-based reverse engineering.
All of my work are done with external protocol analyzer unit on
IEEE 1394 bus. When working to implement drivers, I
read/classified/parsed content of many packets sniffed by the analyzer.
An initial idea of libhinawa/hinawa-utils is to assist this my work.
I heard FFADO developers uses some ways for this type of work:
- Usage of host controller of TI PCILynx and driver module (nosy.ko)
- Windows application; bushound[2]
However, this type of work takes you long time, so I don't necessarily
recommend you. It's 2018 and I think you can find alternative control
surfaces on USB. If you take long time to make devices available on
GNU/Linux, it's better to select devices on 'live' buses instead of
'legacy' buses such as IEEE 1394 bus, IMO. In a case of USB, wireshark
with usbcap is the easiest way for us to sniff packets on Windows.
[1]
http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/094817.html
[2] http://perisoft.net/bushound/
Regards
Takashi Sakamoto
2
21

Re: [alsa-devel] [linux-sunxi] [BUG] On Allwinner A20 Board Cubietruck distorted SPDIF opical output
by Markus Mitsch 28 Oct '18
by Markus Mitsch 28 Oct '18
28 Oct '18
hi.
i posted my answer wrong so here is my finding:
i made the output work by disabling the sigma delta modulation.
after compiling the kernel i can output through spdif with any rate.
greetings
markus
2018-05-26 18:38 GMT+02:00 Markus Mitsch <markusmitsch86(a)googlemail.com>:
> 2018-05-26 16:57 GMT+02:00 Markus Mitsch <markusmitsch86(a)googlemail.com>:
>> 2018-05-23 17:12 GMT+02:00 Code Kipper <codekipper(a)gmail.com>:
>>> Hi All,
>>> I can see that the problem was introduced somewhere here
>>>
>>> DOESN'T WORK
>>> ffc3eb6f3a83 Merge tag 'sunxi-clk-for-4.15' of
>>> https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into
>>> clk-next
>>> ae74ac082886 Merge tag 'clk-v4.15-exynos-pm' of
>>> git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk into
>>> clk-next
>>> faa865f18cb7 Merge tag 'clk-v4.15-samsung' of
>>> git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk into
>>> clk-next
>>> f09a6b86fdae Merge tag 'clk-renesas-for-v4.15-tag1' of
>>> git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers
>>> into clk-next
>>> 4328a2186e51 clk: sunxi-ng: sun4i: Export video PLLs
>>> 553c7d5ba2fe clk: sunxi-ng: Add A83T display clocks
>>> 7679eb20353d clk: samsung: Add a separate driver for Exynos4412 ISP clocks
>>> 8ca8ac102484 clk: samsung: Add dt bindings for Exynos4412 ISP clock controller
>>> 75920aac275a clk: samsung: Instantiate Exynos4412 ISP clocks only when available
>>> 24ea78a09f89 clk: sunxi-ng: sun8i: a23: Use sigma-delta modulation for audio PLL
>>> ee6501d69217 clk: sunxi-ng: sun6i: Use sigma-delta modulation for audio PLL
>>> 042f7f8f9715 clk: sunxi-ng: sun5i: Use sigma-delta modulation for audio PLL
>>> de3448519194 clk: sunxi-ng: sun4i: Use sigma-delta modulation for audio PLL
>>> a5e3e2b2ef85 clk: sunxi-ng: sun8i: h3: Use sigma-delta modulation for audio PLL
>>> 392ba5fafcdf clk: sunxi-ng: nm: Add support for sigma-delta modulation
>>> 05d2eaac96d4 clk: sunxi-ng: Add sigma-delta modulation support
>>> 4cdbc40d64d4 clk: sunxi-ng: nm: Check if requested rate is supported
>>> by fractional clock
>>> d51fe3ba9773 clk: sunxi-ng: sun5i: Fix bit offset of audio PLL post-divider
>>> 4e8975cbb516 clk: samsung: exynos5433: mark PM functions as __maybe_unused
>>> a4f21e9ceb5c clk: samsung: Remove obsolete clkdev alias support
>>> 45d882daf88a clk: samsung: Add explicit MPLL, EPLL clkdev aliases in
>>> S3C2443 driver
>>> cd05417f728b clk: samsung: Rework clkdev alias handling in S3C2443 driver
>>> efea8d377184 clk: samsung: Rework clkdev alias handling in Exynos5440 driver
>>> 36ba48240b19 clk: samsung: Drop useless alias in Exynos5420 clk driver
>>> 29964890f31c clk: samsung: Remove clkdev alias support in Exynos5250 clk driver
>>> 6de08891c896 clk: samsung: Remove double assignment of CLK_ARM_CLK in
>>> Exynos4 driver
>>> 58f4a5ff3a62 clk: samsung: Remove clkdev alias support in Exynos4 clk driver
>>> c9194fb623b0 clk: samsung: Remove support for obsolete Exynos4212 CPU clock
>>> d5cd103b06f9 clk: samsung: Remove support for Exynos4212 SoCs in
>>> Exynos CLKOUT driver
>>> 7c4f63ec94a1 clk: sunxi-ng: a83t: Fix invalid csi-mclk mux offset
>>> WORKS
>>> 0a4e632b6f9d Merge branch 'clk-fixes' into clk-next
>>>
>>> BR,
>>> CK
>>>
>>>
>>> On 22 May 2018 at 21:27, Code Kipper <codekipper(a)gmail.com> wrote:
>>>> Hi Markus,
>>>> I've been able to reproduce this on my A31 board with linux-next(plays
>>>> at 44100 but not at 96K)so it is an issue. I also tested the same code
>>>> on my A64 and it worked fine, The blocks are very similar so it maybe
>>>> a clocking issue, I'll look into this.
>>>> BR,
>>>> CK
>>>>
>>>> On 21 May 2018 at 20:17, Markus Mitsch <markusmitsch86(a)googlemail.com> wrote:
>>>>> 2018-05-21 15:17 GMT+02:00 Maxime Ripard <maxime.ripard(a)bootlin.com>:
>>>>>> On Mon, May 21, 2018 at 02:43:55PM +0200, Markus Mitsch wrote:
>>>>>>> 2018-05-21 11:43 GMT+02:00 Markus Mitsch <markusmitsch86(a)googlemail.com>:
>>>>>>> >>> Hello,
>>>>>>> >>>
>>>>>>> >>> i have a new problem. if i want to output sound from optical i get
>>>>>>> >>> distorted sound. At 44.1 khz its like an old vinly, but at 48 khz and
>>>>>>> >>> higher it is very bad. thanks in advance for your time.
>>>>>>> >
>>>>>>> >> Hi Markus,
>>>>>>> >> I haven't tested it for a while but when I did it worked as high as
>>>>>>> >> 96K with no issues. Does it work ok with the original cubietruck
>>>>>>> >> software?,
>>>>>>> >> CK
>>>>>>> >
>>>>>>> > Hello,
>>>>>>> > i am using arch linux with mainline kernel 4.16.8. parhaps i can try
>>>>>>> > today with official image.
>>>>>>> > mfg
>>>>>>>
>>>>>>> Hi.
>>>>>>> So, with debian image from 2014 with 3.4.79 kernel the sound is clear
>>>>>>> up to 96 khz.
>>>>>>
>>>>>> You said that it is a new problem, when was it introduced? Could you
>>>>>> bisect the issue?
>>>>>>
>>>>>> Maxime
>>>>>
>>>>> Hello.
>>>>> I dont know since when this problem appears. When saying "new" i
>>>>> refered to my older post. I tried to look into the dts file and the
>>>>> code
>>>>> but i am afraid this is a bit too high for me. I can say that the
>>>>> analog output works, even at high sampling rates.
>>>>> And I have read something about a clock source could be the problem.
>>>>> I'm sorry I can't tell you any more.
>>>>>
>>>>> mfg
>>>>> Markus
>>
>> Hello,
>> i tried undoing part of the commit
>> de3448519194 clk: sunxi-ng: sun4i: Use sigma-delta modulation for audio PLL
>> by setting the value for the divider from 1 to 4 again on both places.
>> with no success.
>>
>> markus
>
> i now had a little success. the output works!!
> i disabled the sigma-delta support by making
> ccu_sdm_helper_enable in drivers/clk/sunxi-ng/ccu_sdm.c return imediately.
>
> markus
2
2

[alsa-devel] [PATCH v4 00/14] ASoC: Add support to WCD9335 Audio Codec
by srinivas.kandagatla@linaro.org 24 Oct '18
by srinivas.kandagatla@linaro.org 24 Oct '18
24 Oct '18
From: Srinivas Kandagatla <srinivas.kandagatla(a)linaro.org>
Thankyou for reviewing v3 patchset, here is v4 addressing comments from v3.
Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC.
It is integrated in multiple Qualcomm SoCs like: MSM8996, MSM8976,
and MSM8956 chipsets.
WCD9335 had multiple functional blocks, like: Soundwire controller,
interrupt mux, pin controller, Audio codec, MBHC, MAD(Mic activity Detection),
Ultrasonic proximity and pen detection, Battery-voltage monitoring and
Codec processing engine.
Currently this patchset has been only tested with SLIMbus interface due
to hardware avaiablity, but it can be easily made to work with both SLIMbus
and I2C/I2S.
This patchset adds very basic playback and capture support witout much
fancy features. New features will be added once the basic support is in.
This patchset is tested on top of linux-next on DB820c for both playback
, capture paths and MBHC.
Some parts of the code has been inherited from Qualcomm andriod kernel,
so credits to various authors.
WCD9335 can be interfaced via I2S/I2C or SLIMbus.
Here is my test branch incase someone want to try this out:
https://git.linaro.org/people/srinivas.kandagatla/linux.git/log/?h=wcd9335
Thanks,
Srini
Changes since v3 (https://lkml.org/lkml/2018/9/4/318/)
- Updated mbhc dt bindings according to Robs Comments.
- Added a cleanup patch to common up fixups.
- Addressed various comments on mfd driver by Lee Jones.
- Added acks on bindings and irq support.
- fixed module loading
Srinivas Kandagatla (14):
ASoC: dt-bindings: update wcd9335 bindings.
mfd: wcd9335: add support to wcd9335 core
mfd: wcd9335: add wcd irq support
ASoC: wcd9335: add support to wcd9335 codec
ASoC: wcd9335: add CLASS-H Controller support
ASoC: wcd9335: add basic controls
ASoC: wcd9335: add playback dapm widgets
ASoC: wcd9335: add capture dapm widgets
ASoC: wcd9335: add audio routings
ASoC: dt-bindings: Add WCD9335 MBHC specific properties
ASoC: wcd9335: add mbhc support
ASoC: apq8096: add slim support
ASoC: apq8096: add headset JACK support
ASoC: qcom: common: move be_hw_fixup to common
.../devicetree/bindings/sound/qcom,wcd9335.txt | 30 +-
drivers/mfd/Kconfig | 13 +
drivers/mfd/Makefile | 4 +
drivers/mfd/wcd9335-core.c | 394 ++
include/linux/mfd/wcd9335/registers.h | 640 +++
include/linux/mfd/wcd9335/wcd9335.h | 81 +
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/wcd-clsh-v2.c | 577 +++
sound/soc/codecs/wcd-clsh-v2.h | 49 +
sound/soc/codecs/wcd9335.c | 5241 ++++++++++++++++++++
sound/soc/qcom/apq8096.c | 128 +-
sound/soc/qcom/common.c | 17 +
sound/soc/qcom/sdm845.c | 22 +-
14 files changed, 7168 insertions(+), 35 deletions(-)
create mode 100644 drivers/mfd/wcd9335-core.c
create mode 100644 include/linux/mfd/wcd9335/registers.h
create mode 100644 include/linux/mfd/wcd9335/wcd9335.h
create mode 100644 sound/soc/codecs/wcd-clsh-v2.c
create mode 100644 sound/soc/codecs/wcd-clsh-v2.h
create mode 100644 sound/soc/codecs/wcd9335.c
--
2.9.3
5
21

[alsa-devel] [asoc:for-4.20 333/424] sound/pci/hda/patch_ca0132.c:7650:20: error: implicit declaration of function 'pci_iomap'; did you mean 'pcim_iomap'?
by kbuild test robot 23 Oct '18
by kbuild test robot 23 Oct '18
23 Oct '18
Hi Rakesh,
FYI, the error/warning still remains.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-4.20
head: 1c8bc7b3de5e76cb89aacdc7be1475a028af505f
commit: 6bae5ea9498926440ffc883f3dbceb0adc65e492 [333/424] ASoC: hdac_hda: add asoc extension for legacy HDA codec drivers
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 6bae5ea9498926440ffc883f3dbceb0adc65e492
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=sh
All errors (new ones prefixed by >>):
sound/pci/hda/patch_ca0132.c: In function 'patch_ca0132':
>> sound/pci/hda/patch_ca0132.c:7650:20: error: implicit declaration of function 'pci_iomap'; did you mean 'pcim_iomap'? [-Werror=implicit-function-declaration]
spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
^~~~~~~~~
pcim_iomap
sound/pci/hda/patch_ca0132.c:7650:18: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
^
cc1: some warnings being treated as errors
vim +7650 sound/pci/hda/patch_ca0132.c
d5c016b56 Gabriele Martino 2015-05-18 7581
95c6e9cb7 Ian Minett 2011-06-15 7582 static int patch_ca0132(struct hda_codec *codec)
95c6e9cb7 Ian Minett 2011-06-15 7583 {
95c6e9cb7 Ian Minett 2011-06-15 7584 struct ca0132_spec *spec;
a73d511c4 Ian Minett 2012-12-20 7585 int err;
d5c016b56 Gabriele Martino 2015-05-18 7586 const struct snd_pci_quirk *quirk;
95c6e9cb7 Ian Minett 2011-06-15 7587
4e76a8833 Takashi Iwai 2014-02-25 7588 codec_dbg(codec, "patch_ca0132\n");
95c6e9cb7 Ian Minett 2011-06-15 7589
95c6e9cb7 Ian Minett 2011-06-15 7590 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
95c6e9cb7 Ian Minett 2011-06-15 7591 if (!spec)
95c6e9cb7 Ian Minett 2011-06-15 7592 return -ENOMEM;
95c6e9cb7 Ian Minett 2011-06-15 7593 codec->spec = spec;
993884f6a Chih-Chung Chang 2013-03-25 7594 spec->codec = codec;
95c6e9cb7 Ian Minett 2011-06-15 7595
225068ab2 Takashi Iwai 2015-05-29 7596 codec->patch_ops = ca0132_patch_ops;
225068ab2 Takashi Iwai 2015-05-29 7597 codec->pcm_format_first = 1;
225068ab2 Takashi Iwai 2015-05-29 7598 codec->no_sticky_stream = 1;
225068ab2 Takashi Iwai 2015-05-29 7599
d5c016b56 Gabriele Martino 2015-05-18 7600 /* Detect codec quirk */
d5c016b56 Gabriele Martino 2015-05-18 7601 quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks);
d5c016b56 Gabriele Martino 2015-05-18 7602 if (quirk)
d5c016b56 Gabriele Martino 2015-05-18 7603 spec->quirk = quirk->value;
d5c016b56 Gabriele Martino 2015-05-18 7604 else
d5c016b56 Gabriele Martino 2015-05-18 7605 spec->quirk = QUIRK_NONE;
d5c016b56 Gabriele Martino 2015-05-18 7606
e24aa0a4c Takashi Iwai 2014-08-10 7607 spec->dsp_state = DSP_DOWNLOAD_INIT;
a7e76271b Ian Minett 2012-12-20 7608 spec->num_mixers = 1;
017310fbe Connor McAdams 2018-05-08 7609
017310fbe Connor McAdams 2018-05-08 7610 /* Set which mixers each quirk uses. */
017310fbe Connor McAdams 2018-05-08 7611 switch (spec->quirk) {
017310fbe Connor McAdams 2018-05-08 7612 case QUIRK_SBZ:
e25e34450 Connor McAdams 2018-08-08 7613 spec->mixers[0] = desktop_mixer;
017310fbe Connor McAdams 2018-05-08 7614 snd_hda_codec_set_name(codec, "Sound Blaster Z");
017310fbe Connor McAdams 2018-05-08 7615 break;
e25e34450 Connor McAdams 2018-08-08 7616 case QUIRK_R3D:
e25e34450 Connor McAdams 2018-08-08 7617 spec->mixers[0] = desktop_mixer;
e25e34450 Connor McAdams 2018-08-08 7618 snd_hda_codec_set_name(codec, "Recon3D");
e25e34450 Connor McAdams 2018-08-08 7619 break;
017310fbe Connor McAdams 2018-05-08 7620 case QUIRK_R3DI:
017310fbe Connor McAdams 2018-05-08 7621 spec->mixers[0] = r3di_mixer;
017310fbe Connor McAdams 2018-05-08 7622 snd_hda_codec_set_name(codec, "Recon3Di");
017310fbe Connor McAdams 2018-05-08 7623 break;
017310fbe Connor McAdams 2018-05-08 7624 default:
a7e76271b Ian Minett 2012-12-20 7625 spec->mixers[0] = ca0132_mixer;
017310fbe Connor McAdams 2018-05-08 7626 break;
017310fbe Connor McAdams 2018-05-08 7627 }
a7e76271b Ian Minett 2012-12-20 7628
08eca6b1f Connor McAdams 2018-08-08 7629 /* Setup whether or not to use alt functions/controls/pci_mmio */
009b8f979 Connor McAdams 2018-05-08 7630 switch (spec->quirk) {
009b8f979 Connor McAdams 2018-05-08 7631 case QUIRK_SBZ:
e42c7c731 Connor McAdams 2018-08-08 7632 case QUIRK_R3D:
08eca6b1f Connor McAdams 2018-08-08 7633 spec->use_alt_controls = true;
08eca6b1f Connor McAdams 2018-08-08 7634 spec->use_alt_functions = true;
08eca6b1f Connor McAdams 2018-08-08 7635 spec->use_pci_mmio = true;
08eca6b1f Connor McAdams 2018-08-08 7636 break;
009b8f979 Connor McAdams 2018-05-08 7637 case QUIRK_R3DI:
47cdf76e4 Connor McAdams 2018-05-08 7638 spec->use_alt_controls = true;
009b8f979 Connor McAdams 2018-05-08 7639 spec->use_alt_functions = true;
08eca6b1f Connor McAdams 2018-08-08 7640 spec->use_pci_mmio = false;
009b8f979 Connor McAdams 2018-05-08 7641 break;
009b8f979 Connor McAdams 2018-05-08 7642 default:
47cdf76e4 Connor McAdams 2018-05-08 7643 spec->use_alt_controls = false;
009b8f979 Connor McAdams 2018-05-08 7644 spec->use_alt_functions = false;
08eca6b1f Connor McAdams 2018-08-08 7645 spec->use_pci_mmio = false;
009b8f979 Connor McAdams 2018-05-08 7646 break;
009b8f979 Connor McAdams 2018-05-08 7647 }
009b8f979 Connor McAdams 2018-05-08 7648
08eca6b1f Connor McAdams 2018-08-08 7649 if (spec->use_pci_mmio) {
08eca6b1f Connor McAdams 2018-08-08 @7650 spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
08eca6b1f Connor McAdams 2018-08-08 7651 if (spec->mem_base == NULL) {
08eca6b1f Connor McAdams 2018-08-08 7652 codec_warn(codec, "pci_iomap failed! Setting quirk to QUIRK_NONE.");
08eca6b1f Connor McAdams 2018-08-08 7653 spec->quirk = QUIRK_NONE;
08eca6b1f Connor McAdams 2018-08-08 7654 }
08eca6b1f Connor McAdams 2018-08-08 7655 }
08eca6b1f Connor McAdams 2018-08-08 7656
5aaca44d8 Ian Minett 2012-12-20 7657 spec->base_init_verbs = ca0132_base_init_verbs;
5aaca44d8 Ian Minett 2012-12-20 7658 spec->base_exit_verbs = ca0132_base_exit_verbs;
5aaca44d8 Ian Minett 2012-12-20 7659
993884f6a Chih-Chung Chang 2013-03-25 7660 INIT_DELAYED_WORK(&spec->unsol_hp_work, ca0132_unsol_hp_delayed);
993884f6a Chih-Chung Chang 2013-03-25 7661
95c6e9cb7 Ian Minett 2011-06-15 7662 ca0132_init_chip(codec);
95c6e9cb7 Ian Minett 2011-06-15 7663
95c6e9cb7 Ian Minett 2011-06-15 7664 ca0132_config(codec);
95c6e9cb7 Ian Minett 2011-06-15 7665
d5c016b56 Gabriele Martino 2015-05-18 7666 err = ca0132_prepare_verbs(codec);
d5c016b56 Gabriele Martino 2015-05-18 7667 if (err < 0)
cc91ceaf3 Takashi Iwai 2017-09-04 7668 goto error;
d5c016b56 Gabriele Martino 2015-05-18 7669
a73d511c4 Ian Minett 2012-12-20 7670 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
a73d511c4 Ian Minett 2012-12-20 7671 if (err < 0)
cc91ceaf3 Takashi Iwai 2017-09-04 7672 goto error;
a73d511c4 Ian Minett 2012-12-20 7673
95c6e9cb7 Ian Minett 2011-06-15 7674 return 0;
cc91ceaf3 Takashi Iwai 2017-09-04 7675
cc91ceaf3 Takashi Iwai 2017-09-04 7676 error:
cc91ceaf3 Takashi Iwai 2017-09-04 7677 ca0132_free(codec);
cc91ceaf3 Takashi Iwai 2017-09-04 7678 return err;
95c6e9cb7 Ian Minett 2011-06-15 7679 }
95c6e9cb7 Ian Minett 2011-06-15 7680
:::::: The code at line 7650 was first introduced by commit
:::::: 08eca6b1f1468a4021bac7b3929fd3eb491e2629 ALSA: hda/ca0132 - Add bool variable to enable/disable pci region2 mmio
:::::: TO: Connor McAdams <conmanx360(a)gmail.com>
:::::: CC: Takashi Iwai <tiwai(a)suse.de>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
4
7
Add driver for NAU88C22.
Signed-off-by: David Lin <CTLIN0(a)nuvoton.com>
---
.../devicetree/bindings/sound/nau8822.txt | 16 +
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/nau8822.c | 1136 +++++++++++++++++
sound/soc/codecs/nau8822.h | 204 +++
5 files changed, 1363 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/nau8822.txt
create mode 100644 sound/soc/codecs/nau8822.c
create mode 100644 sound/soc/codecs/nau8822.h
diff --git a/Documentation/devicetree/bindings/sound/nau8822.txt b/Documentation/devicetree/bindings/sound/nau8822.txt
new file mode 100644
index 000000000000..a471d162d4e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nau8822.txt
@@ -0,0 +1,16 @@
+NAU8822 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+ - compatible : "nuvoton,nau8822"
+
+ - reg : the I2C address of the device.
+
+Example:
+
+codec: nau8822@1a {
+ compatible = "nuvoton,nau8822";
+ reg = <0x1a>;
+};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index efb095dbcd71..57365dbc1581 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -109,6 +109,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MT6351 if MTK_PMIC_WRAP
select SND_SOC_NAU8540 if I2C
select SND_SOC_NAU8810 if I2C
+ select SND_SOC_NAU8822 if I2C
select SND_SOC_NAU8824 if I2C
select SND_SOC_NAU8825 if I2C
select SND_SOC_HDMI_CODEC
@@ -1299,6 +1300,10 @@ config SND_SOC_NAU8810
tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
depends on I2C
+config SND_SOC_NAU8822
+ tristate "Nuvoton Technology Corporation NAU88C22 CODEC"
+ depends on I2C
+
config SND_SOC_NAU8824
tristate "Nuvoton Technology Corporation NAU88L24 CODEC"
depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7ae7c85e8219..181a7d222fd7 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -106,6 +106,7 @@ snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
snd-soc-mt6351-objs := mt6351.o
snd-soc-nau8540-objs := nau8540.o
snd-soc-nau8810-objs := nau8810.o
+snd-soc-nau8822-objs := nau8822.o
snd-soc-nau8824-objs := nau8824.o
snd-soc-nau8825-objs := nau8825.o
snd-soc-hdmi-codec-objs := hdmi-codec.o
@@ -366,6 +367,7 @@ obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
obj-$(CONFIG_SND_SOC_MT6351) += snd-soc-mt6351.o
obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
+obj-$(CONFIG_SND_SOC_NAU8822) += snd-soc-nau8822.o
obj-$(CONFIG_SND_SOC_NAU8824) += snd-soc-nau8824.o
obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
new file mode 100644
index 000000000000..622ce947f134
--- /dev/null
+++ b/sound/soc/codecs/nau8822.c
@@ -0,0 +1,1136 @@
+/*
+ * nau8822.c -- NAU8822 ALSA Soc Audio Codec driver
+ *
+ * Copyright 2017 Nuvoton Technology Corp.
+ *
+ * Author: David Lin <ctlin0(a)nuvoton.com>
+ * Co-author: John Hsu <kchsu0(a)nuvoton.com>
+ * Co-author: Seven Li <wtli(a)nuvoton.com>
+ *
+ * Based on WM8974.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <asm/div64.h>
+#include "nau8822.h"
+
+#define NAU_PLL_FREQ_MAX 100000000
+#define NAU_PLL_FREQ_MIN 90000000
+#define NAU_PLL_REF_MAX 33000000
+#define NAU_PLL_REF_MIN 8000000
+#define NAU_PLL_OPTOP_MIN 6
+
+static const int nau8822_mclk_scaler[] = { 10, 15, 20, 30, 40, 60, 80, 120 };
+
+static const struct reg_default nau8822_reg_defaults[] = {
+ { NAU8822_REG_POWER_MANAGEMENT_1, 0x0000 },
+ { NAU8822_REG_POWER_MANAGEMENT_2, 0x0000 },
+ { NAU8822_REG_POWER_MANAGEMENT_3, 0x0000 },
+ { NAU8822_REG_AUDIO_INTERFACE, 0x0050 },
+ { NAU8822_REG_COMPANDING_CONTROL, 0x0000 },
+ { NAU8822_REG_CLOCKING, 0x0140 },
+ { NAU8822_REG_ADDITIONAL_CONTROL, 0x0000 },
+ { NAU8822_REG_GPIO_CONTROL, 0x0000 },
+ { NAU8822_REG_JACK_DETECT_CONTROL_1, 0x0000 },
+ { NAU8822_REG_DAC_CONTROL, 0x0000 },
+ { NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME, 0x00ff },
+ { NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME, 0x00ff },
+ { NAU8822_REG_JACK_DETECT_CONTROL_2, 0x0000 },
+ { NAU8822_REG_ADC_CONTROL, 0x0100 },
+ { NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME, 0x00ff },
+ { NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME, 0x00ff },
+ { NAU8822_REG_EQ1, 0x012c },
+ { NAU8822_REG_EQ2, 0x002c },
+ { NAU8822_REG_EQ3, 0x002c },
+ { NAU8822_REG_EQ4, 0x002c },
+ { NAU8822_REG_EQ5, 0x002c },
+ { NAU8822_REG_DAC_LIMITER_1, 0x0032 },
+ { NAU8822_REG_DAC_LIMITER_2, 0x0000 },
+ { NAU8822_REG_NOTCH_FILTER_1, 0x0000 },
+ { NAU8822_REG_NOTCH_FILTER_2, 0x0000 },
+ { NAU8822_REG_NOTCH_FILTER_3, 0x0000 },
+ { NAU8822_REG_NOTCH_FILTER_4, 0x0000 },
+ { NAU8822_REG_ALC_CONTROL_1, 0x0038 },
+ { NAU8822_REG_ALC_CONTROL_2, 0x000b },
+ { NAU8822_REG_ALC_CONTROL_3, 0x0032 },
+ { NAU8822_REG_NOISE_GATE, 0x0010 },
+ { NAU8822_REG_PLL_N, 0x0008 },
+ { NAU8822_REG_PLL_K1, 0x000c },
+ { NAU8822_REG_PLL_K2, 0x0093 },
+ { NAU8822_REG_PLL_K3, 0x00e9 },
+ { NAU8822_REG_3D_CONTROL, 0x0000 },
+ { NAU8822_REG_RIGHT_SPEAKER_CONTROL, 0x0000 },
+ { NAU8822_REG_INPUT_CONTROL, 0x0033 },
+ { NAU8822_REG_LEFT_INP_PGA_CONTROL, 0x0010 },
+ { NAU8822_REG_RIGHT_INP_PGA_CONTROL, 0x0010 },
+ { NAU8822_REG_LEFT_ADC_BOOST_CONTROL, 0x0100 },
+ { NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 0x0100 },
+ { NAU8822_REG_OUTPUT_CONTROL, 0x0002 },
+ { NAU8822_REG_LEFT_MIXER_CONTROL, 0x0001 },
+ { NAU8822_REG_RIGHT_MIXER_CONTROL, 0x0001 },
+ { NAU8822_REG_LHP_VOLUME, 0x0039 },
+ { NAU8822_REG_RHP_VOLUME, 0x0039 },
+ { NAU8822_REG_LSPKOUT_VOLUME, 0x0039 },
+ { NAU8822_REG_RSPKOUT_VOLUME, 0x0039 },
+ { NAU8822_REG_AUX2_MIXER, 0x0001 },
+ { NAU8822_REG_AUX1_MIXER, 0x0001 },
+ { NAU8822_REG_POWER_MANAGEMENT_4, 0x0000 },
+ { NAU8822_REG_LEFT_TIME_SLOT, 0x0000 },
+ { NAU8822_REG_MISC, 0x0020 },
+ { NAU8822_REG_RIGHT_TIME_SLOT, 0x0000 },
+ { NAU8822_REG_DEVICE_REVISION, 0x007f },
+ { NAU8822_REG_DEVICE_ID, 0x001a },
+ { NAU8822_REG_DAC_DITHER, 0x0114 },
+ { NAU8822_REG_ALC_ENHANCE_1, 0x0000 },
+ { NAU8822_REG_ALC_ENHANCE_2, 0x0000 },
+ { NAU8822_REG_192KHZ_SAMPLING, 0x0008 },
+ { NAU8822_REG_MISC_CONTROL, 0x0000 },
+ { NAU8822_REG_INPUT_TIEOFF, 0x0000 },
+ { NAU8822_REG_POWER_REDUCTION, 0x0000 },
+ { NAU8822_REG_AGC_PEAK2PEAK, 0x0000 },
+ { NAU8822_REG_AGC_PEAK_DETECT, 0x0000 },
+ { NAU8822_REG_AUTOMUTE_CONTROL, 0x0000 },
+ { NAU8822_REG_OUTPUT_TIEOFF, 0x0000 },
+};
+
+static bool nau8822_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case NAU8822_REG_RESET ... NAU8822_REG_JACK_DETECT_CONTROL_1:
+ case NAU8822_REG_DAC_CONTROL ... NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME:
+ case NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME:
+ case NAU8822_REG_EQ1 ... NAU8822_REG_EQ5:
+ case NAU8822_REG_DAC_LIMITER_1 ... NAU8822_REG_DAC_LIMITER_2:
+ case NAU8822_REG_NOTCH_FILTER_1 ... NAU8822_REG_NOTCH_FILTER_4:
+ case NAU8822_REG_ALC_CONTROL_1 ...NAU8822_REG_PLL_K3:
+ case NAU8822_REG_3D_CONTROL:
+ case NAU8822_REG_RIGHT_SPEAKER_CONTROL:
+ case NAU8822_REG_INPUT_CONTROL ... NAU8822_REG_LEFT_ADC_BOOST_CONTROL:
+ case NAU8822_REG_RIGHT_ADC_BOOST_CONTROL ... NAU8822_REG_AUX1_MIXER:
+ case NAU8822_REG_POWER_MANAGEMENT_4 ... NAU8822_REG_DEVICE_ID:
+ case NAU8822_REG_DAC_DITHER:
+ case NAU8822_REG_ALC_ENHANCE_1 ... NAU8822_REG_MISC_CONTROL:
+ case NAU8822_REG_INPUT_TIEOFF ... NAU8822_REG_OUTPUT_TIEOFF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool nau8822_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case NAU8822_REG_RESET ... NAU8822_REG_JACK_DETECT_CONTROL_1:
+ case NAU8822_REG_DAC_CONTROL ... NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME:
+ case NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME:
+ case NAU8822_REG_EQ1 ... NAU8822_REG_EQ5:
+ case NAU8822_REG_DAC_LIMITER_1 ... NAU8822_REG_DAC_LIMITER_2:
+ case NAU8822_REG_NOTCH_FILTER_1 ... NAU8822_REG_NOTCH_FILTER_4:
+ case NAU8822_REG_ALC_CONTROL_1 ...NAU8822_REG_PLL_K3:
+ case NAU8822_REG_3D_CONTROL:
+ case NAU8822_REG_RIGHT_SPEAKER_CONTROL:
+ case NAU8822_REG_INPUT_CONTROL ... NAU8822_REG_LEFT_ADC_BOOST_CONTROL:
+ case NAU8822_REG_RIGHT_ADC_BOOST_CONTROL ... NAU8822_REG_AUX1_MIXER:
+ case NAU8822_REG_POWER_MANAGEMENT_4 ... NAU8822_REG_DEVICE_ID:
+ case NAU8822_REG_DAC_DITHER:
+ case NAU8822_REG_ALC_ENHANCE_1 ... NAU8822_REG_MISC_CONTROL:
+ case NAU8822_REG_INPUT_TIEOFF ... NAU8822_REG_OUTPUT_TIEOFF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool nau8822_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case NAU8822_REG_RESET:
+ case NAU8822_REG_DEVICE_REVISION:
+ case NAU8822_REG_DEVICE_ID:
+ case NAU8822_REG_AGC_PEAK2PEAK:
+ case NAU8822_REG_AGC_PEAK_DETECT:
+ case NAU8822_REG_AUTOMUTE_CONTROL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* The EQ parameters get function is to get the 5 band equalizer control.
+ * The regmap raw read can't work here because regmap doesn't provide
+ * value format for value width of 9 bits. Therefore, the driver reads data
+ * from cache and makes value format according to the endianness of
+ * bytes type control element.
+ */
+static int nau8822_eq_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+ int i, reg;
+ u16 reg_val, *val;
+
+ val = (u16 *)ucontrol->value.bytes.data;
+ reg = NAU8822_REG_EQ1;
+ for (i = 0; i < params->max / sizeof(u16); i++) {
+ reg_val = snd_soc_component_read32(component, reg + i);
+ /* conversion of 16-bit integers between native CPU format
+ * and big endian format
+ */
+ reg_val = cpu_to_be16(reg_val);
+ memcpy(val + i, ®_val, sizeof(reg_val));
+ }
+
+ return 0;
+}
+
+/* The EQ parameters put function is to make configuration of 5 band equalizer
+ * control. These configuration includes central frequency, equalizer gain,
+ * cut-off frequency, bandwidth control, and equalizer path.
+ * The regmap raw write can't work here because regmap doesn't provide
+ * register and value format for register with address 7 bits and value 9 bits.
+ * Therefore, the driver makes value format according to the endianness of
+ * bytes type control element and writes data to codec.
+ */
+static int nau8822_eq_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct soc_bytes_ext *params = (void *)kcontrol->private_value;
+ void *data;
+ u16 *val, value;
+ int i, reg, ret;
+
+ data = kmemdup(ucontrol->value.bytes.data,
+ params->max, GFP_KERNEL | GFP_DMA);
+ if (!data)
+ return -ENOMEM;
+
+ val = (u16 *)data;
+ reg = NAU8822_REG_EQ1;
+ for (i = 0; i < params->max / sizeof(u16); i++) {
+ /* conversion of 16-bit integers between native CPU format
+ * and big endian format
+ */
+ value = be16_to_cpu(*(val + i));
+ ret = snd_soc_component_write(component, reg + i, value);
+ if (ret) {
+ dev_err(component->dev,
+ "EQ configuration fail, register: %x ret: %d\n",
+ reg + i, ret);
+ kfree(data);
+ return ret;
+ }
+ }
+ kfree(data);
+
+ return 0;
+}
+
+static const char * const nau8822_companding[] = {
+ "Off", "NC", "u-law", "A-law"};
+
+static const struct soc_enum nau8822_companding_adc_enum =
+ SOC_ENUM_SINGLE(NAU8822_REG_COMPANDING_CONTROL, NAU8822_ADCCM_SFT,
+ ARRAY_SIZE(nau8822_companding), nau8822_companding);
+
+static const struct soc_enum nau8822_companding_dac_enum =
+ SOC_ENUM_SINGLE(NAU8822_REG_COMPANDING_CONTROL, NAU8822_DACCM_SFT,
+ ARRAY_SIZE(nau8822_companding), nau8822_companding);
+
+static const char * const nau8822_eqmode[] = {"Capture", "Playback"};
+
+static const struct soc_enum nau8822_eqmode_enum =
+ SOC_ENUM_SINGLE(NAU8822_REG_EQ1, NAU8822_EQM_SFT,
+ ARRAY_SIZE(nau8822_eqmode), nau8822_eqmode);
+
+static const char * const nau8822_alc1[] = {"Off", "Right", "Left", "Both"};
+static const char * const nau8822_alc3[] = {"Normal", "Limiter"};
+
+static const struct soc_enum nau8822_alc_enable_enum =
+ SOC_ENUM_SINGLE(NAU8822_REG_ALC_CONTROL_1, NAU8822_ALCEN_SFT,
+ ARRAY_SIZE(nau8822_alc1), nau8822_alc1);
+
+static const struct soc_enum nau8822_alc_mode_enum =
+ SOC_ENUM_SINGLE(NAU8822_REG_ALC_CONTROL_3, NAU8822_ALCM_SFT,
+ ARRAY_SIZE(nau8822_alc3), nau8822_alc3);
+
+static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
+static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
+static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
+static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
+static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);
+
+static const struct snd_kcontrol_new nau8822_snd_controls[] = {
+ SOC_ENUM("ADC Companding", nau8822_companding_adc_enum),
+ SOC_ENUM("DAC Companding", nau8822_companding_dac_enum),
+
+ SOC_ENUM("EQ Function", nau8822_eqmode_enum),
+ SND_SOC_BYTES_EXT("EQ Parameters", 10,
+ nau8822_eq_get, nau8822_eq_put),
+
+ SOC_DOUBLE("DAC Inversion Switch",
+ NAU8822_REG_DAC_CONTROL, 0, 1, 1, 0),
+ SOC_DOUBLE_R_TLV("PCM Volume",
+ NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME,
+ NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME, 0, 255, 0, digital_tlv),
+
+ SOC_SINGLE("High Pass Filter Switch",
+ NAU8822_REG_ADC_CONTROL, 8, 1, 0),
+ SOC_SINGLE("High Pass Cut Off",
+ NAU8822_REG_ADC_CONTROL, 4, 7, 0),
+
+ SOC_DOUBLE("ADC Inversion Switch",
+ NAU8822_REG_ADC_CONTROL, 0, 1, 1, 0),
+ SOC_DOUBLE_R_TLV("ADC Volume",
+ NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME,
+ NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME, 0, 255, 0, digital_tlv),
+
+ SOC_SINGLE("DAC Limiter Switch",
+ NAU8822_REG_DAC_LIMITER_1, 8, 1, 0),
+ SOC_SINGLE("DAC Limiter Decay",
+ NAU8822_REG_DAC_LIMITER_1, 4, 15, 0),
+ SOC_SINGLE("DAC Limiter Attack",
+ NAU8822_REG_DAC_LIMITER_1, 0, 15, 0),
+ SOC_SINGLE("DAC Limiter Threshold",
+ NAU8822_REG_DAC_LIMITER_2, 4, 7, 0),
+ SOC_SINGLE_TLV("DAC Limiter Volume",
+ NAU8822_REG_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),
+
+ SOC_ENUM("ALC Mode", nau8822_alc_mode_enum),
+ SOC_ENUM("ALC Enable Switch", nau8822_alc_enable_enum),
+ SOC_SINGLE("ALC Min Gain",
+ NAU8822_REG_ALC_CONTROL_1, 0, 7, 0),
+ SOC_SINGLE("ALC Max Gain",
+ NAU8822_REG_ALC_CONTROL_1, 3, 7, 0),
+ SOC_SINGLE("ALC Hold",
+ NAU8822_REG_ALC_CONTROL_2, 4, 10, 0),
+ SOC_SINGLE("ALC Target",
+ NAU8822_REG_ALC_CONTROL_2, 0, 15, 0),
+ SOC_SINGLE("ALC Decay",
+ NAU8822_REG_ALC_CONTROL_3, 4, 10, 0),
+ SOC_SINGLE("ALC Attack",
+ NAU8822_REG_ALC_CONTROL_3, 0, 10, 0),
+ SOC_SINGLE("ALC Noise Gate Switch",
+ NAU8822_REG_NOISE_GATE, 3, 1, 0),
+ SOC_SINGLE("ALC Noise Gate Threshold",
+ NAU8822_REG_NOISE_GATE, 0, 7, 0),
+
+ SOC_DOUBLE_R("PGA ZC Switch",
+ NAU8822_REG_LEFT_INP_PGA_CONTROL,
+ NAU8822_REG_RIGHT_INP_PGA_CONTROL,
+ 7, 1, 0),
+ SOC_DOUBLE_R_TLV("PGA Volume",
+ NAU8822_REG_LEFT_INP_PGA_CONTROL,
+ NAU8822_REG_RIGHT_INP_PGA_CONTROL, 0, 63, 0, inpga_tlv),
+
+ SOC_DOUBLE_R("Headphone ZC Switch",
+ NAU8822_REG_LHP_VOLUME,
+ NAU8822_REG_RHP_VOLUME, 7, 1, 0),
+ SOC_DOUBLE_R("Headphone Playback Switch",
+ NAU8822_REG_LHP_VOLUME,
+ NAU8822_REG_RHP_VOLUME, 6, 1, 1),
+ SOC_DOUBLE_R_TLV("Headphone Volume",
+ NAU8822_REG_LHP_VOLUME,
+ NAU8822_REG_RHP_VOLUME, 0, 63, 0, spk_tlv),
+
+ SOC_DOUBLE_R("Speaker ZC Switch",
+ NAU8822_REG_LSPKOUT_VOLUME,
+ NAU8822_REG_RSPKOUT_VOLUME, 7, 1, 0),
+ SOC_DOUBLE_R("Speaker Playback Switch",
+ NAU8822_REG_LSPKOUT_VOLUME,
+ NAU8822_REG_RSPKOUT_VOLUME, 6, 1, 1),
+ SOC_DOUBLE_R_TLV("Speaker Volume",
+ NAU8822_REG_LSPKOUT_VOLUME,
+ NAU8822_REG_RSPKOUT_VOLUME, 0, 63, 0, spk_tlv),
+
+ SOC_DOUBLE_R("AUXOUT Playback Switch",
+ NAU8822_REG_AUX2_MIXER,
+ NAU8822_REG_AUX1_MIXER, 6, 1, 1),
+
+ SOC_DOUBLE_R_TLV("PGA Boost Volume",
+ NAU8822_REG_LEFT_ADC_BOOST_CONTROL,
+ NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 8, 1, 0, pga_boost_tlv),
+ SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
+ NAU8822_REG_LEFT_ADC_BOOST_CONTROL,
+ NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 4, 7, 0, boost_tlv),
+ SOC_DOUBLE_R_TLV("Aux Boost Volume",
+ NAU8822_REG_LEFT_ADC_BOOST_CONTROL,
+ NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 0, 7, 0, boost_tlv),
+
+ SOC_SINGLE("DAC 128x Oversampling Switch",
+ NAU8822_REG_DAC_CONTROL, 5, 1, 0),
+ SOC_SINGLE("ADC 128x Oversampling Switch",
+ NAU8822_REG_ADC_CONTROL, 5, 1, 0),
+};
+
+/* LMAIN and RMAIN Mixer */
+static const struct snd_kcontrol_new nau8822_left_out_mixer[] = {
+ SOC_DAPM_SINGLE("LINMIX Switch",
+ NAU8822_REG_LEFT_MIXER_CONTROL, 1, 1, 0),
+ SOC_DAPM_SINGLE("LAUX Switch",
+ NAU8822_REG_LEFT_MIXER_CONTROL, 5, 1, 0),
+ SOC_DAPM_SINGLE("LDAC Switch",
+ NAU8822_REG_LEFT_MIXER_CONTROL, 0, 1, 0),
+ SOC_DAPM_SINGLE("RDAC Switch",
+ NAU8822_REG_OUTPUT_CONTROL, 5, 1, 0),
+};
+
+static const struct snd_kcontrol_new nau8822_right_out_mixer[] = {
+ SOC_DAPM_SINGLE("RINMIX Switch",
+ NAU8822_REG_RIGHT_MIXER_CONTROL, 1, 1, 0),
+ SOC_DAPM_SINGLE("RAUX Switch",
+ NAU8822_REG_RIGHT_MIXER_CONTROL, 5, 1, 0),
+ SOC_DAPM_SINGLE("RDAC Switch",
+ NAU8822_REG_RIGHT_MIXER_CONTROL, 0, 1, 0),
+ SOC_DAPM_SINGLE("LDAC Switch",
+ NAU8822_REG_OUTPUT_CONTROL, 6, 1, 0),
+};
+
+/* AUX1 and AUX2 Mixer */
+static const struct snd_kcontrol_new nau8822_auxout1_mixer[] = {
+ SOC_DAPM_SINGLE("RDAC Switch", NAU8822_REG_AUX1_MIXER, 0, 1, 0),
+ SOC_DAPM_SINGLE("RMIX Switch", NAU8822_REG_AUX1_MIXER, 1, 1, 0),
+ SOC_DAPM_SINGLE("RINMIX Switch", NAU8822_REG_AUX1_MIXER, 2, 1, 0),
+ SOC_DAPM_SINGLE("LDAC Switch", NAU8822_REG_AUX1_MIXER, 3, 1, 0),
+ SOC_DAPM_SINGLE("LMIX Switch", NAU8822_REG_AUX1_MIXER, 4, 1, 0),
+};
+
+static const struct snd_kcontrol_new nau8822_auxout2_mixer[] = {
+ SOC_DAPM_SINGLE("LDAC Switch", NAU8822_REG_AUX2_MIXER, 0, 1, 0),
+ SOC_DAPM_SINGLE("LMIX Switch", NAU8822_REG_AUX2_MIXER, 1, 1, 0),
+ SOC_DAPM_SINGLE("LINMIX Switch", NAU8822_REG_AUX2_MIXER, 2, 1, 0),
+ SOC_DAPM_SINGLE("AUX1MIX Output Switch",
+ NAU8822_REG_AUX2_MIXER, 3, 1, 0),
+};
+
+/* Input PGA */
+static const struct snd_kcontrol_new nau8822_left_input_mixer[] = {
+ SOC_DAPM_SINGLE("L2 Switch", NAU8822_REG_INPUT_CONTROL, 2, 1, 0),
+ SOC_DAPM_SINGLE("MicN Switch", NAU8822_REG_INPUT_CONTROL, 1, 1, 0),
+ SOC_DAPM_SINGLE("MicP Switch", NAU8822_REG_INPUT_CONTROL, 0, 1, 0),
+};
+static const struct snd_kcontrol_new nau8822_right_input_mixer[] = {
+ SOC_DAPM_SINGLE("R2 Switch", NAU8822_REG_INPUT_CONTROL, 6, 1, 0),
+ SOC_DAPM_SINGLE("MicN Switch", NAU8822_REG_INPUT_CONTROL, 5, 1, 0),
+ SOC_DAPM_SINGLE("MicP Switch", NAU8822_REG_INPUT_CONTROL, 4, 1, 0),
+};
+
+/* Loopback Switch */
+static const struct snd_kcontrol_new nau8822_loopback =
+ SOC_DAPM_SINGLE("Switch", NAU8822_REG_COMPANDING_CONTROL,
+ NAU8822_ADDAP_SFT, 1, 0);
+
+static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(source->dapm);
+ unsigned int value;
+
+ value = snd_soc_component_read32(component, NAU8822_REG_CLOCKING);
+
+ return (value & NAU8822_CLKM_MASK);
+}
+
+static const struct snd_soc_dapm_widget nau8822_dapm_widgets[] = {
+ SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
+ NAU8822_REG_POWER_MANAGEMENT_3, 0, 0),
+ SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
+ NAU8822_REG_POWER_MANAGEMENT_3, 1, 0),
+ SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
+ NAU8822_REG_POWER_MANAGEMENT_2, 0, 0),
+ SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
+ NAU8822_REG_POWER_MANAGEMENT_2, 1, 0),
+
+ SOC_MIXER_ARRAY("Left Output Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_3, 2, 0, nau8822_left_out_mixer),
+ SOC_MIXER_ARRAY("Right Output Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_3, 3, 0, nau8822_right_out_mixer),
+ SOC_MIXER_ARRAY("AUX1 Output Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_1, 7, 0, nau8822_auxout1_mixer),
+ SOC_MIXER_ARRAY("AUX2 Output Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_1, 6, 0, nau8822_auxout2_mixer),
+
+ SOC_MIXER_ARRAY("Left Input Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_2,
+ 2, 0, nau8822_left_input_mixer),
+ SOC_MIXER_ARRAY("Right Input Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_2,
+ 3, 0, nau8822_right_input_mixer),
+
+ SND_SOC_DAPM_PGA("Left Boost Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Boost Mixer",
+ NAU8822_REG_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("Left Capture PGA",
+ NAU8822_REG_LEFT_INP_PGA_CONTROL, 6, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Capture PGA",
+ NAU8822_REG_RIGHT_INP_PGA_CONTROL, 6, 1, NULL, 0),
+
+ SND_SOC_DAPM_PGA("Left Headphone Out",
+ NAU8822_REG_POWER_MANAGEMENT_2, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Headphone Out",
+ NAU8822_REG_POWER_MANAGEMENT_2, 8, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("Left Speaker Out",
+ NAU8822_REG_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right Speaker Out",
+ NAU8822_REG_POWER_MANAGEMENT_3, 5, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("AUX1 Out",
+ NAU8822_REG_POWER_MANAGEMENT_3, 8, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("AUX2 Out",
+ NAU8822_REG_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("Mic Bias",
+ NAU8822_REG_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("PLL",
+ NAU8822_REG_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
+
+ SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
+ &nau8822_loopback),
+
+ SND_SOC_DAPM_INPUT("LMICN"),
+ SND_SOC_DAPM_INPUT("LMICP"),
+ SND_SOC_DAPM_INPUT("RMICN"),
+ SND_SOC_DAPM_INPUT("RMICP"),
+ SND_SOC_DAPM_INPUT("LAUX"),
+ SND_SOC_DAPM_INPUT("RAUX"),
+ SND_SOC_DAPM_INPUT("L2"),
+ SND_SOC_DAPM_INPUT("R2"),
+ SND_SOC_DAPM_OUTPUT("LHP"),
+ SND_SOC_DAPM_OUTPUT("RHP"),
+ SND_SOC_DAPM_OUTPUT("LSPK"),
+ SND_SOC_DAPM_OUTPUT("RSPK"),
+ SND_SOC_DAPM_OUTPUT("AUXOUT1"),
+ SND_SOC_DAPM_OUTPUT("AUXOUT2"),
+};
+
+static const struct snd_soc_dapm_route nau8822_dapm_routes[] = {
+ {"Right DAC", NULL, "PLL", check_mclk_select_pll},
+ {"Left DAC", NULL, "PLL", check_mclk_select_pll},
+
+ /* LMAIN and RMAIN Mixer */
+ {"Right Output Mixer", "LDAC Switch", "Left DAC"},
+ {"Right Output Mixer", "RDAC Switch", "Right DAC"},
+ {"Right Output Mixer", "RAUX Switch", "RAUX"},
+ {"Right Output Mixer", "RINMIX Switch", "Right Boost Mixer"},
+
+ {"Left Output Mixer", "LDAC Switch", "Left DAC"},
+ {"Left Output Mixer", "RDAC Switch", "Right DAC"},
+ {"Left Output Mixer", "LAUX Switch", "LAUX"},
+ {"Left Output Mixer", "LINMIX Switch", "Left Boost Mixer"},
+
+ /* AUX1 and AUX2 Mixer */
+ {"AUX1 Output Mixer", "RDAC Switch", "Right DAC"},
+ {"AUX1 Output Mixer", "RMIX Switch", "Right Output Mixer"},
+ {"AUX1 Output Mixer", "RINMIX Switch", "Right Boost Mixer"},
+ {"AUX1 Output Mixer", "LDAC Switch", "Left DAC"},
+ {"AUX1 Output Mixer", "LMIX Switch", "Left Output Mixer"},
+
+ {"AUX2 Output Mixer", "LDAC Switch", "Left DAC"},
+ {"AUX2 Output Mixer", "LMIX Switch", "Left Output Mixer"},
+ {"AUX2 Output Mixer", "LINMIX Switch", "Left Boost Mixer"},
+ {"AUX2 Output Mixer", "AUX1MIX Output Switch", "AUX1 Output Mixer"},
+
+ /* Outputs */
+ {"Right Headphone Out", NULL, "Right Output Mixer"},
+ {"RHP", NULL, "Right Headphone Out"},
+
+ {"Left Headphone Out", NULL, "Left Output Mixer"},
+ {"LHP", NULL, "Left Headphone Out"},
+
+ {"Right Speaker Out", NULL, "Right Output Mixer"},
+ {"RSPK", NULL, "Right Speaker Out"},
+
+ {"Left Speaker Out", NULL, "Left Output Mixer"},
+ {"LSPK", NULL, "Left Speaker Out"},
+
+ {"AUX1 Out", NULL, "AUX1 Output Mixer"},
+ {"AUX2 Out", NULL, "AUX2 Output Mixer"},
+ {"AUXOUT1", NULL, "AUX1 Out"},
+ {"AUXOUT2", NULL, "AUX2 Out"},
+
+ /* Boost Mixer */
+ {"Right ADC", NULL, "PLL", check_mclk_select_pll},
+ {"Left ADC", NULL, "PLL", check_mclk_select_pll},
+
+ {"Right ADC", NULL, "Right Boost Mixer"},
+
+ {"Right Boost Mixer", NULL, "RAUX"},
+ {"Right Boost Mixer", NULL, "Right Capture PGA"},
+ {"Right Boost Mixer", NULL, "R2"},
+
+ {"Left ADC", NULL, "Left Boost Mixer"},
+
+ {"Left Boost Mixer", NULL, "LAUX"},
+ {"Left Boost Mixer", NULL, "Left Capture PGA"},
+ {"Left Boost Mixer", NULL, "L2"},
+
+ /* Input PGA */
+ {"Right Capture PGA", NULL, "Right Input Mixer"},
+ {"Left Capture PGA", NULL, "Left Input Mixer"},
+
+ /* Enable Microphone Power */
+ {"Right Capture PGA", NULL, "Mic Bias"},
+ {"Left Capture PGA", NULL, "Mic Bias"},
+
+ {"Right Input Mixer", "R2 Switch", "R2"},
+ {"Right Input Mixer", "MicN Switch", "RMICN"},
+ {"Right Input Mixer", "MicP Switch", "RMICP"},
+
+ {"Left Input Mixer", "L2 Switch", "L2"},
+ {"Left Input Mixer", "MicN Switch", "LMICN"},
+ {"Left Input Mixer", "MicP Switch", "LMICP"},
+
+ /* Digital Loopback */
+ {"Digital Loopback", "Switch", "Left ADC"},
+ {"Digital Loopback", "Switch", "Right ADC"},
+ {"Left DAC", NULL, "Digital Loopback"},
+ {"Right DAC", NULL, "Digital Loopback"},
+};
+
+static int nau8822_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_component *component = dai->component;
+ struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
+
+ nau8822->div_id = clk_id;
+ nau8822->sysclk = freq;
+ dev_dbg(component->dev, "master sysclk %dHz, source %s\n", freq,
+ clk_id == NAU8822_CLK_PLL ? "PLL" : "MCLK");
+
+ return 0;
+}
+
+static int nau8822_calc_pll(unsigned int pll_in, unsigned int fs,
+ struct nau8822_pll *pll_param)
+{
+ u64 f2, f2_max, pll_ratio;
+ int i, scal_sel;
+
+ if (pll_in > NAU_PLL_REF_MAX || pll_in < NAU_PLL_REF_MIN)
+ return -EINVAL;
+ f2_max = 0;
+ scal_sel = ARRAY_SIZE(nau8822_mclk_scaler);
+
+ for (i = 0; i < scal_sel; i++) {
+ f2 = 256 * fs * 4 * nau8822_mclk_scaler[i] / 10;
+ if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX &&
+ f2_max < f2) {
+ f2_max = f2;
+ scal_sel = i;
+ }
+ }
+
+ if (ARRAY_SIZE(nau8822_mclk_scaler) == scal_sel)
+ return -EINVAL;
+ pll_param->mclk_scaler = scal_sel;
+ f2 = f2_max;
+
+ /* Calculate the PLL 4-bit integer input and the PLL 24-bit fractional
+ * input; round up the 24+4bit.
+ */
+ pll_ratio = div_u64(f2 << 28, pll_in);
+ pll_param->pre_factor = 0;
+ if (((pll_ratio >> 28) & 0xF) < NAU_PLL_OPTOP_MIN) {
+ pll_ratio <<= 1;
+ pll_param->pre_factor = 1;
+ }
+ pll_param->pll_int = (pll_ratio >> 28) & 0xF;
+ pll_param->pll_frac = ((pll_ratio & 0xFFFFFFF) >> 4);
+
+ return 0;
+}
+
+static int nau8822_config_clkdiv(struct snd_soc_dai *dai, int div, int rate)
+{
+ struct snd_soc_component *component = dai->component;
+ struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
+ struct nau8822_pll *pll = &nau8822->pll;
+ int i, sclk, imclk;
+
+ switch (nau8822->div_id) {
+ case NAU8822_CLK_MCLK:
+ /* Configure the master clock prescaler div to make system
+ * clock to approximate the internal master clock (IMCLK);
+ * and large or equal to IMCLK.
+ */
+ div = 0;
+ imclk = rate * 256;
+ for (i = 1; i < ARRAY_SIZE(nau8822_mclk_scaler); i++) {
+ sclk = (nau8822->sysclk * 10) / nau8822_mclk_scaler[i];
+ if (sclk < imclk)
+ break;
+ div = i;
+ }
+ dev_dbg(component->dev, "master clock prescaler %x for fs %d\n",
+ div, rate);
+
+ /* master clock from MCLK and disable PLL */
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_MCLKSEL_MASK,
+ (div << NAU8822_MCLKSEL_SFT));
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK,
+ NAU8822_CLKM_MCLK);
+ break;
+
+ case NAU8822_CLK_PLL:
+ /* master clock from PLL and enable PLL */
+ if (pll->mclk_scaler != div) {
+ dev_err(component->dev,
+ "master clock prescaler not meet PLL parameters\n");
+ return -EINVAL;
+ }
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_MCLKSEL_MASK,
+ (div << NAU8822_MCLKSEL_SFT));
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK,
+ NAU8822_CLKM_PLL);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_component *component = dai->component;
+ struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
+ struct nau8822_pll *pll_param = &nau8822->pll;
+ int ret, fs;
+
+ fs = freq_out / 256;
+
+ ret = nau8822_calc_pll(freq_in, fs, pll_param);
+ if (ret < 0) {
+ dev_err(component->dev, "Unsupported input clock %d\n",
+ freq_in);
+ return ret;
+ }
+
+ dev_info(component->dev,
+ "pll_int=%x pll_frac=%x mclk_scaler=%x pre_factor=%x\n",
+ pll_param->pll_int, pll_param->pll_frac,
+ pll_param->mclk_scaler, pll_param->pre_factor);
+
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_PLL_N, NAU8822_PLLMCLK_DIV2 | NAU8822_PLLN_MASK,
+ (pll_param->pre_factor ? NAU8822_PLLMCLK_DIV2 : 0) |
+ pll_param->pll_int);
+ snd_soc_component_write(component,
+ NAU8822_REG_PLL_K1, (pll_param->pll_frac >> NAU8822_PLLK1_SFT) &
+ NAU8822_PLLK1_MASK);
+ snd_soc_component_write(component,
+ NAU8822_REG_PLL_K2, (pll_param->pll_frac >> NAU8822_PLLK2_SFT) &
+ NAU8822_PLLK2_MASK);
+ snd_soc_component_write(component,
+ NAU8822_REG_PLL_K3, pll_param->pll_frac & NAU8822_PLLK3_MASK);
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_MCLKSEL_MASK,
+ pll_param->mclk_scaler << NAU8822_MCLKSEL_SFT);
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK, NAU8822_CLKM_PLL);
+
+ return 0;
+}
+
+static int nau8822_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_component *component = dai->component;
+ u16 ctrl1_val = 0, ctrl2_val = 0;
+
+ dev_dbg(component->dev, "%s\n", __func__);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ ctrl2_val |= 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ ctrl2_val &= ~1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ ctrl1_val |= 0x10;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ ctrl1_val |= 0x8;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ ctrl1_val |= 0x18;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ ctrl1_val |= 0x180;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ ctrl1_val |= 0x100;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ ctrl1_val |= 0x80;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_AUDIO_INTERFACE,
+ NAU8822_AIFMT_MASK | NAU8822_LRP_MASK | NAU8822_BCLKP_MASK,
+ ctrl1_val);
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_CLOCKING, NAU8822_CLKIOEN_MASK, ctrl2_val);
+
+ return 0;
+}
+
+static int nau8822_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+ struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
+ int val_len = 0, val_rate = 0;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ val_len |= NAU8822_WLEN_20;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ val_len |= NAU8822_WLEN_24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ val_len |= NAU8822_WLEN_32;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (params_rate(params)) {
+ case 8000:
+ val_rate |= NAU8822_SMPLR_8K;
+ break;
+ case 11025:
+ val_rate |= NAU8822_SMPLR_12K;
+ break;
+ case 16000:
+ val_rate |= NAU8822_SMPLR_16K;
+ break;
+ case 22050:
+ val_rate |= NAU8822_SMPLR_24K;
+ break;
+ case 32000:
+ val_rate |= NAU8822_SMPLR_32K;
+ break;
+ case 44100:
+ case 48000:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_AUDIO_INTERFACE, NAU8822_WLEN_MASK, val_len);
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_ADDITIONAL_CONTROL, NAU8822_SMPLR_MASK, val_rate);
+
+ /* If the master clock is from MCLK, provide the runtime FS for driver
+ * to get the master clock prescaler configuration.
+ */
+ if (nau8822->div_id == NAU8822_CLK_MCLK)
+ nau8822_config_clkdiv(dai, 0, params_rate(params));
+
+ return 0;
+}
+
+static int nau8822_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_component *component = dai->component;
+
+ dev_dbg(component->dev, "%s: %d\n", __func__, mute);
+
+ if (mute)
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_DAC_CONTROL, 0x40, 0x40);
+ else
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_DAC_CONTROL, 0x40, 0);
+
+ return 0;
+}
+
+static int nau8822_set_bias_level(struct snd_soc_component *component,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_POWER_MANAGEMENT_1,
+ NAU8822_REFIMP_MASK, NAU8822_REFIMP_80K);
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_POWER_MANAGEMENT_1,
+ NAU8822_IOBUF_EN | NAU8822_ABIAS_EN,
+ NAU8822_IOBUF_EN | NAU8822_ABIAS_EN);
+
+ if (snd_soc_component_get_bias_level(component) ==
+ SND_SOC_BIAS_OFF) {
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_POWER_MANAGEMENT_1,
+ NAU8822_REFIMP_MASK, NAU8822_REFIMP_3K);
+ mdelay(100);
+ }
+ snd_soc_component_update_bits(component,
+ NAU8822_REG_POWER_MANAGEMENT_1,
+ NAU8822_REFIMP_MASK, NAU8822_REFIMP_300K);
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ snd_soc_component_write(component,
+ NAU8822_REG_POWER_MANAGEMENT_1, 0);
+ snd_soc_component_write(component,
+ NAU8822_REG_POWER_MANAGEMENT_2, 0);
+ snd_soc_component_write(component,
+ NAU8822_REG_POWER_MANAGEMENT_3, 0);
+ break;
+ }
+
+ dev_dbg(component->dev, "%s: %d\n", __func__, level);
+
+ return 0;
+}
+
+#define NAU8822_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define NAU8822_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_soc_dai_ops nau8822_dai_ops = {
+ .hw_params = nau8822_hw_params,
+ .digital_mute = nau8822_mute,
+ .set_fmt = nau8822_set_dai_fmt,
+ .set_sysclk = nau8822_set_dai_sysclk,
+ .set_pll = nau8822_set_pll,
+};
+
+static struct snd_soc_dai_driver nau8822_dai = {
+ .name = "nau8822-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = NAU8822_RATES,
+ .formats = NAU8822_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = NAU8822_RATES,
+ .formats = NAU8822_FORMATS,
+ },
+ .ops = &nau8822_dai_ops,
+ .symmetric_rates = 1,
+};
+
+static int nau8822_suspend(struct snd_soc_component *component)
+{
+ struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
+
+ snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
+
+ regcache_mark_dirty(nau8822->regmap);
+
+ return 0;
+}
+
+static int nau8822_resume(struct snd_soc_component *component)
+{
+ struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
+
+ regcache_sync(nau8822->regmap);
+
+ snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
+
+ return 0;
+}
+
+/*
+ * These registers contain an "update" bit - bit 8. This means, for example,
+ * that one can write new DAC digital volume for both channels, but only when
+ * the update bit is set, will also the volume be updated - simultaneously for
+ * both channels.
+ */
+static const int update_reg[] = {
+ NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME,
+ NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME,
+ NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME,
+ NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME,
+ NAU8822_REG_LEFT_INP_PGA_CONTROL,
+ NAU8822_REG_RIGHT_INP_PGA_CONTROL,
+ NAU8822_REG_LHP_VOLUME,
+ NAU8822_REG_RHP_VOLUME,
+ NAU8822_REG_LSPKOUT_VOLUME,
+ NAU8822_REG_RSPKOUT_VOLUME,
+};
+
+static int nau8822_probe(struct snd_soc_component *component)
+{
+ int i;
+
+ /*
+ * Set the update bit in all registers, that have one. This way all
+ * writes to those registers will also cause the update bit to be
+ * written.
+ */
+ for (i = 0; i < ARRAY_SIZE(update_reg); i++)
+ snd_soc_component_update_bits(component,
+ update_reg[i], 0x100, 0x100);
+
+ return 0;
+}
+
+static const struct snd_soc_component_driver soc_component_dev_nau8822 = {
+ .probe = nau8822_probe,
+ .suspend = nau8822_suspend,
+ .resume = nau8822_resume,
+ .set_bias_level = nau8822_set_bias_level,
+ .controls = nau8822_snd_controls,
+ .num_controls = ARRAY_SIZE(nau8822_snd_controls),
+ .dapm_widgets = nau8822_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(nau8822_dapm_widgets),
+ .dapm_routes = nau8822_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(nau8822_dapm_routes),
+ .idle_bias_on = 1,
+ .use_pmdown_time = 1,
+ .endianness = 1,
+ .non_legacy_dai_naming = 1,
+};
+
+static const struct regmap_config nau8822_regmap_config = {
+ .reg_bits = 7,
+ .val_bits = 9,
+
+ .max_register = NAU8822_REG_MAX_REGISTER,
+ .volatile_reg = nau8822_volatile,
+
+ .readable_reg = nau8822_readable_reg,
+ .writeable_reg = nau8822_writeable_reg,
+
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = nau8822_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(nau8822_reg_defaults),
+};
+
+static int nau8822_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &i2c->dev;
+ struct nau8822 *nau8822 = dev_get_platdata(dev);
+ int ret;
+
+ if (!nau8822) {
+ nau8822 = devm_kzalloc(dev, sizeof(*nau8822), GFP_KERNEL);
+ if (nau8822 == NULL)
+ return -ENOMEM;
+ }
+ i2c_set_clientdata(i2c, nau8822);
+
+ nau8822->regmap = devm_regmap_init_i2c(i2c, &nau8822_regmap_config);
+ if (IS_ERR(nau8822->regmap)) {
+ ret = PTR_ERR(nau8822->regmap);
+ dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+ return ret;
+ }
+ nau8822->dev = dev;
+
+ /* Reset the codec */
+ ret = regmap_write(nau8822->regmap, NAU8822_REG_RESET, 0x00);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
+ return ret;
+ }
+
+ ret = devm_snd_soc_register_component(dev, &soc_component_dev_nau8822,
+ &nau8822_dai, 1);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id nau8822_i2c_id[] = {
+ { "nau8822", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, nau8822_i2c_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id nau8822_of_match[] = {
+ { .compatible = "nuvoton,nau8822", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, nau8822_of_match);
+#endif
+
+static struct i2c_driver nau8822_i2c_driver = {
+ .driver = {
+ .name = "nau8822",
+ .of_match_table = of_match_ptr(nau8822_of_match),
+ },
+ .probe = nau8822_i2c_probe,
+ .id_table = nau8822_i2c_id,
+};
+module_i2c_driver(nau8822_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC NAU8822 codec driver");
+MODULE_AUTHOR("David Lin <ctlin0(a)nuvoton.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/nau8822.h b/sound/soc/codecs/nau8822.h
new file mode 100644
index 000000000000..aa79c969cd44
--- /dev/null
+++ b/sound/soc/codecs/nau8822.h
@@ -0,0 +1,204 @@
+/*
+ * nau8822.h -- NAU8822 Soc Audio Codec driver
+ *
+ * Author: David Lin <ctlin0(a)nuvoton.com>
+ * Co-author: John Hsu <kchsu0(a)nuvoton.com>
+ * Co-author: Seven Li <wtli(a)nuvoton.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __NAU8822_H__
+#define __NAU8822_H__
+
+#define NAU8822_REG_RESET 0x00
+#define NAU8822_REG_POWER_MANAGEMENT_1 0x01
+#define NAU8822_REG_POWER_MANAGEMENT_2 0x02
+#define NAU8822_REG_POWER_MANAGEMENT_3 0x03
+#define NAU8822_REG_AUDIO_INTERFACE 0x04
+#define NAU8822_REG_COMPANDING_CONTROL 0x05
+#define NAU8822_REG_CLOCKING 0x06
+#define NAU8822_REG_ADDITIONAL_CONTROL 0x07
+#define NAU8822_REG_GPIO_CONTROL 0x08
+#define NAU8822_REG_JACK_DETECT_CONTROL_1 0x09
+#define NAU8822_REG_DAC_CONTROL 0x0A
+#define NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME 0x0B
+#define NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME 0x0C
+#define NAU8822_REG_JACK_DETECT_CONTROL_2 0x0D
+#define NAU8822_REG_ADC_CONTROL 0x0E
+#define NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME 0x0F
+#define NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME 0x10
+#define NAU8822_REG_EQ1 0x12
+#define NAU8822_REG_EQ2 0x13
+#define NAU8822_REG_EQ3 0x14
+#define NAU8822_REG_EQ4 0x15
+#define NAU8822_REG_EQ5 0x16
+#define NAU8822_REG_DAC_LIMITER_1 0x18
+#define NAU8822_REG_DAC_LIMITER_2 0x19
+#define NAU8822_REG_NOTCH_FILTER_1 0x1B
+#define NAU8822_REG_NOTCH_FILTER_2 0x1C
+#define NAU8822_REG_NOTCH_FILTER_3 0x1D
+#define NAU8822_REG_NOTCH_FILTER_4 0x1E
+#define NAU8822_REG_ALC_CONTROL_1 0x20
+#define NAU8822_REG_ALC_CONTROL_2 0x21
+#define NAU8822_REG_ALC_CONTROL_3 0x22
+#define NAU8822_REG_NOISE_GATE 0x23
+#define NAU8822_REG_PLL_N 0x24
+#define NAU8822_REG_PLL_K1 0x25
+#define NAU8822_REG_PLL_K2 0x26
+#define NAU8822_REG_PLL_K3 0x27
+#define NAU8822_REG_3D_CONTROL 0x29
+#define NAU8822_REG_RIGHT_SPEAKER_CONTROL 0x2B
+#define NAU8822_REG_INPUT_CONTROL 0x2C
+#define NAU8822_REG_LEFT_INP_PGA_CONTROL 0x2D
+#define NAU8822_REG_RIGHT_INP_PGA_CONTROL 0x2E
+#define NAU8822_REG_LEFT_ADC_BOOST_CONTROL 0x2F
+#define NAU8822_REG_RIGHT_ADC_BOOST_CONTROL 0x30
+#define NAU8822_REG_OUTPUT_CONTROL 0x31
+#define NAU8822_REG_LEFT_MIXER_CONTROL 0x32
+#define NAU8822_REG_RIGHT_MIXER_CONTROL 0x33
+#define NAU8822_REG_LHP_VOLUME 0x34
+#define NAU8822_REG_RHP_VOLUME 0x35
+#define NAU8822_REG_LSPKOUT_VOLUME 0x36
+#define NAU8822_REG_RSPKOUT_VOLUME 0x37
+#define NAU8822_REG_AUX2_MIXER 0x38
+#define NAU8822_REG_AUX1_MIXER 0x39
+#define NAU8822_REG_POWER_MANAGEMENT_4 0x3A
+#define NAU8822_REG_LEFT_TIME_SLOT 0x3B
+#define NAU8822_REG_MISC 0x3C
+#define NAU8822_REG_RIGHT_TIME_SLOT 0x3D
+#define NAU8822_REG_DEVICE_REVISION 0x3E
+#define NAU8822_REG_DEVICE_ID 0x3F
+#define NAU8822_REG_DAC_DITHER 0x41
+#define NAU8822_REG_ALC_ENHANCE_1 0x46
+#define NAU8822_REG_ALC_ENHANCE_2 0x47
+#define NAU8822_REG_192KHZ_SAMPLING 0x48
+#define NAU8822_REG_MISC_CONTROL 0x49
+#define NAU8822_REG_INPUT_TIEOFF 0x4A
+#define NAU8822_REG_POWER_REDUCTION 0x4B
+#define NAU8822_REG_AGC_PEAK2PEAK 0x4C
+#define NAU8822_REG_AGC_PEAK_DETECT 0x4D
+#define NAU8822_REG_AUTOMUTE_CONTROL 0x4E
+#define NAU8822_REG_OUTPUT_TIEOFF 0x4F
+#define NAU8822_REG_MAX_REGISTER NAU8822_REG_OUTPUT_TIEOFF
+
+/* NAU8822_REG_POWER_MANAGEMENT_1 (0x1) */
+#define NAU8822_REFIMP_MASK 0x3
+#define NAU8822_REFIMP_80K 0x1
+#define NAU8822_REFIMP_300K 0x2
+#define NAU8822_REFIMP_3K 0x3
+#define NAU8822_IOBUF_EN (0x1 << 2)
+#define NAU8822_ABIAS_EN (0x1 << 3)
+
+/* NAU8822_REG_AUDIO_INTERFACE (0x4) */
+#define NAU8822_AIFMT_MASK (0x3 << 3)
+#define NAU8822_WLEN_MASK (0x3 << 5)
+#define NAU8822_WLEN_20 (0x1 << 5)
+#define NAU8822_WLEN_24 (0x2 << 5)
+#define NAU8822_WLEN_32 (0x3 << 5)
+#define NAU8822_LRP_MASK (0x1 << 7)
+#define NAU8822_BCLKP_MASK (0x1 << 8)
+
+/* NAU8822_REG_COMPANDING_CONTROL (0x5) */
+#define NAU8822_ADDAP_SFT 0
+#define NAU8822_ADCCM_SFT 1
+#define NAU8822_DACCM_SFT 3
+
+/* NAU8822_REG_CLOCKING (0x6) */
+#define NAU8822_CLKIOEN_MASK 0x1
+#define NAU8822_MCLKSEL_SFT 5
+#define NAU8822_MCLKSEL_MASK (0x7 << 5)
+#define NAU8822_BCLKSEL_SFT 2
+#define NAU8822_BCLKSEL_MASK (0x7 << 2)
+#define NAU8822_CLKM_MASK (0x1 << 8)
+#define NAU8822_CLKM_MCLK (0x0 << 8)
+#define NAU8822_CLKM_PLL (0x1 << 8)
+
+/* NAU8822_REG_ADDITIONAL_CONTROL (0x08) */
+#define NAU8822_SMPLR_SFT 1
+#define NAU8822_SMPLR_MASK (0x7 << 1)
+#define NAU8822_SMPLR_48K (0x0 << 1)
+#define NAU8822_SMPLR_32K (0x1 << 1)
+#define NAU8822_SMPLR_24K (0x2 << 1)
+#define NAU8822_SMPLR_16K (0x3 << 1)
+#define NAU8822_SMPLR_12K (0x4 << 1)
+#define NAU8822_SMPLR_8K (0x5 << 1)
+
+/* NAU8822_REG_EQ1 (0x12) */
+#define NAU8822_EQ1GC_SFT 0
+#define NAU8822_EQ1CF_SFT 5
+#define NAU8822_EQM_SFT 8
+
+/* NAU8822_REG_EQ2 (0x13) */
+#define NAU8822_EQ2GC_SFT 0
+#define NAU8822_EQ2CF_SFT 5
+#define NAU8822_EQ2BW_SFT 8
+
+/* NAU8822_REG_EQ3 (0x14) */
+#define NAU8822_EQ3GC_SFT 0
+#define NAU8822_EQ3CF_SFT 5
+#define NAU8822_EQ3BW_SFT 8
+
+/* NAU8822_REG_EQ4 (0x15) */
+#define NAU8822_EQ4GC_SFT 0
+#define NAU8822_EQ4CF_SFT 5
+#define NAU8822_EQ4BW_SFT 8
+
+/* NAU8822_REG_EQ5 (0x16) */
+#define NAU8822_EQ5GC_SFT 0
+#define NAU8822_EQ5CF_SFT 5
+
+/* NAU8822_REG_ALC_CONTROL_1 (0x20) */
+#define NAU8822_ALCMINGAIN_SFT 0
+#define NAU8822_ALCMXGAIN_SFT 3
+#define NAU8822_ALCEN_SFT 7
+
+/* NAU8822_REG_ALC_CONTROL_2 (0x21) */
+#define NAU8822_ALCSL_SFT 0
+#define NAU8822_ALCHT_SFT 4
+
+/* NAU8822_REG_ALC_CONTROL_3 (0x22) */
+#define NAU8822_ALCATK_SFT 0
+#define NAU8822_ALCDCY_SFT 4
+#define NAU8822_ALCM_SFT 8
+
+/* NAU8822_REG_PLL_N (0x24) */
+#define NAU8822_PLLMCLK_DIV2 (0x1 << 4)
+#define NAU8822_PLLN_MASK 0xF
+
+#define NAU8822_PLLK1_SFT 18
+#define NAU8822_PLLK1_MASK 0x3F
+
+/* NAU8822_REG_PLL_K2 (0x26) */
+#define NAU8822_PLLK2_SFT 9
+#define NAU8822_PLLK2_MASK 0x1FF
+
+/* NAU8822_REG_PLL_K3 (0x27) */
+#define NAU8822_PLLK3_MASK 0x1FF
+
+/* System Clock Source */
+enum {
+ NAU8822_CLK_MCLK,
+ NAU8822_CLK_PLL,
+};
+
+struct nau8822_pll {
+ int pre_factor;
+ int mclk_scaler;
+ int pll_frac;
+ int pll_int;
+};
+
+/* Codec Private Data */
+struct nau8822 {
+ struct device *dev;
+ struct regmap *regmap;
+ int mclk_idx;
+ struct nau8822_pll pll;
+ int sysclk;
+ int div_id;
+};
+
+#endif /* __NAU8822_H__ */
--
2.18.0
3
5

17 Oct '18
Hi Matthieu,
On Wed, Jun 06, 2018 at 09:38:08PM +0200, Mathieu Malaterre wrote:
> diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
> index 1a354a6b6e87..35d82d96e781 100644
> --- a/sound/soc/jz4740/Kconfig
> +++ b/sound/soc/jz4740/Kconfig
> @@ -1,20 +1,20 @@
> config SND_JZ4740_SOC
> - tristate "SoC Audio for Ingenic JZ4740 SoC"
> - depends on MACH_JZ4740 || COMPILE_TEST
> + tristate "SoC Audio for Ingenic JZ4740/JZ4780 SoC"
> + depends on MACH_JZ4740 || MACH_JZ4780 || COMPILE_TEST
Perhaps this could be MACH_INGENIC, or even just MIPS?
Thanks,
Paul
2
4
Hi,
As in previous years we're trying to organize an audio miniconference so
we can get together and talk through issues, especially design decisons,
face to face. This year's event will be held on Sunday October 21st in
Edinburgh, the day before ELC Europe starts there. We're still
finalizing the venue (we expect to be able to confirm next week) but
it'll be outside the ELC venue so there will be no need to purchase an
ELC ticket to attend.
As with previous years let's pull together an agenda through a mailing
list discussion - if people could reply to this mail with any topics
they'd like to discuss we can take it from there. Of course if we can
sort things out more quickly via the mailing list that's even better!
If you're planning to attend please fill out the form here:
https://docs.google.com/spreadsheets/d/11p2pSNxS7sJysg1JwErWi0T2Dq7XKRtAGng…
Thanks,
Mark
6
10

11 Oct '18
Hi everyone,
I’m hoping that somebody here might be able to spot where I’m going wrong; I'm working with a picture-frame-like device manufactured by the late OpenPeak Inc. known as the OpenFrame (or O2 Joggler in the UK). It has an internal speaker and a 3.5mm line out socket; none of the other connections to its STAC9202 codec chip are exposed to the end user. I've been porting Ubuntu Bionic to the device and everything is done, except for the audio driver.
Back in kernel 3.18 it was possible to use the following kernel patch and userland ALSA patch to have these two outputs work correctly, with the insertion of a plug into the line out properly muting the internal speaker.
https://github.com/andydvsn/OpenFrame-Kernel/blob/master/patches/03-stac920…
https://github.com/andydvsn/OpenFrame-Ubuntu/blob/master/overlay-trusty/lib…
In kernel 4.14 the same trick no longer works, so I've rewritten the patch to more properly add support for this variant of STAC9202 to ALSA. It now looks like this:
https://gist.github.com/andydvsn/7bffa8de0ed691b14508485d75501ffc
This seems to line up the pin configurations appropriately, but when a plug is inserted to the line out, although the audio to the internal speaker is muted, the speaker emits a crackling sound whenever the device is processing. It seems that it is not being properly powered down and is amplifying general circuit noise. Disconnecting the plug returns sound to the internal speaker and the crackling ceases. This is reliable across multiple devices.
Here is the alsa-info output from both the crackling kernel 4.14 and the working-just-fine kernel 3.18.
https://gist.github.com/andydvsn/ccf55e6f7961dd405fc39d41a6ce9ef6
I don't have sufficient knowledge of ALSA drivers and patches and have been working purely from the configurations used by others over the years, so I would really appreciate somebody looking at the alsa-info output and the new patch to determine where I should go from here. I believe this is all to do with EAPD control, but what options I have for controlling that aren't known to me right now.
Ideally, I want to end up with the audio muting and switching correctly when the jack is inserted. A bonus would be to lose the unused (or at least inaccessible) audio input and output options in alsamixer and gain individual control of the internal speaker and line out levels (which appear to be paired together at the moment).
All the best,
A.
--
Andrew Davison
2
11
This patch series adds support for the Sound Blaster ZxR, as well as a
few bug fixes. This should be the last ca0132 based Creative card that
needed support to be added.
Also, I did check to make sure each patch compiles properly this time,
but you can check yourself just to be sure. :)
Connor McAdams (11):
ALSA: hda/ca0132 - Fix AE-5 control type
ALSA: hda/ca0132 - Fix surround sound with output effects
ALSA: hda/ca0132 - Add ZxR quirks + new quirk check function
ALSA: hda/ca0132 - Add ZxR pincfg
ALSA: hda/ca0132 - Add DBpro hda_codec_ops
ALSA: hda/ca0132 - Add ZxR init commands
ALSA: hda/ca0132 - Add ZxR DSP post-download commands
ALSA: hda/ca0132 - Add ZxR input/output select commands
ALSA: hda/ca0132 - Remove input select enum for ZxR
ALSA: hda/ca0132 - Add ZxR 600 ohm gain control
ALSA: hda/ca0132 - Add ZxR exit commands
sound/pci/hda/patch_ca0132.c | 369 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 345 insertions(+), 24 deletions(-)
--
2.7.4
3
17

Re: [alsa-devel] Microphone detected, but no output for all ASUS G751xx with ALC668 chipset
by Connor McAdams 08 Oct '18
by Connor McAdams 08 Oct '18
08 Oct '18
I might not get around to writing the fix myself, but, here's the
COEF's from within Windows. I've marked the ones missing inside the
main init function. So, if anyone else wants to add these in, feel
free.
On Wed, Sep 12, 2018 at 1:16 PM, Håvard <hovardslill(a)gmail.com> wrote:
> That was without running the program (sorry)
>
> This is output when running program:
>
> Before there was no "Current verb...."
> They came when I opened up windows microphone settings. (something I didn't
> do before)
>
> -Håvard
>
> Den ons. 12. sep. 2018 kl. 19:11 skrev Håvard <hovardslill(a)gmail.com>:
>>
>> I think this is right!
>>
>> I first booted up, then tested speakers (That I could not hear) and then
>> tested microphone (Which worked perfectly) in windows settings.
>>
>> (My first email was dissaproved as it was too large)
>>
>> Den ons. 12. sep. 2018 kl. 19:05 skrev Håvard <hovardslill(a)gmail.com>:
>>>
>>> I think this is right!
>>>
>>> I first booted up, then tested speakers (That I could not hear) and then
>>> tested microphone (Which worked perfectly) in windows settings.
>>>
>>> -Håvard
>>>
>>> Den ons. 12. sep. 2018 kl. 18:49 skrev Connor McAdams
>>> <conmanx360(a)gmail.com>:
>>>>
>>>> Also, sorry to keep sending more replies, make sure the only trace you
>>>> have on is vfio_region_write, and not the read one. The read spams up
>>>> the console.
>>>>
>>>> On Wed, Sep 12, 2018 at 12:43 PM, Connor McAdams <conmanx360(a)gmail.com>
>>>> wrote:
>>>> > Reason being, it may not have identified the CORB buffer properly or
>>>> > something. That's very odd to have no data. Never seen that before.
>>>> >
>>>> > On Wed, Sep 12, 2018 at 12:42 PM, Connor McAdams
>>>> > <conmanx360(a)gmail.com> wrote:
>>>> >> Could you try again and make a copy of your terminal output?
>>>> >>
>>>> >> On Wed, Sep 12, 2018 at 12:41 PM, Håvard <hovardslill(a)gmail.com>
>>>> >> wrote:
>>>> >>> Hi again.
>>>> >>> Sorry for not noticing all files were empty, did it not run for long
>>>> >>> enough?
>>>> >>>
>>>> >>> -Håvard
>>>> >>>
>>>> >>> Den ons. 12. sep. 2018 kl. 18:39 skrev Håvard
>>>> >>> <hovardslill(a)gmail.com>:
>>>> >>>>
>>>> >>>> Sorry my bad again it was working perfectly, just missed a step.
>>>> >>>>
>>>> >>>> I'll add the dumps as an attatchment. I had both external headset
>>>> >>>> and
>>>> >>>> microphone plugged in and let the VM run in the background for
>>>> >>>> ~30min while
>>>> >>>> doing other stuff. I did not play music or test my microphone in
>>>> >>>> the VM
>>>> >>>> either, If i did anything wrong, please tell me!
>>>> >>>>
>>>> >>>> It stopped at 0x104f4
>>>> >>>>
>>>> >>>> -Håvard
>>>> >>>>
>>>> >>>> Den ons. 12. sep. 2018 kl. 00:31 skrev Connor McAdams
>>>> >>>> <conmanx360(a)gmail.com>:
>>>> >>>>>
>>>> >>>>> Hm.... that's odd. They should show up in the folder you ran the
>>>> >>>>> command from. Does your console show any "DumpMem entered..." or
>>>> >>>>> something like that? You may have a permissions error. I've had
>>>> >>>>> some
>>>> >>>>> people report that as an issue before.
>>>> >>>>>
>>>> >>>>> On Tue, Sep 11, 2018 at 5:08 PM, Håvard <hovardslill(a)gmail.com>
>>>> >>>>> wrote:
>>>> >>>>> > Hi!
>>>> >>>>> >
>>>> >>>>> > Took a while, but I think I got it working. Did not see any
>>>> >>>>> > "frame[xx]"
>>>> >>>>> > files though. What dumps do you want?
>>>> >>>>> >
>>>> >>>>> > -Håvard
>>>> >>>>> >
>>>> >>>>> > Den tir. 11. sep. 2018 kl. 21:27 skrev Håvard
>>>> >>>>> > <hovardslill(a)gmail.com>:
>>>> >>>>> >>
>>>> >>>>> >> Sorry about that, I forgot to enable a kernel config...
>>>> >>>>> >>
>>>> >>>>> >> -Håvard
>>>> >>>>> >>
>>>> >>>>> >> Den tir. 11. sep. 2018 kl. 21:20 skrev Connor McAdams
>>>> >>>>> >> <conmanx360(a)gmail.com>:
>>>> >>>>> >>>
>>>> >>>>> >>> When it's bound as a stub, it shouldn't show up in alsamixer
>>>> >>>>> >>> controls.
>>>> >>>>> >>> You can check what module is loaded by doing lspci -v . It
>>>> >>>>> >>> should say
>>>> >>>>> >>> kernel driver in use: pci-stub. Also, did you run the
>>>> >>>>> >>> vfio-bind
>>>> >>>>> >>> script
>>>> >>>>> >>> before trying it?
>>>> >>>>> >>>
>>>> >>>>> >>> On Tue, Sep 11, 2018 at 3:18 PM, Håvard
>>>> >>>>> >>> <hovardslill(a)gmail.com>
>>>> >>>>> >>> wrote:
>>>> >>>>> >>> > Thank you for the offer!
>>>> >>>>> >>> >
>>>> >>>>> >>> > I run gentoo, but your github guide is very useful. I can't
>>>> >>>>> >>> > seem to
>>>> >>>>> >>> > bind my
>>>> >>>>> >>> > audio driver to a pci-stud. Is the Sound card still supposed
>>>> >>>>> >>> > to
>>>> >>>>> >>> > function as
>>>> >>>>> >>> > normal when I (think I) have bound it to a stud.
>>>> >>>>> >>> >
>>>> >>>>> >>> > -Håvard
>>>> >>>>> >>> >
>>>> >>>>> >>> > Den tir. 11. sep. 2018 kl. 20:26 skrev Connor McAdams
>>>> >>>>> >>> > <conmanx360(a)gmail.com>:
>>>> >>>>> >>> >>
>>>> >>>>> >>> >> One thing you could try, is using the program I used to
>>>> >>>>> >>> >> reverse
>>>> >>>>> >>> >> engineer the Sound Blaster Z series of cards, QemuHDADump.
>>>> >>>>> >>> >> If your
>>>> >>>>> >>> >> processor supports pci-passthrough with a virtual machine,
>>>> >>>>> >>> >> you
>>>> >>>>> >>> >> could
>>>> >>>>> >>> >> run a Windows virtual machine with the sound card in it and
>>>> >>>>> >>> >> capture
>>>> >>>>> >>> >> the commands. I'd be willing to look through the dumps to
>>>> >>>>> >>> >> see if
>>>> >>>>> >>> >> there
>>>> >>>>> >>> >> are any special verbs or anything.
>>>> >>>>> >>> >>
>>>> >>>>> >>> >> You can find the program here:
>>>> >>>>> >>> >> https://github.com/Conmanx360/QemuHDADump
>>>> >>>>> >>> >>
>>>> >>>>> >>> >> Let me know.
>>>> >>>>> >>> >>
>>>> >>>>> >>> >> On Tue, Sep 11, 2018 at 2:15 PM, Håvard
>>>> >>>>> >>> >> <hovardslill(a)gmail.com>
>>>> >>>>> >>> >> wrote:
>>>> >>>>> >>> >> > Sorry, my gmail didn't update so I wrote my response
>>>> >>>>> >>> >> > before I
>>>> >>>>> >>> >> > read
>>>> >>>>> >>> >> > your
>>>> >>>>> >>> >> > last one.
>>>> >>>>> >>> >> >
>>>> >>>>> >>> >> > It is a separate mic port as the G751JT doesn't have any
>>>> >>>>> >>> >> > headset
>>>> >>>>> >>> >> > multijacks.
>>>> >>>>> >>> >> >
>>>> >>>>> >>> >> > I'll try and dig around in the kernel! Thanks for the
>>>> >>>>> >>> >> > tip!
>>>> >>>>> >>> >> >
>>>> >>>>> >>> >> > -Håvard
>>>> >>>>> >>> >> >
>>>> >>>>> >>> >> > Den tir. 11. sep. 2018 kl. 20:09 skrev Håvard
>>>> >>>>> >>> >> > <hovardslill(a)gmail.com>:
>>>> >>>>> >>> >> >
>>>> >>>>> >>> >> >> Thank you for taking your time and trying to help! :)
>>>> >>>>> >>> >> >>
>>>> >>>>> >>> >> >> Do you know where I can ask around for more help on the
>>>> >>>>> >>> >> >> issue?
>>>> >>>>> >>> >> >> I
>>>> >>>>> >>> >> >> don't
>>>> >>>>> >>> >> >> want to give up yet.
>>>> >>>>> >>> >> >>
>>>> >>>>> >>> >> >> -Håvard
>>>> >>>>> >>> >> >>
>>>> >>>>> >>> >> >> Den tir. 11. sep. 2018 kl. 20:02 skrev Takashi Iwai
>>>> >>>>> >>> >> >> <tiwai(a)suse.de>:
>>>> >>>>> >>> >> >>
>>>> >>>>> >>> >> >>> On Tue, 11 Sep 2018 19:14:37 +0200,
>>>> >>>>> >>> >> >>> Håvard wrote:
>>>> >>>>> >>> >> >>> >
>>>> >>>>> >>> >> >>> > Yes, microphone gets detected instantly and it
>>>> >>>>> >>> >> >>> > automatically
>>>> >>>>> >>> >> >>> > changes
>>>> >>>>> >>> >> >>> > to
>>>> >>>>> >>> >> >>> it
>>>> >>>>> >>> >> >>> > in pavucontrol.
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>> Then it likely requires some additional initialization
>>>> >>>>> >>> >> >>> outside
>>>> >>>>> >>> >> >>> HD-audio. It's hard to know, as it's pretty much
>>>> >>>>> >>> >> >>> vendor-specific.
>>>> >>>>> >>> >> >>> You can dig down the Windows, but I have no idea about
>>>> >>>>> >>> >> >>> Windows
>>>> >>>>> >>> >> >>> implementation, so can't give any hints, unfortunately.
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>> Takashi
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>> >
>>>> >>>>> >>> >> >>> > Den tir. 11. sep. 2018 kl. 18:52 skrev Takashi Iwai
>>>> >>>>> >>> >> >>> > <tiwai(a)suse.de>:
>>>> >>>>> >>> >> >>> >
>>>> >>>>> >>> >> >>> > > On Tue, 11 Sep 2018 18:40:23 +0200,
>>>> >>>>> >>> >> >>> > > Håvard wrote:
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > Thank you for replying!
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > Enabling loopback in alsamixer:
>>>> >>>>> >>> >> >>> > > > http://i.imgur.com/lNo6e7T.png
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > And unmuting more and more things in "Mic
>>>> >>>>> >>> >> >>> > > > Playback
>>>> >>>>> >>> >> >>> > > > Volume"
>>>> >>>>> >>> >> >>> > > > in
>>>> >>>>> >>> >> >>> > > hdaanalyzer:
>>>> >>>>> >>> >> >>> > > > http://i.imgur.com/H0HiOhy.png
>>>> >>>>> >>> >> >>> > > > made white noise come from the headset. However
>>>> >>>>> >>> >> >>> > > > it did
>>>> >>>>> >>> >> >>> > > > not
>>>> >>>>> >>> >> >>> > > > change or
>>>> >>>>> >>> >> >>> > > react
>>>> >>>>> >>> >> >>> > > > at all when I talked or even muted the microphone
>>>> >>>>> >>> >> >>> > > > physically.
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > I couldn't find "Mic Playback Switch" anywhere in
>>>> >>>>> >>> >> >>> > > > either
>>>> >>>>> >>> >> >>> > > > alsamixer
>>>> >>>>> >>> >> >>> or
>>>> >>>>> >>> >> >>> > > > hdaanalyzer.
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > > It's a mixer mute switch.
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > > > The microphone works perfectly fine under
>>>> >>>>> >>> >> >>> > > > Windows, so I
>>>> >>>>> >>> >> >>> > > > don't
>>>> >>>>> >>> >> >>> > > > think
>>>> >>>>> >>> >> >>> it is
>>>> >>>>> >>> >> >>> > > > the mic pin.
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > > But the fact above indicates the possibility of the
>>>> >>>>> >>> >> >>> > > wrong
>>>> >>>>> >>> >> >>> > > pin,
>>>> >>>>> >>> >> >>> > > too.
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > > Does the jack detection of the ext mic pin work?
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > > Takashi
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > -Håvard
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > Den man. 10. sep. 2018 kl. 22:39 skrev Takashi
>>>> >>>>> >>> >> >>> > > > Iwai
>>>> >>>>> >>> >> >>> > > > <tiwai(a)suse.de
>>>> >>>>> >>> >> >>> >:
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > > > > On Thu, 06 Sep 2018 20:44:30 +0200,
>>>> >>>>> >>> >> >>> > > > > Håvard wrote:
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > Additional relevant info:
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > A similar issue was also discussed three
>>>> >>>>> >>> >> >>> > > > > > years ago
>>>> >>>>> >>> >> >>> > > > > > on
>>>> >>>>> >>> >> >>> > > > > > Sun
>>>> >>>>> >>> >> >>> > > > > > Jun
>>>> >>>>> >>> >> >>> > > 17:15:54
>>>> >>>>> >>> >> >>> > > > > CEST
>>>> >>>>> >>> >> >>> > > > > > 2015 and was about his surround sound setup,
>>>> >>>>> >>> >> >>> > > > > > but did
>>>> >>>>> >>> >> >>> > > > > > not
>>>> >>>>> >>> >> >>> > > > > > touch
>>>> >>>>> >>> >> >>> on the
>>>> >>>>> >>> >> >>> > > > > > external microphone problem:
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>> http://mailman.alsa-project.org/pipermail/alsa-devel/2015-June/093317.html
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > alsa-info.sh:
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>> http://www.alsa-project.org/db/?f=1d8616ba5977308e03db6c3a86e36e9e9b38d6f0
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > Graph of ALC668 chipset from hdaanalyzer:
>>>> >>>>> >>> >> >>> > > > > > http://i.imgur.com/c08DNJW.png
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > setting alsa-mode[1-8] does nothing to help
>>>> >>>>> >>> >> >>> > > > > > the
>>>> >>>>> >>> >> >>> > > > > > issue.
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > There are several of similar bug reports
>>>> >>>>> >>> >> >>> > > > > > around the
>>>> >>>>> >>> >> >>> > > > > > web
>>>> >>>>> >>> >> >>> experiencing
>>>> >>>>> >>> >> >>> > > > > > similar issues, and on different distros.
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > Microphone works perfectly in windows
>>>> >>>>> >>> >> >>> > > > > >
>>>> >>>>> >>> >> >>> > > > > > I have a ASUS ROG G751JT, but this problem
>>>> >>>>> >>> >> >>> > > > > > seems to
>>>> >>>>> >>> >> >>> > > > > > happen
>>>> >>>>> >>> >> >>> > > > > > with
>>>> >>>>> >>> >> >>> all
>>>> >>>>> >>> >> >>> > > > > laptops
>>>> >>>>> >>> >> >>> > > > > > under the G751 name.
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > > > > When you enable the loopback volume and switch,
>>>> >>>>> >>> >> >>> > > > > and
>>>> >>>>> >>> >> >>> > > > > unmute/adjust
>>>> >>>>> >>> >> >>> "Mic
>>>> >>>>> >>> >> >>> > > > > Playback Volume", and "Mic Playback Switch", do
>>>> >>>>> >>> >> >>> > > > > you
>>>> >>>>> >>> >> >>> > > > > hear
>>>> >>>>> >>> >> >>> > > > > the
>>>> >>>>> >>> >> >>> > > > > input
>>>> >>>>> >>> >> >>> > > > > from the ext mic? It's a route directly from
>>>> >>>>> >>> >> >>> > > > > NID 0x18
>>>> >>>>> >>> >> >>> > > > > to
>>>> >>>>> >>> >> >>> > > > > the
>>>> >>>>> >>> >> >>> mixer
>>>> >>>>> >>> >> >>> > > > > NID 0x0b, then output mixer NID 0x0c, then
>>>> >>>>> >>> >> >>> > > > > outputs.
>>>> >>>>> >>> >> >>> > > > > So
>>>> >>>>> >>> >> >>> > > > > this
>>>> >>>>> >>> >> >>> > > > > can
>>>> >>>>> >>> >> >>> be
>>>> >>>>> >>> >> >>> > > > > used to verify the hardware routing.
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > > > > If you don't hear via this route, it means that
>>>> >>>>> >>> >> >>> > > > > the
>>>> >>>>> >>> >> >>> > > > > input
>>>> >>>>> >>> >> >>> > > > > from
>>>> >>>>> >>> >> >>> the ext
>>>> >>>>> >>> >> >>> > > > > mic pin itself is broken, and it implies that
>>>> >>>>> >>> >> >>> > > > > something
>>>> >>>>> >>> >> >>> > > > > outside
>>>> >>>>> >>> >> >>> > > > > HD-audio codec.
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > > > > Takashi
>>>> >>>>> >>> >> >>> > > > >
>>>> >>>>> >>> >> >>> > > > [2 <text/html; UTF-8 (quoted-printable)>]
>>>> >>>>> >>> >> >>> > > >
>>>> >>>>> >>> >> >>> > >
>>>> >>>>> >>> >> >>> > [2 <text/html; UTF-8 (quoted-printable)>]
>>>> >>>>> >>> >> >>> >
>>>> >>>>> >>> >> >>>
>>>> >>>>> >>> >> >>
>>>> >>>>> >>> >> > _______________________________________________
>>>> >>>>> >>> >> > Alsa-devel mailing list
>>>> >>>>> >>> >> > Alsa-devel(a)alsa-project.org
>>>> >>>>> >>> >> >
>>>> >>>>> >>> >> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
3
26