From 59e7a359e7748cb33cd0a7918a7ea4f12ca77974 Mon Sep 17 00:00:00 2001 From: "riqun.ou" Date: Thu, 8 Nov 2018 15:47:32 +0800 Subject: [PATCH] sound: add resample node for axg_s420_v03gva.dts [1/1] PD#SWPL-365 Problem: System can't use resample function on GVA project. Solution: Add resample node in axg_s420_v03gva.dts Verify: Passed on s420 Change-Id: Ie48c579e9e9f6e1d61147f5410c95e5bca55b0a7 Signed-off-by: riqun.ou audio: codecs: fix TL1 reference board volume too small [2/2] PD#SWPL-2652 Problem: X301/T309 AMP volume configured to small Solution: change the default external AMP codec mixer name to a match the ini parsing function in audio hal. TODO: need dynamically check the different codec mixer name in ini file. Verify: verify by x301 Change-Id: Iba835d37ea02bec3095556d54fbf327bd6390904 Signed-off-by: Jian Xu audio: codec: the DAC gain set of acodec not work [1/1] PD#SWPL-3134 Problem: the DAC gain set is not work Solution: update and aml_codec_tl1_acodec.c, change the method of getting codec pointer from kcontrol pointer. Verify: verify by T962x2_X301 board Change-Id: I02f02b73fab3b8391ef4866a71ffaf0d48bbbbbf Signed-off-by: Shuyu Li audio: add tas5805 [1/1] PD#SWPL-3081 Problem: compatiable tas5805 module Solution: add tas5805 drivers Verify: T962X2 Change-Id: I3608e47fe768af0f924751a8bcc103389d0811de Signed-off-by: Yonghao Jiao audio: auge: add HDMIRX SPDIF in support [1/2] PD#SWPL-2956 Problem: HDMI in DTS/Dolby input has noise when treated to LPCM Solution: By default,we are using PAO mode for HDMIRX,but we have not enabled the PaPb search for 61937 raw data input, after add that, we can detect the raw data, but it can not by clear when switch from NONE-LPCM to NONE-LPCM, need add IRQ function to clear that by sw.we enabled spdif in from HDMIRX, which is the same design as txl/txlx.we can get the Pc information now. also we add a new interface to set spdif in source when hdmirx input. Verify: x301 Change-Id: I3c4e8b387308ef862a069c29d15b8b5a9e865564 Signed-off-by: Jian Xu udio: auge: tl1 acodec mapping to data 1 [1/2] PD#SWPL-3277 Problem: tl1 internal codec volume can by adjusted Solution: configure the acodec data layout mapping to a fixed volume Verify: x301 Change-Id: I14d3762b39a0a5291722ef5489026f10fc960120 Signed-off-by: Jian Xu Conflicts: arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts audio: Fix TDM not wokring on HDMI I2S in [1/1] PD#SWPL-2887 Problem: When TDM is used for HDMI I2S in, the solt set is wrong. Solution: Fix the lane max value from 3 to 4 Verify: A113 Change-Id: I33f5ca21bf1e2407d83fa5d0f22e21f7b1f5e749 Signed-off-by: yujie.wu audio: codec: fix to resume ad82584's volume after suspend [1/1] PD#SWPL-3456 Problem: 1) After suspend, volume is not resume 2) ARC connected, still sound out from spk Solution: 1) save channel volume when suspend, then resume the volume 2) add mute mixer control for ad82584 Verify: x301 Change-Id: Ic6e7502e3f9689cc2d1053295f26aaf4d5be2603 Signed-off-by: Xing Wang audio: auge: add vad driver [1/1] PD#SWPL-2404 Problem: VAD for wake up Solution: Add vad driver to fetch VAD buffer and ALSA buffer, in userspace, they will be combined for wakeup engine Verify: x301 Change-Id: I3b4de5fdfe173ce18e58a187a3adeda601e226b3 Signed-off-by: Xing Wang audio: fix pop snd after bootup [2/2] PD#SWPL-3178 Problem: output big pop noise after system boot up. Solution: Add zero and then unmute the stream. NOTICE: user should unmute the AD82584F after boot. Verify: local verified. Change-Id: I21555318f9347c5340a28f7e5cf0e3e2cde849a0 Signed-off-by: Shuai Li audio: fix no audio after resume of ad82584f [1/1] PD#SWPL-4090 Problem: No audio after suspend and resume. Suspend won't save the mute value, and after resume, it could not be restored. Solution: Add a mute val to save when suspend, and after resume, restore the mute value. Verify: Verified by QA. Change-Id: Ie24bb11f5c565048391846a66b5d12bab1d55666 Signed-off-by: Shuai Li audio: auge: fix sharebuffer channel map [1/1] PD#SWPL-2645 Problem: play ddp source, then play pcm source, no sound Solution: 1. fix same source control and channel map issue 2. i2s 8ch, spdif 2ch, channels are not mapped, make spdif 8 channel mask 3. when same source used, keep mpll use same mpll Verify: x301 Change-Id: I2fe4bbcbcbfff0a1c1a6cebf61d1da5aba9b7a9d Signed-off-by: Xing Wang Conflicts: arch/arm64/boot/dts/amlogic/tl1_t962x2_t309.dts arch/arm64/boot/dts/amlogic/tl1_t962x2_x301.dts audio: add stream mute and continuous clk [1/1] PD#SWPL-2952 Problem: Pop noise could be heard when switching between sources. Solution: 1. Add stream digital mute functions. 2. continuous clock to eliminate the clk reset issue. Verify: Local verified. Change-Id: I372f4c03aaf875d75aa903c9c2dfda00619af000 Signed-off-by: Shuai Li dts: tl1: enable resample for tl1 [1/2] PD#SWPL-3365 Problem: not resample for audio in, so output in wrong sample rate Solution: 1. enable resample in dts 2. fix to check whether resample is needed Verify: x301 Change-Id: I99238cc21a00ab53df6a1f8ab1703bc9ab48cbaa Signed-off-by: Xing Wang Conflicts: arch/arm64/boot/dts/amlogic/tl1_t962x2_t309.dts arch/arm64/boot/dts/amlogic/tl1_t962x2_x301.dts --- .../devicetree/bindings/sound/tas5805.txt | 18 + MAINTAINERS | 10 + arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts | 29 +- arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts | 1776 ++++++++++++++++ arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts | 56 +- arch/arm/configs/meson64_a32_defconfig | 1 + .../boot/dts/amlogic/axg_s400_v03gva.dts | 8 +- .../boot/dts/amlogic/axg_s420_v03gva.dts | 30 +- include/linux/amlogic/major.h | 1 + sound/soc/amlogic/auge/Makefile | 5 +- sound/soc/amlogic/auge/audio_utils.c | 5 + sound/soc/amlogic/auge/ddr_mngr.c | 473 +++-- sound/soc/amlogic/auge/ddr_mngr.h | 159 +- sound/soc/amlogic/auge/extn.c | 74 +- sound/soc/amlogic/auge/frhdmirx_hw.c | 19 +- sound/soc/amlogic/auge/frhdmirx_hw.h | 2 +- sound/soc/amlogic/auge/locker.c | 4 +- sound/soc/amlogic/auge/pdm.c | 27 +- sound/soc/amlogic/auge/resample.c | 43 +- sound/soc/amlogic/auge/resample_hw.c | 4 +- sound/soc/amlogic/auge/sharebuffer.c | 11 +- sound/soc/amlogic/auge/spdif.c | 78 +- sound/soc/amlogic/auge/spdif_hw.c | 36 +- sound/soc/amlogic/auge/spdif_hw.h | 3 +- sound/soc/amlogic/auge/tdm.c | 184 +- sound/soc/amlogic/auge/tdm_hw.c | 165 +- sound/soc/amlogic/auge/tdm_hw.h | 12 + sound/soc/amlogic/auge/vad.c | 786 +++++++ sound/soc/amlogic/auge/vad.h | 47 + sound/soc/amlogic/auge/vad_dev.c | 175 ++ sound/soc/amlogic/auge/vad_hw.c | 109 + sound/soc/amlogic/auge/vad_hw.h | 38 + sound/soc/amlogic/auge/vad_hw_coeff.c | 167 ++ sound/soc/amlogic/common/spdif_info.c | 3 +- sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/amlogic/Kconfig | 11 + sound/soc/codecs/amlogic/Makefile | 2 + sound/soc/codecs/amlogic/ad82584f.c | 37 +- sound/soc/codecs/amlogic/ad82584f.h | 1 + .../soc/codecs/amlogic/aml_codec_tl1_acodec.c | 12 +- sound/soc/codecs/amlogic/tas5707.c | 1 + sound/soc/codecs/amlogic/tas5805.c | 547 +++++ sound/soc/codecs/amlogic/tas5805.h | 1880 +++++++++++++++++ 43 files changed, 6707 insertions(+), 352 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/tas5805.txt create mode 100644 arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts create mode 100644 sound/soc/amlogic/auge/vad.c create mode 100644 sound/soc/amlogic/auge/vad.h create mode 100644 sound/soc/amlogic/auge/vad_dev.c create mode 100644 sound/soc/amlogic/auge/vad_hw.c create mode 100644 sound/soc/amlogic/auge/vad_hw.h create mode 100644 sound/soc/amlogic/auge/vad_hw_coeff.c create mode 100644 sound/soc/codecs/amlogic/tas5805.c create mode 100644 sound/soc/codecs/amlogic/tas5805.h diff --git a/Documentation/devicetree/bindings/sound/tas5805.txt b/Documentation/devicetree/bindings/sound/tas5805.txt new file mode 100644 index 000000000000..05ff201dfcef --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tas5805.txt @@ -0,0 +1,18 @@ +Texas Instruments TAS5805 Audio amplifier + +The TAS5805 serial control bus communicates through the I2C protocol only. The +serial bus is also used for periodic codec fault checking/reporting during +audio playback. For more product information please see the links below: + +Required properties: + +- compatible : "ti, tas5805" +- reg : I2C slave address + +Example: + +tas5805: tas5805@7c { + status = "okay"; + compatible = "ti,tas5805"; + reg = <0x2d>; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 2f620e259d90..3b52b6cc3e59 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13982,6 +13982,14 @@ F: sound/soc/codecs/amlogic/Makefile F: sound/soc/codecs/amlogic/tas5707.c F: sound/soc/codecs/amlogic/tas5707.h +AMLOGIC Audio codec driver +M: Yonghao Jiao +F: arch/arm/configs/meson32_deconfig +F: sound/soc/codecs/amlogic/Kconfig +F: sound/soc/codecs/amlogic/Makefile +F: sound/soc/codecs/amlogic/tas5805.c +F: sound/soc/codecs/amlogic/tas5805.h + AMLOGIC AXG ADD DTS FOR A113D SOCKET AND DEVELOPMENT BOARDS M: Yun Cai F: arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts @@ -14672,10 +14680,12 @@ AMLOGIC TL1 SOUND CARD AMLOGIC TL1 AUDIO EXTERANL INPUT/OUTPUT DRIVERS AMLOGIC TL1 NEW EQDRC AMLOGIC TL1 MIXER CONTROLS +AMLOGIC TL1 VAD DRIVER M: Xing Wang ; }; }; - }; /* Audio Related end */ @@ -1129,6 +1128,34 @@ status = "disabled"; }; + vad:vad { + compatible = "amlogic, snd-vad"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_VAD>; + clock-names = "gate", "pll", "clk"; + + interrupts = ; + interrupt-names = "irq_wakeup", "irq_frame_sync"; + + /* + * Data src sel: + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + * 5: loopback_b; + * 6: tdmin_lb; + * 7: loopback_a; + */ + src = <4>; + + status = "disabled"; + }; }; /* end of audiobus */ &pinctrl_periphs { diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts new file mode 100644 index 000000000000..355d25ee4d92 --- /dev/null +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts @@ -0,0 +1,1776 @@ +/* + * arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * 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. + * + */ + +/dts-v1/; + +#include "mesontl1.dtsi" +#include "partition_mbox_normal_P_32.dtsi" +#include "mesontl1_t309-panel.dtsi" + +/ { + model = "Amlogic TL1 T962X2 T309"; + amlogic-dt-id = "tl1_t962x2_t309"; + compatible = "amlogic, tl1_t962x2_t309"; + + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; + serial2 = &uart_B; + serial3 = &uart_C; + serial4 = &uart_AO_B; + tsensor0 = &p_tsensor; + tsensor1 = &d_tsensor; + tsensor2 = &s_tsensor; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c_AO; + }; + + memory@00000000 { + device_type = "memory"; + linux,usable-memory = <0x100000 0x7ff00000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + /* global autoconfigured region for contiguous allocations */ + secmon_reserved: linux,secmon { + compatible = "shared-dma-pool"; + reusable; + size = <0x400000>; + alignment = <0x400000>; + alloc-ranges = <0x05000000 0x400000>; + }; + + codec_mm_cma:linux,codec_mm_cma { + compatible = "shared-dma-pool"; + reusable; + /* ion_codec_mm max can alloc size 80M*/ + size = <0x13400000>; + alignment = <0x400000>; + linux,contiguous-region; + alloc-ranges = <0x12000000 0x13400000>; + }; + + /* codec shared reserved */ + codec_mm_reserved:linux,codec_mm_reserved { + compatible = "amlogic, codec-mm-reserved"; + size = <0x0>; + alignment = <0x100000>; + //no-map; + }; + + logo_reserved:linux,meson-fb { + compatible = "shared-dma-pool"; + reusable; + size = <0x800000>; + alignment = <0x400000>; + alloc-ranges = <0x7f800000 0x800000>; + }; + + lcd_tcon_reserved:linux,lcd_tcon { + compatible = "shared-dma-pool"; + reusable; + size = <0xc00000>; + alignment = <0x400000>; + alloc-ranges = <0x71000000 0xc00000>; + }; + + ion_cma_reserved:linux,ion-dev { + compatible = "shared-dma-pool"; + reusable; + size = <0x8000000>; + alignment = <0x400000>; + }; + + /* vdin0 CMA pool */ + //vdin0_cma_reserved:linux,vdin0_cma { + // compatible = "shared-dma-pool"; + // reusable; + /* 3840x2160x4x4 ~=128 M */ + // size = <0xc400000>; + // alignment = <0x400000>; + //}; + + /* vdin1 CMA pool */ + vdin1_cma_reserved:linux,vdin1_cma { + compatible = "shared-dma-pool"; + reusable; + /* 1920x1080x2x4 =16 M */ + size = <0x1400000>; + alignment = <0x400000>; + }; + + /*demod_reserved:linux,demod { + * compatible = "amlogic, demod-mem"; + * size = <0x800000>; //8M //100m 0x6400000 + * alloc-ranges = <0x0 0x30000000>; + * //multi-use; + * //no-map; + *}; + */ + + demod_cma_reserved:linux,demod_cma { + compatible = "shared-dma-pool"; + reusable; + /* 8M */ + size = <0x0800000>; + alignment = <0x400000>; + }; + + /*vbi reserved mem*/ + vbi_reserved:linux,vbi { + compatible = "amlogic, vbi-mem"; + size = <0x100000>; + alloc-ranges = <0x0e000000 0x800000>; + }; + + /*di CMA pool */ + di_cma_reserved:linux,di_cma { + compatible = "shared-dma-pool"; + reusable; + /* buffer_size = 3621952(yuv422 8bit) + * | 4736064(yuv422 10bit) + * | 4074560(yuv422 10bit full pack mode) + * 10x3621952=34.6M(0x23) support 8bit + * 10x4736064=45.2M(0x2e) support 12bit + * 10x4074560=40M(0x28) support 10bit + */ + size = <0x02800000>; + alignment = <0x400000>; + }; + + /* for hdmi rx emp use */ + hdmirx_emp_cma_reserved:linux,emp_cma { + compatible = "shared-dma-pool"; + /*linux,phandle = <5>;*/ + reusable; + /* 4M for emp to ddr */ + /* 32M for tmds to ddr */ + size = <0x2000000>; + alignment = <0x400000>; + /* alloc-ranges = <0x400000 0x2000000>; */ + }; + + /* POST PROCESS MANAGER */ + ppmgr_reserved:linux,ppmgr { + compatible = "amlogic, ppmgr_memory"; + size = <0x0>; + }; + }; /* end of reserved-memory */ + + codec_mm { + compatible = "amlogic, codec, mm"; + status = "okay"; + memory-region = <&codec_mm_cma &codec_mm_reserved>; + }; + + ppmgr { + compatible = "amlogic, ppmgr"; + memory-region = <&ppmgr_reserved>; + status = "okay"; + }; + + deinterlace { + compatible = "amlogic, deinterlace"; + status = "okay"; + /* 0:use reserved; 1:use cma; 2:use cma as reserved */ + flag_cma = <1>; + //memory-region = <&di_reserved>; + memory-region = <&di_cma_reserved>; + interrupts = <0 46 1 + 0 40 1>; + interrupt-names = "pre_irq", "post_irq"; + clocks = <&clkc CLKID_VPU_CLKB_TMP_COMP>, + <&clkc CLKID_VPU_CLKB_COMP>; + clock-names = "vpu_clkb_tmp_composite", + "vpu_clkb_composite"; + clock-range = <334 667>; + /* buffer-size = <3621952>;(yuv422 8bit) */ + buffer-size = <4074560>;/*yuv422 fullpack*/ + /* reserve-iomap = "true"; */ + /* if enable nr10bit, set nr10bit-support to 1 */ + post-wr-support = <1>; + nr10bit-support = <1>; + nrds-enable = <1>; + pps-enable = <1>; + }; + + vout { + compatible = "amlogic, vout"; + status = "okay"; + fr_auto_policy = <0>; + }; + + /* Audio Related start */ + pdm_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, pdm_dummy_codec"; + status = "okay"; + }; + + dummy_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, aml_dummy_codec"; + status = "okay"; + }; + + tl1_codec:codec { + #sound-dai-cells = <0>; + compatible = "amlogic, tl1_acodec"; + status = "okay"; + reg = <0xff632000 0x1c>; + tdmout_index = <0>; + tdmin_index = <0>; + dat1_ch_sel = <1>; + }; + + aml_dtv_demod { + compatible = "amlogic, ddemod-tl1"; + dev_name = "aml_dtv_demod"; + status = "okay"; + + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + reg = <0xff650000 0x4000 /*dtv demod base*/ + 0xff63c000 0x2000 /*hiu reg base*/ + 0xff800000 0x1000 /*io_aobus_base*/ + 0xffd01000 0x1000 /*reset*/ + >; + + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + memory-region = <&demod_cma_reserved>;//<&demod_reserved>; + }; + + auge_sound { + compatible = "amlogic, tl1-sound-card"; + aml-audio-card,name = "AML-AUGESOUND"; + + avout_mute-gpios = <&gpio GPIODV_3 GPIO_ACTIVE_HIGH>; + + aml-audio-card,dai-link@0 { + format = "i2s"; + mclk-fs = <256>; + continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdma>; + frame-master = <&tdma>; + /* slave mode */ + /* + * bitclock-master = <&tdmacodec>; + * frame-master = <&tdmacodec>; + */ + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-i2s"; + tdmacpu: cpu { + sound-dai = <&tdma>; + dai-tdm-slot-tx-mask = + <1 1>; + dai-tdm-slot-rx-mask = + <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmacodec: codec { + //sound-dai = <&dummy_codec>; + sound-dai = <&ad82584f &tl1_codec>; + }; + }; + + aml-audio-card,dai-link@1 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmb>; + frame-master = <&tdmb>; + /* slave mode */ + //bitclock-master = <&tdmbcodec>; + //frame-master = <&tdmbcodec>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pcm"; + cpu { + sound-dai = <&tdmb>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + /* + * dai-tdm-slot-tx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-rx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-num = <8>; + */ + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmbcodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@2 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmc>; + frame-master = <&tdmc>; + /* slave mode */ + //bitclock-master = <&tdmccodec>; + //frame-master = <&tdmccodec>; + /* suffix-name, sync with android audio hal used for */ + //suffix-name = "alsaPORT-tdm"; + cpu { + sound-dai = <&tdmc>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmccodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@3 { + mclk-fs = <64>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pdm"; + cpu { + sound-dai = <&pdm>; + }; + codec { + sound-dai = <&pdm_codec>; + }; + }; + + aml-audio-card,dai-link@4 { + mclk-fs = <128>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-spdif"; + cpu { + sound-dai = <&spdifa>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@5 { + mclk-fs = <128>; + cpu { + sound-dai = <&spdifb>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@6 { + mclk-fs = <256>; + suffix-name = "alsaPORT-tv"; + cpu { + sound-dai = <&extn>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + }; + /* Audio Related end */ + + dvb { + compatible = "amlogic, dvb"; + status = "okay"; + fe0_mode = "internal"; + fe0_tuner = <&tuner>; + + /*"parallel","serial","disable"*/ + ts2 = "parallel"; + ts2_control = <0>; + ts2_invert = <0>; + interrupts = <0 23 1 + 0 5 1 + 0 53 1 + 0 19 1 + 0 25 1 + 0 17 1>; + interrupt-names = "demux0_irq", + "demux1_irq", + "demux2_irq", + "dvr0_irq", + "dvr1_irq", + "dvr2_irq"; + clocks = <&clkc CLKID_DEMUX + &clkc CLKID_ASYNC_FIFO + &clkc CLKID_AHB_ARB0 +/* &clkc CLKID_DOS_PARSER>;*/ + &clkc CLKID_U_PARSER>; + clock-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; + }; + + tvafe_avin_detect { + compatible = "amlogic, tl1_tvafe_avin_detect"; + status = "okay"; + device_mask = <1>;/*bit0:ch1;bit1:ch2*/ + interrupts = <0 12 1>, + <0 13 1>; + }; + + amlvecm { + compatible = "amlogic, vecm"; + dev_name = "aml_vecm"; + status = "okay"; + gamma_en = <1>;/*1:enabel ;0:disable*/ + wb_en = <1>;/*1:enabel ;0:disable*/ + cm_en = <1>;/*1:enabel ;0:disable*/ + wb_sel = <1>;/*1:mtx ;0:gainoff*/ + vlock_en = <1>;/*1:enable;0:disable*/ + vlock_mode = <0x4>; + /* vlock work mode: + *bit0:auto ENC + *bit1:auto PLL + *bit2:manual PLL + *bit3:manual ENC + *bit4:manual soft ENC + *bit5:manual MIX PLL ENC + */ + vlock_pll_m_limit = <1>; + vlock_line_limit = <3>; + }; + + vdin@0 { + compatible = "amlogic, vdin"; + /*memory-region = <&vdin0_cma_reserved>;*/ + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0x101>; + /*MByte, if 10bit disable: 64M(YUV422), + *if 10bit enable: 64*1.5 = 96M(YUV422) + *if support 4K2K-YUV444-10bit-WR:3840*2160*4*4 ~= 128M + *if support 4K2K-YUV422-10bit-wr:3840*2160*3*4 ~= 96M + *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M + *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M + */ + cma_size = <190>; + interrupts = <0 83 1>; + rdma-irq = <2>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <0>; + /*vdin write mem color depth support: + * bit0:support 8bit + * bit1:support 9bit + * bit2:support 10bit + * bit3:support 12bit + * bit4:support yuv422 10bit full pack mode (from txl new add) + * bit8:use 8bit at 4k_50/60hz_10bit + * bit9:use 10bit at 4k_50/60hz_10bit + */ + tv_bit_mode = <0x215>; + /* afbce_bit_mode: (amlogic frame buff compression encoder) + * bit 0~3: + * 0 -- normal mode, not use afbce + * 1 -- use afbce non-mmu mode + * 2 -- use afbce mmu mode + * bit 4: + * 0 -- afbce compression-lossy disable + * 1 -- afbce compression-lossy enable + */ + afbce_bit_mode = <0>; + }; + + vdin@1 { + compatible = "amlogic, vdin"; + memory-region = <&vdin1_cma_reserved>; + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0>; + interrupts = <0 85 1>; + rdma-irq = <4>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <1>; + /*vdin write mem color depth support: + *bit0:support 8bit + *bit1:support 9bit + *bit2:support 10bit + *bit3:support 12bit + */ + tv_bit_mode = <0x15>; + }; + + tvafe { + compatible = "amlogic, tvafe-tl1"; + /*memory-region = <&tvafe_cma_reserved>;*/ + status = "okay"; + flag_cma = <1>;/*1:share with codec_mm;0:cma alone*/ + cma_size = <5>;/*MByte*/ + reg = <0xff654000 0x2000>;/*tvafe reg base*/ + reserve-iomap = "true"; + tvafe_id = <0>; + //pinctrl-names = "default"; + /*!!particular sequence, no more and no less!!!*/ + tvafe_pin_mux = < + 3 /* TVAFE_CVBS_IN2, CVBS_IN0 = 0 */ + 1 /* TVAFE_CVBS_IN0, CVBS_IN1 */ + 2 /* TVAFE_CVBS_IN1, CVBS_IN2 */ + 4 /* TVAFE_CVBS_IN3, CVBS_IN3 */ + >; + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + }; + + vbi { + compatible = "amlogic, vbi"; + memory-region = <&vbi_reserved>; + status = "okay"; + interrupts = <0 83 1>; + reserve-iomap = "true"; + }; + + cvbsout { + compatible = "amlogic, cvbsout-tl1"; + status = "disabled"; + clocks = <&clkc CLKID_VCLK2_ENCI + &clkc CLKID_VCLK2_VENCI0 + &clkc CLKID_VCLK2_VENCI1 + &clkc CLKID_DAC_CLK>; + clock-names = "venci_top_gate", + "venci_0_gate", + "venci_1_gate", + "vdac_clk_gate"; + /* clk path */ + /* 0:vid_pll vid2_clk */ + /* 1:gp0_pll vid2_clk */ + /* 2:vid_pll vid1_clk */ + /* 3:gp0_pll vid1_clk */ + clk_path = <0>; + + /* performance: reg_address, reg_value */ + /* tl1 */ + performance = <0x1bf0 0x9 + 0x1b56 0x333 + 0x1b12 0x8080 + 0x1b05 0xfd + 0x1c59 0xf850 + 0xffff 0x0>; /* ending flag */ + performance_sarft = <0x1bf0 0x9 + 0x1b56 0x333 + 0x1b12 0x0 + 0x1b05 0x9 + 0x1c59 0xfc48 + 0xffff 0x0>; /* ending flag */ + performance_revB_telecom = <0x1bf0 0x9 + 0x1b56 0x546 + 0x1b12 0x8080 + 0x1b05 0x9 + 0x1c59 0xf850 + 0xffff 0x0>; /* ending flag */ + }; + + /* for external keypad */ + adc_keypad { + compatible = "amlogic, adc_keypad"; + status = "okay"; + key_name = "power","up","down","enter","left","right","home"; + key_num = <7>; + io-channels = <&saradc SARADC_CH2>,<&saradc SARADC_CH3>; + io-channel-names = "key-chan-2", "key-chan-3"; + key_chan = ; + key_code = <116 103 108 28 105 106 102>; + key_val = <0 143 266 389 512 143 266>; //val=voltage/1800mV*1023 + key_tolerance = <40 40 40 40 40 40 40>; +}; + + unifykey { + compatible = "amlogic, unifykey"; + status = "okay"; + + unifykey-num = <21>; + unifykey-index-0 = <&keysn_0>; + unifykey-index-1 = <&keysn_1>; + unifykey-index-2 = <&keysn_2>; + unifykey-index-3 = <&keysn_3>; + unifykey-index-4 = <&keysn_4>; + unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; + unifykey-index-7 = <&keysn_7>; + unifykey-index-8 = <&keysn_8>; + unifykey-index-9 = <&keysn_9>; + unifykey-index-10= <&keysn_10>; + unifykey-index-11 = <&keysn_11>; + unifykey-index-12 = <&keysn_12>; + unifykey-index-13 = <&keysn_13>; + unifykey-index-14 = <&keysn_14>; + unifykey-index-15 = <&keysn_15>; + unifykey-index-16 = <&keysn_16>; + unifykey-index-17 = <&keysn_17>; + unifykey-index-18 = <&keysn_18>; + unifykey-index-19 = <&keysn_19>; + unifykey-index-20 = <&keysn_20>; + + keysn_0: key_0{ + key-name = "usid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_1:key_1{ + key-name = "mac"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_2:key_2{ + key-name = "hdcp"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_3:key_3{ + key-name = "secure_boot_set"; + key-device = "efuse"; + key-permit = "write"; + }; + keysn_4:key_4{ + key-name = "mac_bt"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_5:key_5{ + key-name = "mac_wifi"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_6:key_6{ + key-name = "hdcp2_tx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_7:key_7{ + key-name = "hdcp2_rx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_8:key_8{ + key-name = "widevinekeybox"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_9:key_9{ + key-name = "deviceid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_10:key_10{ + key-name = "hdcp22_fw_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_11:key_11{ + key-name = "hdcp22_rx_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_12:key_12{ + key-name = "hdcp22_rx_fw"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_13:key_13{ + key-name = "hdcp14_rx"; + key-device = "normal"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_14:key_14{ + key-name = "prpubkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_15:key_15{ + key-name = "prprivkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_16:key_16{ + key-name = "lcd"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_17:key_17{ + key-name = "lcd_extern"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_18:key_18{ + key-name = "backlight"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_19:key_19{ + key-name = "lcd_tcon"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_20:key_20{ + key-name = "attestationkeybox";// attestation key + key-device = "secure"; + key-permit = "read","write","del"; + }; + }; /* End unifykey */ + + hdmirx { + compatible = "amlogic, hdmirx_tl1"; + #address-cells=<1>; + #size-cells=<1>; + memory-region = <&hdmirx_emp_cma_reserved>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmirx_a_mux &hdmirx_b_mux + &hdmirx_c_mux>; + repeat = <0>; + interrupts = <0 41 1>; + clocks = <&clkc CLKID_HDMIRX_MODET_COMP>, + <&clkc CLKID_HDMIRX_CFG_COMP>, + <&clkc CLKID_HDMIRX_ACR_COMP>, + <&clkc CLKID_HDMIRX_METER_COMP>, + <&clkc CLKID_HDMIRX_AXI_COMP>, + <&xtal>, + <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV7>, + <&clkc CLKID_HDCP22_SKP_COMP>, + <&clkc CLKID_HDCP22_ESM_COMP>; + // <&clkc CLK_AUD_PLL2FS>, + // <&clkc CLK_AUD_PLL4FS>, + // <&clkc CLK_AUD_OUT>; + clock-names = "hdmirx_modet_clk", + "hdmirx_cfg_clk", + "hdmirx_acr_ref_clk", + "cts_hdmirx_meter_clk", + "cts_hdmi_axi_clk", + "xtal", + "fclk_div5", + "fclk_div7", + "hdcp_rx22_skp", + "hdcp_rx22_esm"; + // "hdmirx_aud_pll2fs", + // "hdmirx_aud_pll4f", + // "clk_aud_out"; + hdmirx_id = <0>; + en_4k_2_2k = <0>; + hpd_low_cec_off = <1>; + /* bit4: enable feature, bit3~0: port number */ + disable_port = <0x0>; + /* MAP_ADDR_MODULE_CBUS */ + /* MAP_ADDR_MODULE_HIU */ + /* MAP_ADDR_MODULE_HDMIRX_CAPB3 */ + /* MAP_ADDR_MODULE_SEC_AHB */ + /* MAP_ADDR_MODULE_SEC_AHB2 */ + /* MAP_ADDR_MODULE_APB4 */ + /* MAP_ADDR_MODULE_TOP */ + reg = < 0x0 0x0 + 0xff63C000 0x2000 + 0xffe0d000 0x2000 + 0x0 0x0 + 0x0 0x0 + 0x0 0x0 + 0xff610000 0xa000>; + }; + + aocec: aocec { + compatible = "amlogic, aocec-tl1"; + /*device_name = "aocec";*/ + status = "okay"; + vendor_name = "Amlogic"; /* Max Chars: 8 */ + /* Refer to the following URL at: + * http://standards.ieee.org/develop/regauth/oui/oui.txt + */ + vendor_id = <0x000000>; + product_desc = "TL1"; /* Max Chars: 16 */ + cec_osd_string = "AML_TV"; /* Max Chars: 14 */ + port_num = <3>; + ee_cec; + arc_port_mask = <0x2>; + interrupts = <0 205 1 + 0 199 1>; + interrupt-names = "hdmi_aocecb","hdmi_aocec"; + pinctrl-names = "default","hdmitx_aocecb","cec_pin_sleep"; + pinctrl-0=<&aoceca_mux>; + pinctrl-1=<&aocecb_mux>; + pinctrl-2=<&aoceca_mux>; + reg = <0xFF80023c 0x4 + 0xFF800000 0x400>; + reg-names = "ao_exit","ao"; + }; + + p_tsensor: p_tsensor@ff634800 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634800 0x50>, + <0xff800268 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 35 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + d_tsensor: d_tsensor@ff634c00 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634c00 0x50>, + <0xff800230 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 36 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + s_tsensor: s_tsensor@ff635000 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff635000 0x50>, + <0xff80026c 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 38 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + meson_cooldev: meson-cooldev@0 { + status = "okay"; + compatible = "amlogic, meson-cooldev"; + cooling_devices { + cpufreq_cool_cluster0 { + min_state = <1000000>; + dyn_coeff = <140>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpufreq_cool0"; + device_type = "cpufreq"; + }; + cpucore_cool_cluster0 { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpucore_cool0"; + device_type = "cpucore"; + }; + gpufreq_cool { + min_state = <400>; + dyn_coeff = <358>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpufreq_cool0"; + device_type = "gpufreq"; + }; + gpucore_cool { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpucore_cool0"; + device_type = "gpucore"; + }; + }; + cpufreq_cool0:cpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + cpucore_cool0:cpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpufreq_cool0:gpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpucore_cool0:gpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + };/*meson cooling devices end*/ + + thermal-zones { + pll_thermal: pll_thermal { + polling-delay = <1000>; + polling-delay-passive = <100>; + sustainable-power = <1680>; + thermal-sensors = <&p_tsensor 0>; + trips { + pswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + pcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + phot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + pcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + cooling-maps { + cpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&cpufreq_cool0 0 11>; + contribution = <1024>; + }; + cpucore_cooling_map { + trip = <&pcontrol>; + cooling-device = <&cpucore_cool0 0 4>; + contribution = <1024>; + }; + gpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&gpufreq_cool0 0 4>; + contribution = <1024>; + }; + }; + }; + ddr_thermal: ddr_thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + sustainable-power = <1680>; + thermal-sensors = <&d_tsensor 1>; + trips { + dswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + dcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + dhot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + dcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + sar_thermal: sar_thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + sustainable-power = <1680>; + thermal-sensors = <&s_tsensor 2>; + trips { + sswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + scontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + shot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + scritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; /*thermal zone end*/ + + /*DCDC for MP8756GD*/ + cpu_opp_table0: cpu_opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + opp01 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + opp02 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + opp03 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <761000>; + }; + opp04 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <791000>; + }; + opp05 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <801000>; + }; + opp06 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <831000>; + }; + opp07 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <861000>; + }; + opp08 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <891000>; + }; + opp09 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <921000>; + }; + opp10 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <981000>; + }; + opp11 { + opp-hz = /bits/ 64 <1908000000>; + opp-microvolt = <1011000>; + }; + }; + + cpufreq-meson { + compatible = "amlogic, cpufreq-meson"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_ao_d_pins3>; + status = "okay"; + }; + + tuner: tuner { + status = "okay"; + tuner_name = "mxl661_tuner"; + tuner_i2c_adap = <&i2c0>; + tuner_i2c_addr = <0x60>; + tuner_xtal = <1>; /* 0: 16MHz, 1: 24MHz */ + tuner_xtal_mode = <3>; + /* NO_SHARE_XTAL(0) + * SLAVE_XTAL_SHARE(3) + */ + tuner_xtal_cap = <25>; /* when tuner_xtal_mode = 3, set 25 */ + }; + + atv-demod { + compatible = "amlogic, atv-demod"; + status = "okay"; + tuner = <&tuner>; + btsc_sap_mode = <1>; + /* pinctrl-names="atvdemod_agc_pins"; */ + /* pinctrl-0=<&atvdemod_agc_pins>; */ + reg = <0xff656000 0x2000 /* demod reg */ + 0xff63c000 0x2000 /* hiu reg */ + 0xff634000 0x2000 /* periphs reg */ + 0xff64a000 0x2000>; /* audio reg */ + reg_23cf = <0x88188832>; + /*default:0x88188832;r840 on haier:0x48188832*/ + }; + + bt-dev{ + compatible = "amlogic, bt-dev"; + status = "okay"; + gpio_reset = <&gpio GPIOC_13 GPIO_ACTIVE_HIGH>; + }; + + wifi{ + compatible = "amlogic, aml_wifi"; + status = "okay"; + interrupt_pin = <&gpio GPIOC_12 GPIO_ACTIVE_HIGH>; + irq_trigger_type = "GPIO_IRQ_LOW"; + dhd_static_buf; //dhd_static_buf support + power_on_pin = <&gpio GPIOC_11 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_b_pins1>; + pwm_config = <&wifi_pwm_conf>; + }; + + wifi_pwm_conf:wifi_pwm_conf{ + pwm_channel1_conf { + pwms = <&pwm_ab MESON_PWM_1 30541 0>; + duty-cycle = <15270>; + times = <8>; + }; + pwm_channel2_conf { + pwms = <&pwm_ab MESON_PWM_3 30500 0>; + duty-cycle = <15250>; + times = <12>; + }; + }; + + sd_emmc_b: sdio@ffe05000 { + status = "okay"; + compatible = "amlogic, meson-mmc-tl1"; + reg = <0xffe05000 0x800>; + interrupts = <0 190 4>; + + pinctrl-names = "sdio_all_pins", + "sdio_clk_cmd_pins"; + pinctrl-0 = <&sdio_all_pins>; + pinctrl-1 = <&sdio_clk_cmd_pins>; + + clocks = <&clkc CLKID_SD_EMMC_B>, + <&clkc CLKID_SD_EMMC_B_P0_COMP>, + <&clkc CLKID_FCLK_DIV2>, + <&clkc CLKID_FCLK_DIV5>, + <&xtal>; + clock-names = "core", "clkin0", "clkin1", "clkin2", "xtal"; + + bus-width = <4>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <100000000>; + disable-wp; + sdio { + pinname = "sdio"; + ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */ + caps = "MMC_CAP_4_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", /**ptm debug */ + "MMC_CAP_UHS_SDR12", + "MMC_CAP_UHS_SDR25", + "MMC_CAP_UHS_SDR50", + "MMC_CAP_UHS_SDR104", + "MMC_PM_KEEP_POWER", + "MMC_CAP_SDIO_IRQ"; + f_min = <400000>; + f_max = <200000000>; + max_req_size = <0x20000>; /**128KB*/ + card_type = <3>; + /* 3:sdio device(ie:sdio-wifi), + * 4:SD combo (IO+mem) card + */ + }; + }; +}; /* end of / */ + +&i2c0 { + status = "okay"; + clock-frequency = <300000>; + pinctrl-names="default"; + pinctrl-0=<&i2c0_dv_pins>; +}; + +&audiobus { + tdma:tdm@0 { + compatible = "amlogic, tl1-snd-tdma"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <0>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_A + &clkc CLKID_MPLL0 + &clkc CLKID_MPLL0>; + clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdma_mclk &tdmout_a>; + + /* + * 0: tdmout_a; + * 1: tdmout_b; + * 2: tdmout_c; + * 3: spdifout; + * 4: spdifout_b; + */ + samesource_sel = <3>; + + /* In for ACODEC_ADC */ + acodec_adc = <1>; + + status = "okay"; + }; + + tdmb:tdm@1 { + compatible = "amlogic, tl1-snd-tdmb"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <1>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_B + &clkc CLKID_MPLL1>; + clock-names = "mclk", "clk_srcpll"; + + status = "okay"; + }; + + tdmc:tdm@2 { + compatible = "amlogic, tl1-snd-tdmc"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <2>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdmout_c &tdmin_c>; + + status = "okay"; + }; + + spdifa:spdif@0 { + compatible = "amlogic, tl1-snd-spdif-a"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 + &clkc CLKID_FCLK_DIV4 + &clkaudio CLKID_AUDIO_GATE_SPDIFIN + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A + &clkaudio CLKID_AUDIO_SPDIFIN + &clkaudio CLKID_AUDIO_SPDIFOUT_A>; + clock-names = "sysclk", "fixed_clk", "gate_spdifin", + "gate_spdifout", "clk_spdifin", "clk_spdifout"; + + interrupts = + ; + interrupt-names = "irq_spdifin"; + + pinctrl-names = "spdif_pins"; + pinctrl-0 = <&spdifout_a>; + + /* + * whether do asrc for pcm and resample a or b + * if raw data, asrc is disabled automatically + * 0: "Disable", + * 1: "Enable:32K", + * 2: "Enable:44K", + * 3: "Enable:48K", + * 4: "Enable:88K", + * 5: "Enable:96K", + * 6: "Enable:176K", + * 7: "Enable:192K", + */ + asrc_id = <0>; + auto_asrc = <3>; + + status = "okay"; + }; + + spdifb:spdif@1 { + compatible = "amlogic, tl1-snd-spdif-b"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/ + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B + &clkaudio CLKID_AUDIO_SPDIFOUT_B>; + clock-names = "sysclk", + "gate_spdifout", "clk_spdifout"; + + status = "okay"; + }; + + pdm:pdm { + compatible = "amlogic, tl1-snd-pdm"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_PDM + &clkc CLKID_FCLK_DIV3 + &clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_PDMIN0 + &clkaudio CLKID_AUDIO_PDMIN1>; + clock-names = "gate", + "sysclk_srcpll", + "dclk_srcpll", + "pdm_dclk", + "pdm_sysclk"; + + pinctrl-names = "pdm_pins"; + pinctrl-0 = <&pdmin>; + + /* mode 0~4, defalut:1 */ + filter_mode = <1>; + + status = "okay"; + }; + + extn:extn { + compatible = "amlogic, snd-extn"; + #sound-dai-cells = <0>; + + interrupts = + ; + interrupt-names = "irq_frhdmirx"; + + status = "okay"; + }; + + aed:effect { + compatible = "amlogic, snd-effect-v2"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_EQDRC>; + clock-names = "gate", "srcpll", "eqdrc"; + + eq_enable = <1>; + multiband_drc_enable = <0>; + fullband_drc_enable = <0>; + /* + * 0:tdmout_a + * 1:tdmout_b + * 2:tdmout_c + * 3:spdifout + * 4:spdifout_b + */ + eqdrc_module = <0>; + /* max 0xf, each bit for one lane, usually one lane */ + lane_mask = <0x1>; + /* max 0xff, each bit for one channel */ + channel_mask = <0x3>; + + status = "okay"; + }; + + asrca: resample@0 { + compatible = "amlogic, tl1-resample-a"; + clocks = <&clkc CLKID_MPLL0 + &clkaudio CLKID_AUDIO_MCLK_A + &clkaudio CLKID_AUDIO_RESAMPLE_A>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "okay"; + }; + + asrcb: resample@1 { + compatible = "amlogic, tl1-resample-b"; + + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_B>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + +}; /* end of audiobus */ + +&pinctrl_periphs { + /* audio pin mux */ + + tdma_mclk: tdma_mclk { + mux { /* GPIOZ_0 */ + groups = "mclk0_z"; + function = "mclk0"; + }; + }; + + tdmout_a: tdmout_a { + mux { /* GPIOZ_1, GPIOZ_2, GPIOZ_3 */ + groups = "tdma_sclk_z", + "tdma_fs_z", + "tdma_dout0_z"; + function = "tdma_out"; + }; + }; + + tdmin_a: tdmin_a { + mux { /* GPIOZ_9 */ + groups = "tdma_din2_z"; + function = "tdma_in"; + }; + }; + + tdmout_c: tdmout_c { + mux { /* GPIODV_7, GPIODV_8, GPIODV_9 */ + groups = "tdmc_sclk", + "tdmc_fs", + "tdmc_dout0"; + function = "tdmc_out"; + }; + }; + + tdmin_c: tdmin_c { + mux { /* GPIODV_10 */ + groups = "tdmc_din1"; + function = "tdmc_in"; + }; + }; + + spdifin_a: spdifin_a { + mux { /* GPIODV_5 */ + groups = "spdif_in"; + function = "spdif_in"; + }; + }; + + spdifout_a: spdifout_a { + mux { /* GPIODV_4 */ + groups = "spdif_out_dv4"; + function = "spdif_out"; + }; + }; + + pdmin: pdmin { + mux { /* GPIOZ_7, GPIOZ_8, pdm_din2_z4 */ + groups = "pdm_dclk_z", + "pdm_din0_z", + "pdm_din2_z4"; + function = "pdm"; + }; + }; + + /*backlight*/ + bl_pwm_vs_on_pins:bl_pwm_vs_on_pin { + mux { + groups = "pwm_vs_z5"; + function = "pwm_vs"; + }; + }; + bl_pwm_off_pins:bl_pwm_off_pin { + mux { + groups = "GPIOZ_5"; + function = "gpio_periphs"; + output-low; + }; + }; + bl_pwm_combo_0_vs_on_pins:bl_pwm_combo_0_vs_on_pin { + mux { + groups = "pwm_vs_z5"; + function = "pwm_vs"; + }; + }; + bl_pwm_combo_1_vs_on_pins:bl_pwm_combo_1_vs_on_pin { + mux { + groups = "pwm_vs_z6"; + function = "pwm_vs"; + }; + }; + bl_pwm_combo_off_pins:bl_pwm_combo_off_pin { + mux { + groups = "GPIOZ_5", + "GPIOZ_6"; + function = "gpio_periphs"; + output-low; + }; + }; + +}; /* end of pinctrl_periphs */ + +&audio_data{ + status = "okay"; +}; + +&i2c2 { + status = "okay"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_z_pins>; + clock-frequency = <400000>; + + ad82584f: ad82584f@62 { + compatible = "ESMT, ad82584f"; + #sound-dai-cells = <0>; + reg = <0x31>; + status = "okay"; + reset_pin = <&gpio_ao GPIOAO_6 0>; + }; + +}; + +&sd_emmc_c { + status = "okay"; + emmc { + caps = "MMC_CAP_8_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", + "MMC_CAP_1_8V_DDR", + "MMC_CAP_HW_RESET", + "MMC_CAP_ERASE", + "MMC_CAP_CMD23"; + caps2 = "MMC_CAP2_HS200"; + /* "MMC_CAP2_HS400";*/ + f_min = <400000>; + f_max = <200000000>; + }; +}; + + + +&spifc { + status = "disabled"; + spi-nor@0 { + cs_gpios = <&gpio BOOT_13 GPIO_ACTIVE_HIGH>; + }; +}; + +&slc_nand { + status = "disabled"; + plat-names = "bootloader", "nandnormal"; + plat-num = <2>; + plat-part-0 = <&bootloader>; + plat-part-1 = <&nandnormal>; + bootloader: bootloader{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <1>; + part_num = <0>; + rb_detect = <1>; + }; + nandnormal: nandnormal{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + plane_mode = "twoplane"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <2>; + part_num = <3>; + partition = <&nand_partitions>; + rb_detect = <1>; + }; + nand_partitions:nand_partition{ + /* + * if bl_mode is 1, tpl size was generate by + * fip_copies * fip_size which + * will not skip bad when calculating + * the partition size; + * + * if bl_mode is 0, + * tpl partition must be comment out. + */ + tpl{ + offset=<0x0 0x0>; + size=<0x0 0x0>; + }; + logo{ + offset=<0x0 0x0>; + size=<0x0 0x200000>; + }; + recovery{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + boot{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + system{ + offset=<0x0 0x0>; + size=<0x0 0x4000000>; + }; + data{ + offset=<0xffffffff 0xffffffff>; + size=<0x0 0x0>; + }; + }; +}; + +ðmac { + status = "okay"; + pinctrl-names = "internal_eth_pins"; + pinctrl-0 = <&internal_eth_pins>; + mc_val = <0x4be04>; + + internal_phy=<1>; +}; + +&uart_A { + status = "okay"; +}; + +&dwc3 { + status = "okay"; +}; + +&usb2_phy_v2 { + status = "okay"; + portnum = <3>; +}; + +&usb3_phy_v2 { + status = "okay"; + portnum = <0>; + otg = <0>; +}; + +&dwc2_a { + status = "okay"; + /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ + controller-type = <1>; +}; + +&spicc0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spicc0_pins_h>; + cs-gpios = <&gpio GPIOH_20 0>; +}; + +&meson_fb { + status = "okay"; + display_size_default = <1920 1080 1920 2160 32>; + mem_size = <0x00800000 0x1980000 0x100000 0x800000>; + logo_addr = "0x7f800000"; + mem_alloc = <0>; + pxp_mode = <0>; /** 0:normal mode 1:pxp mode */ +}; + +&pwm_AO_cd { + status = "okay"; +}; + +&saradc { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <300000>; + pinctrl-names="default"; + pinctrl-0=<&i2c1_h_pins>; + + lcd_extern_i2c0: lcd_extern_i2c@0 { + compatible = "lcd_ext, i2c"; + dev_name = "i2c_T5800Q"; + reg = <0x1c>; + status = "okay"; + }; + + lcd_extern_i2c1: lcd_extern_i2c@1 { + compatible = "lcd_ext, i2c"; + dev_name = "i2c_ANX6862"; + reg = <0x20>; + status = "okay"; + }; + + lcd_extern_i2c2: lcd_extern_i2c@2 { + compatible = "lcd_ext, i2c"; + dev_name = "i2c_ANX7911"; + reg = <0x74>; + status = "okay"; + }; +}; + +&pwm_ab { + status = "okay"; +}; + +&pwm_cd { + status = "okay"; +}; + +&efuse { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts index 4f1bee41f6ab..6ddf8823143f 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts @@ -167,6 +167,7 @@ reg = <0xff632000 0x1c>; tdmout_index = <0>; tdmin_index = <0>; + dat1_ch_sel = <1>; }; auge_sound { @@ -178,7 +179,7 @@ aml-audio-card,dai-link@0 { format = "i2s"; mclk-fs = <256>; - //continuous-clock; + continuous-clock; //bitclock-inversion; //frame-inversion; /* master mode */ @@ -937,7 +938,7 @@ clocks = <&clkaudio CLKID_AUDIO_MCLK_A &clkc CLKID_MPLL0 - &clkc CLKID_MPLL1>; + &clkc CLKID_MPLL0>; clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; pinctrl-names = "tdm_pins"; @@ -1024,7 +1025,7 @@ * 7: "Enable:192K", */ asrc_id = <0>; - auto_asrc = <0>; + auto_asrc = <3>; status = "okay"; }; @@ -1107,8 +1108,8 @@ asrca: resample@0 { compatible = "amlogic, tl1-resample-a"; - clocks = <&clkc CLKID_MPLL3 - &clkaudio CLKID_AUDIO_MCLK_F + clocks = <&clkc CLKID_MPLL0 + &clkaudio CLKID_AUDIO_MCLK_A &clkaudio CLKID_AUDIO_RESAMPLE_A>; clock-names = "resample_pll", "resample_src", "resample_clk"; /*same with toddr_src @@ -1123,7 +1124,7 @@ */ resample_module = <3>; - status = "disabled"; + status = "okay"; }; asrcb: resample@1 { @@ -1149,6 +1150,41 @@ status = "disabled"; }; + vad:vad { + compatible = "amlogic, snd-vad"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_VAD>; + clock-names = "gate", "pll", "clk"; + + interrupts = ; + interrupt-names = "irq_wakeup", "irq_frame_sync"; + + /* + * Data src sel: + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + * 5: loopback_b; + * 6: tdmin_lb; + * 7: loopback_a; + */ + src = <4>; + + /* + * deal with hot word in user space or kernel space + * 0: in user space + * 1: in kernel space + */ + level = <0>; + + status = "disabled"; + }; }; /* end of audiobus */ &pinctrl_periphs { @@ -1229,6 +1265,14 @@ pinctrl-0=<&i2c2_z_pins>; clock-frequency = <400000>; + tas5805: tas5805@36 { + compatible = "ti,tas5805"; + #sound-dai-cells = <0>; + codec_name = "tas5805"; + reg = <0x2d>; + status = "disable"; + }; + ad82584f: ad82584f@62 { compatible = "ESMT, ad82584f"; #sound-dai-cells = <0>; diff --git a/arch/arm/configs/meson64_a32_defconfig b/arch/arm/configs/meson64_a32_defconfig index db75074efec6..71f5e9fab311 100644 --- a/arch/arm/configs/meson64_a32_defconfig +++ b/arch/arm/configs/meson64_a32_defconfig @@ -482,6 +482,7 @@ CONFIG_AMLOGIC_SND_CODEC_AMLT9015S=y CONFIG_AMLOGIC_SND_CODEC_TXLX_ACODEC=y CONFIG_AMLOGIC_SND_CODEC_TL1_ACODEC=y CONFIG_AMLOGIC_SND_SOC_TAS5707=y +CONFIG_AMLOGIC_SND_SOC_TAS5805=y CONFIG_AMLOGIC_SND_SOC_TLV320ADC3101=y CONFIG_AMLOGIC_SND_SOC_PCM186X=y CONFIG_AMLOGIC_SND_SOC_SSM3525=y diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts index 261293d955d2..f805271bbd23 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts @@ -854,6 +854,7 @@ unifykey-index-3 = <&keysn_3>; unifykey-index-4 = <&keysn_4>; unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; keysn_0: key_0{ key-name = "usid"; @@ -887,6 +888,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_6:key_6{ + key-name = "gva_certs"; + key-device = "normal"; + key-permit = "read","write","del"; + }; };//End unifykey audio_data: audio_data { compatible = "amlogic, audio_data"; @@ -1111,7 +1117,7 @@ #sound-dai-cells = <0>; clocks = <&clkaudio CLKID_AUDIO_PDM &clkc CLKID_FCLK_DIV3 - &clkc CLKID_MPLL3 + &clkc CLKID_MPLL2 &clkaudio CLKID_AUDIO_PDMIN0 &clkaudio CLKID_AUDIO_PDMIN1>; clock-names = "gate", diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts b/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts index 6c223f739b93..1b2300f0f4ef 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts @@ -668,13 +668,14 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <6>; + unifykey-num = <7>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; unifykey-index-3 = <&keysn_3>; unifykey-index-4 = <&keysn_4>; unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; keysn_0: key_0{ key-name = "usid"; @@ -708,6 +709,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_6:key_6{ + key-name = "gva_certs"; + key-device = "normal"; + key-permit = "read","write","del"; + }; };//End unifykey audio_data: audio_data { compatible = "amlogic, audio_data"; @@ -934,7 +940,7 @@ #sound-dai-cells = <0>; clocks = <&clkaudio CLKID_AUDIO_PDM &clkc CLKID_FCLK_DIV3 - &clkc CLKID_MPLL3 + &clkc CLKID_MPLL2 &clkaudio CLKID_AUDIO_PDMIN0 &clkaudio CLKID_AUDIO_PDMIN1>; clock-names = "gate", @@ -992,6 +998,26 @@ status = "okay"; }; + + audioresample: resample { + compatible = "amlogic, axg-resample"; + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_CTRL>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, + * TDMIN_B, + * TDMIN_C, + * SPDIFIN, + * PDMIN, + * NONE, + * TDMIN_LB, + * LOOPBACK, + */ + resample_module = <3>; + status = "okay"; + }; }; /* end of audiobus */ &pinctrl_periphs { diff --git a/include/linux/amlogic/major.h b/include/linux/amlogic/major.h index 4d2f9c2becad..1ce50430bb88 100644 --- a/include/linux/amlogic/major.h +++ b/include/linux/amlogic/major.h @@ -29,6 +29,7 @@ #define AMAUDIO2_MAJOR (13+(AML_BASE)) #define VFM_MAJOR (14+(AML_BASE)) #define IONVIDEO_MAJOR (15+(AML_BASE)) +#define VAD_MAJOR (16+(AML_BASE)) /* *#define UIO_MAJOR 4+(AML_BASE) *#define USB_DEV_EP_MAJOR 5+(AML_BASE) diff --git a/sound/soc/amlogic/auge/Makefile b/sound/soc/amlogic/auge/Makefile index f7fbe5ece59d..4cf47bec8853 100644 --- a/sound/soc/amlogic/auge/Makefile +++ b/sound/soc/amlogic/auge/Makefile @@ -29,4 +29,7 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE) += audio_controller.o \ pwrdet_hw.o \ sharebuffer.o \ extn.o \ - frhdmirx_hw.o + frhdmirx_hw.o \ + vad.o \ + vad_hw.o \ + vad_dev.o diff --git a/sound/soc/amlogic/auge/audio_utils.c b/sound/soc/amlogic/auge/audio_utils.c index cae3be9b38ff..32dca83e41c3 100644 --- a/sound/soc/amlogic/auge/audio_utils.c +++ b/sound/soc/amlogic/auge/audio_utils.c @@ -25,6 +25,7 @@ #include "ddr_mngr.h" #include "resample.h" #include "effects_v2.h" +#include "vad.h" #include #include @@ -951,6 +952,10 @@ int snd_card_add_kcontrols(struct snd_soc_card *card) return ret; } + ret = card_add_vad_kcontrols(card); + if (ret < 0) + pr_warn_once("Failed to add VAD controls\n"); + return snd_soc_add_card_controls(card, snd_auge_controls, ARRAY_SIZE(snd_auge_controls)); diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index d350436f7192..4d70dec390cd 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -14,6 +14,7 @@ * more details. * */ +#define DEBUG #undef pr_fmt #define pr_fmt(fmt) "audio_ddr_mngr: " fmt @@ -23,6 +24,9 @@ #include #include +#include +#include + #include "regs.h" #include "ddr_mngr.h" #include "audio_utils.h" @@ -33,131 +37,11 @@ #include "effects_hw_v2.h" #include "effects_v2.h" #include "pwrdet_hw.h" +#include "vad.h" #define DRV_NAME "audio-ddr-manager" static DEFINE_MUTEX(ddr_mutex); -#if 0 -struct ddr_desc { - /* start address of DDR */ - unsigned int start; - /* finish address of DDR */ - unsigned int finish; - /* interrupt address or counts of DDR blocks */ - unsigned int intrpt; - /* fifo total counts */ - unsigned int fifo_depth; - /* fifo start threshold */ - unsigned int fifo_thr; - enum ddr_types data_type; - unsigned int edian; - unsigned int pp_mode; - //unsigned int reg_base; - struct clk *ddr; - struct clk *ddr_arb; -}; -#endif - -struct ddr_chipinfo { - /* INT and Start address is same or separated */ - bool int_start_same_addr; - /* force finished */ - bool force_finished; - /* same source */ - bool same_src_fn; - /* insert channel number */ - bool insert_chnum; - - /* ddr bus in urgent */ - bool ugt; - - /* source sel switch to ctrl1 - * for toddr, 0: source sel is controlled by ctrl0 - * 1: source sel is controlled by ctrl1 - * for frddr, 0: source sel is controlled by ctrl0 - * 1: source sel is controlled by ctrl2 - */ - bool src_sel_ctrl; - - /* - * resample source sel switch - * resample : from ctrl0 to ctrl3 - * toddr : from ctrl0 to ctrl1 - */ - bool asrc_src_sel_ctrl; - /* spdif in 32bit, only support left justified */ - bool asrc_only_left_j; - - /* toddr number max - * 0: default, 3 toddr, axg, g12a, g12b - * 4: 4 toddr, tl1 - */ - int fifo_num; -}; - -struct toddr { - //struct ddr_desc dscrpt; - struct device *dev; - unsigned int resample: 1; - unsigned int ext_signed: 1; - unsigned int msb_bit; - unsigned int lsb_bit; - unsigned int reg_base; - unsigned int bitdepth; - unsigned int channels; - unsigned int rate; - enum toddr_src src; - unsigned int fifo_id; - - unsigned int asrc_src_sel; - - int is_lb; /* check whether for loopback */ - int irq; - bool in_use: 1; - struct aml_audio_controller *actrl; - struct ddr_chipinfo *chipinfo; -}; - -enum status { - DISABLED, - READY, /* controls has set enable, but ddr is not in running */ - RUNNING, -}; - -struct toddr_attach { - bool enable; - int id; - int status; - /* which module should be attached, - * check which toddr in use should be attached - */ - enum toddr_src attach_module; -}; - -struct frddr_attach { - bool enable; - int status; - /* which module for attach , - * check which frddr in use should be added - */ - enum frddr_dest attach_module; -}; - -struct frddr { - //struct ddr_desc dscrpt; - struct device *dev; - enum frddr_dest dest; - struct aml_audio_controller *actrl; - unsigned int reg_base; - unsigned int fifo_id; - - unsigned int msb; - unsigned int type; - - int irq; - bool in_use; - struct ddr_chipinfo *chipinfo; -}; #define DDRMAX 4 static struct frddr frddrs[DDRMAX]; @@ -173,6 +57,11 @@ static struct toddr_attach attach_pwrdet; static void aml_check_pwrdet(bool enable); static bool aml_check_pwrdet_module(int src); +/* VAD */ +static struct toddr_attach attach_vad; +static void aml_check_vad(struct toddr *to, bool enable); + + /* Audio EQ DRC */ static struct frddr_attach attach_aed; static void aml_check_aed(bool enable, int dst); @@ -213,7 +102,7 @@ static struct toddr *register_toddr_l(struct device *dev, to->dev = dev; to->actrl = actrl; to->in_use = true; - pr_info("toddrs[%d] registered by device %s\n", i, dev_name(dev)); + pr_debug("toddrs[%d] registered by device %s\n", i, dev_name(dev)); return to; } @@ -259,7 +148,7 @@ static int unregister_toddr_l(struct device *dev, void *data) to->dev = NULL; to->actrl = NULL; to->in_use = false; - pr_info("toddrs[%d] released by device %s\n", i, dev_name(dev)); + pr_debug("toddrs[%d] released by device %s\n", i, dev_name(dev)); return 0; } @@ -275,8 +164,6 @@ int fetch_toddr_index_by_src(int toddr_src) } } - pr_err("invalid toddr src\n"); - return -1; } @@ -291,8 +178,6 @@ struct toddr *fetch_toddr_by_src(int toddr_src) } } - pr_err("invalid toddr src\n"); - return NULL; } @@ -332,6 +217,9 @@ int aml_toddr_set_buf(struct toddr *to, unsigned int start, unsigned int reg_base = to->reg_base; unsigned int reg; + to->start_addr = start; + to->end_addr = end; + reg = calc_toddr_address(EE_AUDIO_TODDR_A_START_ADDR, reg_base); aml_audiobus_write(actrl, reg, start); reg = calc_toddr_address(EE_AUDIO_TODDR_A_FINISH_ADDR, reg_base); @@ -347,6 +235,41 @@ int aml_toddr_set_buf(struct toddr *to, unsigned int start, return 0; } +int aml_toddr_set_buf_startaddr(struct toddr *to, unsigned int start) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + to->start_addr = start; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_START_ADDR, reg_base); + aml_audiobus_write(actrl, reg, start); + + /* int address */ + if (to->chipinfo + && (!to->chipinfo->int_start_same_addr)) { + reg = calc_toddr_address(EE_AUDIO_TODDR_A_INIT_ADDR, reg_base); + aml_audiobus_write(actrl, reg, start); + } + + return 0; +} + +int aml_toddr_set_buf_endaddr(struct toddr *to, unsigned int end) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + to->end_addr = end; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_FINISH_ADDR, reg_base); + aml_audiobus_write(actrl, reg, end); + + return 0; +} + int aml_toddr_set_intrpt(struct toddr *to, unsigned int intrpt) { struct aml_audio_controller *actrl = to->actrl; @@ -371,6 +294,34 @@ unsigned int aml_toddr_get_position(struct toddr *to) return aml_audiobus_read(actrl, reg); } +unsigned int aml_toddr_get_addr(struct toddr *to, enum status_sel sel) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg_sel, reg, addr; + + reg_sel = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + aml_audiobus_update_bits(actrl, reg_sel, + 0xf << 8, + sel << 8); + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_STATUS2, reg_base); + addr = aml_audiobus_read(actrl, reg); + + if (sel == VAD_WAKEUP_ADDR) { + /* clear VAD addr/cnt */ + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base); + aml_audiobus_update_bits(actrl, reg, 0x1 << 1, 0x1 << 1); + } + + /* reset to default, current write addr */ + aml_audiobus_update_bits(actrl, reg_sel, + 0xf << 8, + 0x0 << 8); + + return addr; +} + void aml_toddr_enable(struct toddr *to, bool enable) { struct aml_audio_controller *actrl = to->actrl; @@ -383,9 +334,16 @@ void aml_toddr_enable(struct toddr *to, bool enable) /* check resample */ aml_check_resample(to, enable); - /* check power detect */ - if (aml_check_pwrdet_module(to->src)) - aml_check_pwrdet(enable); + if (to->chipinfo + && to->chipinfo->wakeup) { + if (to->chipinfo->wakeup == 1) { + /* check power detect */ + if (aml_check_pwrdet_module(to->src)) + aml_check_pwrdet(enable); + } else if (to->chipinfo->wakeup == 2) + /* check VAD */ + aml_check_vad(to, enable); + } if (!enable) aml_audiobus_write(actrl, reg, 0x0); @@ -444,6 +402,35 @@ void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh) } } +void aml_toddr_update_fifos_rd_th(struct toddr *to, int th) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg, mask, val; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + if (to->chipinfo + && to->chipinfo->src_sel_ctrl) { + mask = 0xfff << 12; + val = (th - 1) << 12; + } else { + mask = 0xff << 16; + val = (th - 1) << 16; + } + aml_audiobus_update_bits(actrl, reg, mask, val); +} + +void aml_toddr_force_finish(struct toddr *to) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + aml_audiobus_update_bits(actrl, reg, 1 << 25, 1 << 25); + aml_audiobus_update_bits(actrl, reg, 1 << 25, 0 << 25); +} + void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt) { struct aml_audio_controller *actrl = to->actrl; @@ -499,8 +486,6 @@ void aml_toddr_set_resample(struct toddr *to, bool enable) unsigned int reg_base = to->reg_base; unsigned int reg; - pr_info("toddr selects data to %s resample\n", - enable ? "enable" : "disable"); reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base); aml_audiobus_update_bits(actrl, reg, 1<<30, enable<<30); } @@ -511,9 +496,6 @@ void aml_toddr_set_resample_ab(struct toddr *to, int asrc_src_sel, bool enable) unsigned int reg_base = to->reg_base; unsigned int reg; - pr_info("toddr selects data to %s resample %c\n", - enable ? "enable" : "disable", - (asrc_src_sel == 0) ? 'a' : 'b'); reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); if (asrc_src_sel == 0) aml_audiobus_update_bits(actrl, reg, 1 << 27, enable << 27); @@ -546,11 +528,12 @@ static void aml_resample_enable( } } - pr_info("Resample %d in running, module:%d, toddr:%d, asrc_src_sel:%d\n", - p_attach_resample->id, - p_attach_resample->attach_module, + pr_info("toddr %d selects data to %s resample_%c for module:%s\n", to->fifo_id, - to->asrc_src_sel); + enable ? "enable" : "disable", + (p_attach_resample->id == 0) ? 'a' : 'b', + toddr_src_get_str(p_attach_resample->attach_module) + ); if (enable) { int bitwidth = to->bitdepth; @@ -708,17 +691,18 @@ void aml_pwrdet_enable(bool enable, int pwrdet_module) if (!to) { attach_pwrdet.status = READY; - pr_info("not in capture, power detect is ready\n"); } else { attach_pwrdet.status = RUNNING; aml_set_pwrdet(to, enable); + pr_info("Capture with power detect\n"); } } } else { if (attach_pwrdet.status == RUNNING) { struct toddr *to = fetch_toddr_by_src(pwrdet_module); - aml_set_pwrdet(to, enable); + if (to) + aml_set_pwrdet(to, enable); } attach_pwrdet.status = DISABLED; } @@ -751,6 +735,79 @@ static void aml_check_pwrdet(bool enable) } } +static void aml_vad_enable( + struct toddr_attach *p_attach_vad, + bool enable) +{ + struct toddr *to = fetch_toddr_by_src(p_attach_vad->attach_module); + + if (!to) + return; + + vad_set_toddr_info(enable ? to : NULL); + + /* vad enable or not */ + vad_enable(enable); +} + +void aml_set_vad(bool enable, int module) +{ + struct toddr_attach *p_attach_vad = &attach_vad; + bool update_running = false; + + p_attach_vad->enable = enable; + p_attach_vad->attach_module = module; + + if (enable) { + if ((p_attach_vad->status == DISABLED) + || (p_attach_vad->status == READY)) { + struct toddr *to = fetch_toddr_by_src( + p_attach_vad->attach_module); + + if (!to) { + p_attach_vad->status = READY; + } else { + p_attach_vad->status = RUNNING; + update_running = true; + pr_info("Capture with VAD\n"); + } + } + } else { + if (p_attach_vad->status == RUNNING) + update_running = true; + + p_attach_vad->status = DISABLED; + } + + if (update_running) + aml_vad_enable(p_attach_vad, enable); +} + +/* + * when try to enable vad, if toddr is not in used, + * set vad status as ready + */ +static void aml_check_vad(struct toddr *to, bool enable) +{ + struct toddr_attach *p_attach_vad = &attach_vad; + bool is_vad = false; + + if (p_attach_vad->enable + && (to->src == p_attach_vad->attach_module)) + is_vad = true; + + /* vad in enable */ + if (is_vad) { + if (enable) + p_attach_vad->status = RUNNING; + else + p_attach_vad->status = DISABLED; + + aml_vad_enable(p_attach_vad, enable); + } +} + + /* from DDRS */ static struct frddr *register_frddr_l(struct device *dev, struct aml_audio_controller *actrl, @@ -786,7 +843,7 @@ static struct frddr *register_frddr_l(struct device *dev, from->dev = dev; from->actrl = actrl; from->in_use = true; - pr_info("frddrs[%d] registered by device %s\n", i, dev_name(dev)); + pr_debug("frddrs[%d] registered by device %s\n", i, dev_name(dev)); return from; } @@ -826,7 +883,7 @@ static int unregister_frddr_l(struct device *dev, void *data) from->dev = NULL; from->actrl = NULL; from->in_use = false; - pr_info("frddrs[%d] released by device %s\n", i, dev_name(dev)); + pr_debug("frddrs[%d] released by device %s\n", i, dev_name(dev)); return 0; } @@ -841,7 +898,6 @@ int fetch_frddr_index_by_src(int frddr_src) } } - pr_err("invalid frdd_src\n"); return -1; } @@ -856,8 +912,6 @@ struct frddr *fetch_frddr_by_src(int frddr_src) } } - pr_err("invalid frddr src\n"); - return NULL; } @@ -877,7 +931,8 @@ int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel) && (frddrs[i].fifo_id != current_fifo_id) && (frddrs[i].dest == ss_sel)) { - pr_info("ss_sel:%d used, invalid for share buffer\n", + pr_info(" frddr:%d, ss_sel:%d used, invalid for share buffer\n", + i, ss_sel); ret = 0; break; @@ -971,9 +1026,18 @@ void aml_frddr_enable(struct frddr *fr, bool enable) /* ensure disable before enable frddr */ aml_audiobus_update_bits(actrl, reg, 1<<31, enable<<31); - if (!enable) + if (!enable) { aml_audiobus_write(actrl, reg, 0x0); + /* clr src sel and its en */ + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + aml_audiobus_write(actrl, reg, 0x0); + } + } + /* check for Audio EQ/DRC */ if (aml_check_aed_module(fr->dest)) aml_check_aed(enable, fr->dest); @@ -1019,8 +1083,6 @@ void aml_frddr_select_dst_ss(struct frddr *fr, unsigned int reg_base = fr->reg_base; unsigned int reg, ss_valid; - reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base); - ss_valid = aml_check_sharebuffer_valid(fr, dst); /* same source en */ @@ -1029,21 +1091,54 @@ void aml_frddr_select_dst_ss(struct frddr *fr, && ss_valid) { int s_v = 0, s_m = 0; - switch (sel) { - case 1: - s_m = 0xf << 4; - s_v = enable ? (dst << 4 | 1 << 7) : 0 << 4; - break; - case 2: - s_m = 0xf << 8; - s_v = enable ? (dst << 8 | 1 << 11) : 0 << 8; - break; - default: - pr_warn_once("sel :%d is not supported for same source\n", - sel); - break; + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + + switch (sel) { + case 1: + s_m = 0x17 << 8; + s_v = enable ? + (dst << 8 | 1 << 12) : 0 << 8; + break; + case 2: + s_m = 0x17 << 16; + s_v = enable ? + (dst << 16 | 1 << 20) : 0 << 16; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } + s_m |= 0xff << 24; + if (enable) + s_v |= (fr->channels - 1) << 24; + else + s_v |= 0x0 << 24; + } else { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, + reg_base); + + switch (sel) { + case 1: + s_m = 0xf << 4; + s_v = enable ? + (dst << 4 | 1 << 7) : 0 << 4; + break; + case 2: + s_m = 0xf << 8; + s_v = enable ? + (dst << 8 | 1 << 11) : 0 << 8; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } } - pr_info("%s sel:%d, dst_src:%d\n", + pr_debug("%s sel:%d, dst_src:%d\n", __func__, sel, dst); aml_audiobus_update_bits(actrl, reg, s_m, s_v); } @@ -1073,8 +1168,11 @@ unsigned int aml_frddr_get_fifo_id(struct frddr *fr) } void aml_frddr_set_format(struct frddr *fr, - unsigned int msb, unsigned int frddr_type) + unsigned int chnum, + unsigned int msb, + unsigned int frddr_type) { + fr->channels = chnum; fr->msb = msb; fr->type = frddr_type; } @@ -1336,11 +1434,13 @@ int card_add_ddr_kcontrols(struct snd_soc_card *card) static struct ddr_chipinfo axg_ddr_chipinfo = { .int_start_same_addr = true, .asrc_only_left_j = true, + .wakeup = 1, }; static struct ddr_chipinfo g12a_ddr_chipinfo = { .same_src_fn = true, .asrc_only_left_j = true, + .wakeup = 1, }; static struct ddr_chipinfo tl1_ddr_chipinfo = { @@ -1349,6 +1449,7 @@ static struct ddr_chipinfo tl1_ddr_chipinfo = { .src_sel_ctrl = true, .asrc_src_sel_ctrl = true, .fifo_num = 4, + .wakeup = 2, }; static const struct of_device_id aml_ddr_mngr_device_id[] = { @@ -1368,11 +1469,45 @@ static const struct of_device_id aml_ddr_mngr_device_id[] = { }; MODULE_DEVICE_TABLE(of, aml_ddr_mngr_device_id); +static bool pm_audio_in_suspend; + +void pm_audio_set_suspend(bool is_suspend) +{ + pm_audio_in_suspend = is_suspend; +} + +bool pm_audio_is_suspend(void) +{ + return pm_audio_in_suspend; +} + +/* Detects a suspend and resume event */ +static int ddr_pm_event(struct notifier_block *notifier, + unsigned long pm_event, void *unused) +{ + pr_info("%s, pm_event:%lu\n", __func__, pm_event); + + switch (pm_event) { + case PM_SUSPEND_PREPARE: + pm_audio_set_suspend(true); + break; + case PM_POST_SUSPEND: + break; + default: + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block ddr_pm_notifier_block = { + .notifier_call = ddr_pm_event, +}; + static int aml_ddr_mngr_platform_probe(struct platform_device *pdev) { struct ddr_chipinfo *p_ddr_chipinfo; int ddr_num = 3; /* early chipset support max 3 ddr num */ - int i; + int i, ret; p_ddr_chipinfo = (struct ddr_chipinfo *) of_device_get_match_data(&pdev->dev); @@ -1436,6 +1571,12 @@ static int aml_ddr_mngr_platform_probe(struct platform_device *pdev) frddrs[DDR_D].fifo_id = DDR_D; } } + + ret = register_pm_notifier(&ddr_pm_notifier_block); + if (ret) + pr_warn("[%s] failed to register PM notifier %d\n", + __func__, ret); + return 0; } diff --git a/sound/soc/amlogic/auge/ddr_mngr.h b/sound/soc/amlogic/auge/ddr_mngr.h index 30ed31c7d9ee..ab1c795b64b1 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.h +++ b/sound/soc/amlogic/auge/ddr_mngr.h @@ -73,6 +73,16 @@ enum frddr_dest { SPDIFOUT_B, }; +enum status_sel { + CURRENT_DDR_ADDR, + NEXT_FINISH_ADDR, + COUNT_CURRENT_DDR_ACK, + COUNT_NEXT_FINISH_DDR_ACK, + VAD_WAKEUP_ADDR, /* from tl1, vad */ + VAD_FS_ADDR, + VAD_FIFO_CNT, +}; + struct toddr_fmt { unsigned int type; unsigned int msb; @@ -83,6 +93,140 @@ struct toddr_fmt { unsigned int rate; }; +#if 0 +struct ddr_desc { + /* start address of DDR */ + unsigned int start; + /* finish address of DDR */ + unsigned int finish; + /* interrupt address or counts of DDR blocks */ + unsigned int intrpt; + /* fifo total counts */ + unsigned int fifo_depth; + /* fifo start threshold */ + unsigned int fifo_thr; + enum ddr_types data_type; + unsigned int edian; + unsigned int pp_mode; + //unsigned int reg_base; + struct clk *ddr; + struct clk *ddr_arb; +}; +#endif + +struct ddr_chipinfo { + /* INT and Start address is same or separated */ + bool int_start_same_addr; + /* force finished */ + bool force_finished; + /* same source */ + bool same_src_fn; + /* insert channel number */ + bool insert_chnum; + + /* ddr bus in urgent */ + bool ugt; + + /* source sel switch to ctrl1 + * for toddr, 0: source sel is controlled by ctrl0 + * 1: source sel is controlled by ctrl1 + * for frddr, 0: source sel is controlled by ctrl0 + * 1: source sel is controlled by ctrl2 + */ + bool src_sel_ctrl; + + /* + * resample source sel switch + * resample : from ctrl0 to ctrl3 + * toddr : from ctrl0 to ctrl1 + */ + bool asrc_src_sel_ctrl; + /* spdif in 32bit, only support left justified */ + bool asrc_only_left_j; + + /* toddr number max + * 0: default, 3 toddr, axg, g12a, g12b + * 4: 4 toddr, tl1 + */ + int fifo_num; + + /* power detect or VAD + * 0: disabled + * 1: power detect + * 2: vad + */ + int wakeup; +}; + +struct toddr { + //struct ddr_desc dscrpt; + struct device *dev; + unsigned int resample: 1; + unsigned int ext_signed: 1; + unsigned int msb_bit; + unsigned int lsb_bit; + unsigned int reg_base; + unsigned int bitdepth; + unsigned int channels; + unsigned int rate; + + unsigned int start_addr; + unsigned int end_addr; + + enum toddr_src src; + unsigned int fifo_id; + + unsigned int asrc_src_sel; + + int is_lb; /* check whether for loopback */ + int irq; + bool in_use: 1; + struct aml_audio_controller *actrl; + struct ddr_chipinfo *chipinfo; +}; + +enum status { + DISABLED, + READY, /* controls has set enable, but ddr is not in running */ + RUNNING, +}; + +struct toddr_attach { + bool enable; + int id; + int status; + /* which module should be attached, + * check which toddr in use should be attached + */ + enum toddr_src attach_module; +}; + +struct frddr_attach { + bool enable; + int status; + /* which module for attach , + * check which frddr in use should be added + */ + enum frddr_dest attach_module; +}; + +struct frddr { + //struct ddr_desc dscrpt; + struct device *dev; + enum frddr_dest dest; + struct aml_audio_controller *actrl; + unsigned int reg_base; + unsigned int fifo_id; + + unsigned int channels; + unsigned int msb; + unsigned int type; + + int irq; + bool in_use; + struct ddr_chipinfo *chipinfo; +}; + /* to ddrs */ int fetch_toddr_index_by_src(int toddr_src); struct toddr *fetch_toddr_by_src(int toddr_src); @@ -92,11 +236,17 @@ struct toddr *aml_audio_register_toddr(struct device *dev, int aml_audio_unregister_toddr(struct device *dev, void *data); int aml_toddr_set_buf(struct toddr *to, unsigned int start, unsigned int end); +int aml_toddr_set_buf_startaddr(struct toddr *to, unsigned int start); +int aml_toddr_set_buf_endaddr(struct toddr *to, unsigned int end); + int aml_toddr_set_intrpt(struct toddr *to, unsigned int intrpt); unsigned int aml_toddr_get_position(struct toddr *to); +unsigned int aml_toddr_get_addr(struct toddr *to, enum status_sel sel); void aml_toddr_select_src(struct toddr *to, enum toddr_src); void aml_toddr_enable(struct toddr *to, bool enable); void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh); +void aml_toddr_update_fifos_rd_th(struct toddr *to, int th); +void aml_toddr_force_finish(struct toddr *to); void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt); void aml_toddr_insert_chanum(struct toddr *to); unsigned int aml_toddr_read(struct toddr *to); @@ -106,6 +256,8 @@ void aml_toddr_write(struct toddr *to, unsigned int val); void aml_set_resample(int id, bool enable, int resample_module); /* power detect */ void aml_pwrdet_enable(bool enable, int pwrdet_module); +/* Voice Activity Detection */ +void aml_set_vad(bool enable, int module); /* from ddrs */ int fetch_frddr_index_by_src(int frddr_src); @@ -130,7 +282,9 @@ void aml_frddr_set_fifos(struct frddr *fr, unsigned int depth, unsigned int thresh); unsigned int aml_frddr_get_fifo_id(struct frddr *fr); void aml_frddr_set_format(struct frddr *fr, - unsigned int msb, unsigned int frddr_type); + unsigned int chnum, + unsigned int msb, + unsigned int frddr_type); /* audio eq drc */ void aml_set_aed(bool enable, int aed_module); @@ -144,5 +298,8 @@ const char *frddr_src_get_str(int idx); int card_add_ddr_kcontrols(struct snd_soc_card *card); +void pm_audio_set_suspend(bool is_suspend); +bool pm_audio_is_suspend(void); + #endif diff --git a/sound/soc/amlogic/auge/extn.c b/sound/soc/amlogic/auge/extn.c index c0fe61605c77..55d3e46ec438 100644 --- a/sound/soc/amlogic/auge/extn.c +++ b/sound/soc/amlogic/auge/extn.c @@ -613,6 +613,72 @@ static int frhdmirx_set_mode( return 0; } +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +/* spdif in audio format detect: LPCM or NONE-LPCM */ +struct sppdif_audio_info { + unsigned char aud_type; + /*IEC61937 package presamble Pc value*/ + short pc; + char *aud_type_str; +}; + +static const char *const spdif_audio_type_texts[] = { + "LPCM", + "AC3", + "EAC3", + "DTS", + "DTS-HD", + "TRUEHD", + "PAUSE" +}; + +static const struct sppdif_audio_info type_texts[] = { + {0, 0, "LPCM"}, + {1, 0x1, "AC3"}, + {2, 0x15, "EAC3"}, + {3, 0xb, "DTS-I"}, + {3, 0x0c, "DTS-II"}, + {3, 0x0d, "DTS-III"}, + {3, 0x11, "DTS-IV"}, + {4, 0, "DTS-HD"}, + {5, 0x16, "TRUEHD"}, + {6, 0x103, "PAUSE"}, + {6, 0x003, "PAUSE"}, + {6, 0x100, "PAUSE"}, +}; + +static const struct soc_enum hdmirx_audio_type_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_audio_type_texts), + spdif_audio_type_texts); + +static int hdmiin_check_audio_type(void) +{ + int total_num = sizeof(type_texts)/sizeof(struct sppdif_audio_info); + int pc = frhdmirx_get_chan_status_pc(); + int audio_type = 0; + int i; + + for (i = 0; i < total_num; i++) { + if (pc == type_texts[i].pc) { + audio_type = type_texts[i].aud_type; + break; + } + } + + pr_debug("%s audio type:%d\n", __func__, audio_type); + + return audio_type; +} + +static int hdmirx_audio_type_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = + hdmiin_check_audio_type(); + return 0; +} +#endif static const struct snd_kcontrol_new extn_controls[] = { /* Out */ @@ -664,6 +730,10 @@ static const struct snd_kcontrol_new extn_controls[] = { 0, aml_get_atmos_audio_edid, aml_set_atmos_audio_edid), + SOC_ENUM_EXT("HDMIIN Audio Type", + hdmirx_audio_type_enum, + hdmirx_audio_type_get_enum, + NULL), #endif }; @@ -723,8 +793,8 @@ static int extn_platform_probe(struct platform_device *pdev) /* Default ARC SRC */ p_extn->arc_src = 1; - /* Default: PAO mode */ - p_extn->hdmirx_mode = 1; + /* Default: SPDIF in mode */ + p_extn->hdmirx_mode = 0; ret = snd_soc_register_component(&pdev->dev, &extn_component, diff --git a/sound/soc/amlogic/auge/frhdmirx_hw.c b/sound/soc/amlogic/auge/frhdmirx_hw.c index c46f6df81a44..19c55f480522 100644 --- a/sound/soc/amlogic/auge/frhdmirx_hw.c +++ b/sound/soc/amlogic/auge/frhdmirx_hw.c @@ -84,7 +84,11 @@ void frhdmirx_ctrl(int channels, int src) /* PAO mode */ if (src) { audiobus_write(EE_AUDIO_FRHDMIRX_CTRL0, - 0x1 << 23 | 0x1 << 22 | 0x1 << 7); + 0x1 << 23 | /* slect pao mode */ + 0x1 << 22 | /* capture input by fall edge*/ + 0x1 << 7 | /* start sending ch num info out */ + 0x1 << 8 | /* start detect PAPB */ + 0x1 << 6 /* chan status sel: pao pc/pd value */); return; } @@ -101,7 +105,7 @@ void frhdmirx_ctrl(int channels, int src) 0x1 << 30 | /* chnum_sel */ lane_mask << 24 | /* chnum_sel */ 0x1 << 22 | /* clk_inv */ - 0x0 << 11 /* req_sel, Sync 4 spdifin by which */ + 0x0 << 11 /* req_sel, Sync 4 spdifin by which */ ); /* nonpcm2pcm_th */ @@ -110,3 +114,14 @@ void frhdmirx_ctrl(int channels, int src) /* enable irq bits */ frhdmirx_enable_irq_bits(channels, src); } + +unsigned int frhdmirx_get_chan_status_pc(void) +{ + unsigned int val; + + val = audiobus_read(EE_AUDIO_FRHDMIRX_STAT1); + return (val >> 16) & 0xff; +} + + + diff --git a/sound/soc/amlogic/auge/frhdmirx_hw.h b/sound/soc/amlogic/auge/frhdmirx_hw.h index ce51e13242cd..e0ebfe46323e 100644 --- a/sound/soc/amlogic/auge/frhdmirx_hw.h +++ b/sound/soc/amlogic/auge/frhdmirx_hw.h @@ -20,5 +20,5 @@ extern void frhdmirx_enable(bool enable); extern void frhdmirx_src_select(int src); extern void frhdmirx_ctrl(int channels, int src); - +extern unsigned int frhdmirx_get_chan_status_pc(void); #endif diff --git a/sound/soc/amlogic/auge/locker.c b/sound/soc/amlogic/auge/locker.c index bc53b6a0e0f6..d41cc4ab6ca7 100644 --- a/sound/soc/amlogic/auge/locker.c +++ b/sound/soc/amlogic/auge/locker.c @@ -14,6 +14,8 @@ * more details. * */ +#define DEBUG + #include #include @@ -192,7 +194,7 @@ void audio_locker_set(int enable) int audio_locker_get(void) { if (!s_locker) { - pr_err("audio locker is not init\n"); + pr_debug("audio locker is not init\n"); return -1; } diff --git a/sound/soc/amlogic/auge/pdm.c b/sound/soc/amlogic/auge/pdm.c index e29228d51294..d4ef74f0e7b1 100644 --- a/sound/soc/amlogic/auge/pdm.c +++ b/sound/soc/amlogic/auge/pdm.c @@ -34,6 +34,7 @@ #include "iomap.h" #include "regs.h" #include "ddr_mngr.h" +#include "vad.h" /*#define __PTM_PDM_CLK__*/ @@ -55,8 +56,8 @@ static struct snd_pcm_hardware aml_pdm_hardware = { .channels_min = PDM_CHANNELS_MIN, .channels_max = PDM_CHANNELS_MAX, - .buffer_bytes_max = 32 * 1024, - .period_bytes_max = 16 * 1024, + .buffer_bytes_max = 512 * 1024, + .period_bytes_max = 256 * 1024, .period_bytes_min = 32, .periods_min = 2, .periods_max = 1024, @@ -592,6 +593,10 @@ static int aml_pdm_dai_prepare( unsigned int bitwidth; unsigned int toddr_type, lsb; + if (vad_pdm_is_running() + && pm_audio_is_suspend()) + return 0; + /* set bclk */ bitwidth = snd_pcm_format_width(runtime->format); lsb = 32 - bitwidth; @@ -690,12 +695,21 @@ static int aml_pdm_dai_trigger( { struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai); - pr_info("%s\n", __func__); + pr_info("%s, cmd:%d\n", __func__, cmd); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + + if (vad_pdm_is_running() + && pm_audio_is_suspend()) { + pm_audio_set_suspend(false); + /* VAD switch to alsa buffer */ + vad_update_buffer(0); + break; + } + pdm_fifo_reset(); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { @@ -709,6 +723,13 @@ static int aml_pdm_dai_trigger( case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (vad_pdm_is_running() + && pm_audio_is_suspend()) { + /* switch to VAD buffer */ + vad_update_buffer(1); + break; + } + dev_info(substream->pcm->card->dev, "pdm capture stop\n"); pdm_enable(0); aml_toddr_enable(p_pdm->tddr, 0); diff --git a/sound/soc/amlogic/auge/resample.c b/sound/soc/amlogic/auge/resample.c index 326ebaa2f45a..7c56eb1cc200 100644 --- a/sound/soc/amlogic/auge/resample.c +++ b/sound/soc/amlogic/auge/resample.c @@ -14,6 +14,8 @@ * more details. * */ +#define DEBUG + #include #include #include @@ -82,7 +84,7 @@ static struct audioresample *get_audioresample(int id) p_resample = ((id == 0) ? s_resample_a : s_resample_b); if (!p_resample) { - pr_info("Not init audio resample\n"); + pr_debug("Not init audio resample\n"); return NULL; } @@ -105,19 +107,6 @@ static int resample_clk_set(struct audioresample *p_resample) /* enable clock */ if (p_resample->enable) { - ret = clk_prepare_enable(p_resample->clk); - if (ret) { - pr_err("Can't enable resample_clk clock: %d\n", - ret); - return -EINVAL; - } - - ret = clk_prepare_enable(p_resample->sclk); - if (ret) { - pr_err("Can't enable resample_src clock: %d\n", - ret); - return -EINVAL; - } if (p_resample->out_rate) { #ifdef __PTM_RESAMPLE_CLK__ @@ -144,6 +133,20 @@ static int resample_clk_set(struct audioresample *p_resample) return -EINVAL; } + ret = clk_prepare_enable(p_resample->sclk); + if (ret) { + pr_err("Can't enable resample_src clock: %d\n", + ret); + return -EINVAL; + } + + ret = clk_prepare_enable(p_resample->clk); + if (ret) { + pr_err("Can't enable resample_clk clock: %d\n", + ret); + return -EINVAL; + } + pr_info("%s, resample_pll:%lu, sclk:%lu, clk:%lu\n", __func__, clk_get_rate(p_resample->pll), @@ -226,7 +229,7 @@ static int resample_get_enum( struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); if (!p_resample) { - pr_info("audio resample is not init\n"); + pr_debug("audio resample is not init\n"); return 0; } @@ -248,8 +251,9 @@ int resample_set(int id, int index) p_resample->asrc_rate_idx = index; - pr_info("%s %s\n", + pr_info("%s resample_%c %s\n", __func__, + (id == 0) ? 'a' : 'b', auge_resample_texts[index]); if (audio_resample_set(p_resample, (bool)index, resample_rate)) @@ -274,7 +278,7 @@ static int resample_set_enum( int index = ucontrol->value.enumerated.item[0]; if (!p_resample) { - pr_info("audio resample is not init\n"); + pr_debug("audio resample is not init\n"); return 0; } @@ -355,7 +359,7 @@ static int resample_module_get_enum( struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); if (!p_resample) { - pr_info("audio resample is not init\n"); + pr_debug("audio resample is not init\n"); return 0; } @@ -371,7 +375,7 @@ static int resample_module_set_enum( struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); if (!p_resample) { - pr_info("audio resample is not init\n"); + pr_debug("audio resample is not init\n"); return 0; } @@ -582,4 +586,3 @@ static struct platform_driver resample_platform_driver = { .probe = resample_platform_probe, }; module_platform_driver(resample_platform_driver); - diff --git a/sound/soc/amlogic/auge/resample_hw.c b/sound/soc/amlogic/auge/resample_hw.c index 0425c607a572..1722ce8eb82d 100644 --- a/sound/soc/amlogic/auge/resample_hw.c +++ b/sound/soc/amlogic/auge/resample_hw.c @@ -70,8 +70,8 @@ int resample_init(int id, int input_sr) else pr_err("unsupport input sample rate:%d\n", input_sr); - pr_info("resample id:%d, clk_rate = %u, input_sr = %d, Avg_cnt_init = %u\n", - id, + pr_info("resample id:%c, clk_rate = %u, input_sr = %d, Avg_cnt_init = %u\n", + (id == 0) ? 'a' : 'b', clk_rate, input_sr, Avg_cnt_init); diff --git a/sound/soc/amlogic/auge/sharebuffer.c b/sound/soc/amlogic/auge/sharebuffer.c index 1ca66ad386fb..f94fd2a03b0c 100644 --- a/sound/soc/amlogic/auge/sharebuffer.c +++ b/sound/soc/amlogic/auge/sharebuffer.c @@ -34,7 +34,9 @@ static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream, spdifout_samesource_set(spdif_id, aml_frddr_get_fifo_id(fr), - bit_depth, true); + bit_depth, + runtime->channels, + true); /* spdif to hdmitx */ spdifout_to_hdmitx_ctrl(spdif_id); @@ -59,7 +61,9 @@ static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream, if (spdif_id != 1) spdifout_samesource_set(spdif_id, aml_frddr_get_fifo_id(fr), - bit_depth, false); + bit_depth, + runtime->channels, + false); return 0; } @@ -90,7 +94,8 @@ int sharebuffer_prepare(struct snd_pcm_substream *substream, // TODO: same with tdm } else if (samesource_sel < 5) { /* same source with spdif a/b */ - sharebuffer_spdifout_prepare(substream, fr, samesource_sel - 3); + sharebuffer_spdifout_prepare(substream, + fr, samesource_sel - 3); } /* frddr, share buffer, src_sel1 */ diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 19971c0c0374..5db566dd196a 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -14,7 +14,7 @@ * more details. * */ - +#define DEBUG #include #include #include @@ -51,6 +51,8 @@ /* for debug */ /*#define __SPDIFIN_INSERT_CHNUM__*/ +/*#define __SPDIFIN_AUDIO_TYPE_HW__*/ + struct spdif_chipinfo { unsigned int id; @@ -236,7 +238,7 @@ static int spdifin_check_audio_type(void) } } - pr_debug("%s audio type:%d\n", __func__, audio_type); + /*pr_debug("%s audio type:%d\n", __func__, audio_type);*/ return audio_type; } @@ -253,6 +255,7 @@ static int spdifin_audio_type_get_enum( /* For fake */ static bool is_mute; +static int spdifin_src; static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -268,6 +271,36 @@ static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol, return 0; } +static const char *const spdifin_src_texts[] = { + "spdifin pad", "spdifout", "N/A", "HDMIRX" +}; + +const struct soc_enum spdifin_src_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdifin_src_texts), + spdifin_src_texts); + +int spdifin_source_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = spdifin_src; + return 0; +} + +int spdifin_source_set_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int src = ucontrol->value.enumerated.item[0]; + + if (src > 3) { + pr_err("bad parameter for spdifin src set\n"); + return -1; + } + spdifin_set_src(src); + spdifin_src = src; + return 0; +} static const struct snd_kcontrol_new snd_spdif_controls[] = { @@ -288,6 +321,10 @@ static const struct snd_kcontrol_new snd_spdif_controls[] = { SOC_SINGLE_BOOL_EXT("Audio spdif mute", 0, aml_audio_get_spdif_mute, aml_audio_set_spdif_mute), + SOC_ENUM_EXT("Audio spdifin source", + spdifin_src_enum, + spdifin_source_get_enum, + spdifin_source_set_enum), }; @@ -525,11 +562,12 @@ static void spdifin_status_event(struct aml_spdif *p_spdif) pr_info("Event: EXTCON_SPDIFIN_SAMPLERATE, new sample rate:%s\n", spdifin_samplerate[mode + 1]); +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample enable, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) resample_set(p_spdif->asrc_id, p_spdif->auto_asrc); - +#endif extcon_set_state(p_spdif->edev, EXTCON_SPDIFIN_SAMPLERATE, 1); } @@ -547,16 +585,18 @@ static void spdifin_status_event(struct aml_spdif *p_spdif) EXTCON_SPDIFIN_AUDIOTYPE, 1); #ifdef __PTM_SPDIF_CLK__ +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample disable, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) resample_set(p_spdif->asrc_id, 0); +#endif #endif } if (intrpt_status & 0x10) pr_info("Pd changed\n"); } else { if (intrpt_status & 0x8) - pr_info("CH status changed\n"); + pr_debug("CH status changed\n"); if (intrpt_status & 0x10) { int val = spdifin_get_ch_status0to31(); @@ -579,9 +619,11 @@ static void spdifin_status_event(struct aml_spdif *p_spdif) extcon_set_state(p_spdif->edev, EXTCON_SPDIFIN_AUDIOTYPE, 0); +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample to 48k, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) resample_set(p_spdif->asrc_id, p_spdif->auto_asrc); +#endif } if (intrpt_status & 0x40) pr_info("valid changed\n"); @@ -818,7 +860,7 @@ static struct snd_pcm_ops aml_spdif_ops = { .mmap = aml_spdif_mmap, }; -#define PREALLOC_BUFFER (32 * 1024) +#define PREALLOC_BUFFER (128 * 1024) #define PREALLOC_BUFFER_MAX (256 * 1024) static int aml_spdif_new(struct snd_soc_pcm_runtime *rtd) { @@ -827,7 +869,7 @@ static int aml_spdif_new(struct snd_soc_pcm_runtime *rtd) p_spdif = (struct aml_spdif *)dev_get_drvdata(dev); - pr_info("%s spdif_%s, clk continuous:%d\n", + pr_debug("%s spdif_%s, clk continuous:%d\n", __func__, (p_spdif->id == 0) ? "a":"b", p_spdif->clk_cont); @@ -934,9 +976,12 @@ static int aml_dai_spdif_startup( pr_err("Can't enable pcm clk_spdifin clock: %d\n", ret); goto err; } + +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample to 48k in default, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) resample_set(p_spdif->asrc_id, p_spdif->auto_asrc); +#endif } return 0; @@ -963,10 +1008,11 @@ static void aml_dai_spdif_shutdown( clk_disable_unprepare(p_spdif->sysclk); clk_disable_unprepare(p_spdif->gate_spdifout); } else { +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample disabled, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) resample_set(p_spdif->asrc_id, 0); - +#endif clk_disable_unprepare(p_spdif->clk_spdifin); clk_disable_unprepare(p_spdif->fixed_clk); clk_disable_unprepare(p_spdif->gate_spdifin); @@ -1003,7 +1049,9 @@ static int aml_dai_spdif_prepare( } fifo_id = aml_frddr_get_fifo_id(fr); - aml_frddr_set_format(fr, bit_depth - 1, + aml_frddr_set_format(fr, + runtime->channels, + bit_depth - 1, spdifout_get_frddr_type(bit_depth)); aml_frddr_select_dst(fr, dst); aml_frddr_set_fifos(fr, 0x40, 0x20); @@ -1182,7 +1230,7 @@ static int aml_dai_spdif_hw_params(struct snd_pcm_substream *substream, static int aml_dai_set_spdif_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - pr_info("%s , fmt %#x\n", __func__, fmt); + pr_debug("%s , fmt %#x\n", __func__, fmt); return 0; } @@ -1196,10 +1244,10 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif) int ret; if (spdif_is_4x_clk()) { - pr_info("set 4x audio clk for 958\n"); + pr_debug("set 4x audio clk for 958\n"); p_spdif->sysclk_freq *= 4; } else { - pr_info("set normal 512 fs /4 fs\n"); + pr_debug("set normal 512 fs /4 fs\n"); } mpll_freq = p_spdif->sysclk_freq * mul; @@ -1221,10 +1269,10 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif) pr_err("Can't enable clk_spdifout clock: %d\n", ret); return; } - pr_info("\t set spdifout clk:%d, mpll:%d\n", + pr_debug("\t set spdifout clk:%d, mpll:%d\n", p_spdif->sysclk_freq, mpll_freq); - pr_info("\t get spdifout clk:%lu, mpll:%lu\n", + pr_debug("\t get spdifout clk:%lu, mpll:%lu\n", clk_get_rate(p_spdif->clk_spdifout), clk_get_rate(p_spdif->sysclk)); } @@ -1372,7 +1420,7 @@ static int aml_spdif_parse_of(struct platform_device *pdev) if (ret < 0) p_spdif->auto_asrc = 0; - pr_info("SPDIF id %d asrc_id:%d auto_asrc:%d\n", + pr_debug("SPDIF id %d asrc_id:%d auto_asrc:%d\n", p_spdif->id, p_spdif->asrc_id, p_spdif->auto_asrc); @@ -1497,7 +1545,7 @@ static int aml_spdif_platform_probe(struct platform_device *pdev) dev_warn_once(dev, "check whether to update spdif chipinfo\n"); - pr_info("%s, spdif ID = %u\n", __func__, aml_spdif->id); + pr_debug("%s, spdif ID = %u\n", __func__, aml_spdif->id); /* get audio controller */ node_prt = of_get_parent(node); diff --git a/sound/soc/amlogic/auge/spdif_hw.c b/sound/soc/amlogic/auge/spdif_hw.c index 592370b63600..d83fb6afda9a 100644 --- a/sound/soc/amlogic/auge/spdif_hw.c +++ b/sound/soc/amlogic/auge/spdif_hw.c @@ -14,7 +14,7 @@ * more details. * */ - +#define DEBUG #include #include "iomap.h" @@ -64,7 +64,7 @@ void aml_spdifin_chnum_en(struct aml_audio_controller *actrl, reg = EE_AUDIO_SPDIFIN_CTRL0; aml_audiobus_update_bits(actrl, reg, 1 << 26, is_enable << 26); - pr_info("%s spdifin ctrl0:0x%x\n", + pr_debug("%s spdifin ctrl0:0x%x\n", __func__, aml_audiobus_read(actrl, reg)); } @@ -234,7 +234,7 @@ void aml_spdif_fifo_ctrl( return; } - pr_info("%s, bit depth:%d, frddr type:%d, toddr:type:%d\n", + pr_debug("%s, bit depth:%d, frddr type:%d, toddr:type:%d\n", __func__, bitwidth, frddr_type, @@ -403,12 +403,16 @@ void spdifout_clk_ctrl(int spdif_id, bool is_enable) audiobus_write(reg, is_enable << 31 | 0x0 << 24 | 0x3 << 0); } -void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth) +static void spdifout_fifo_ctrl(int spdif_id, + int fifo_id, int bitwidth, int channels) { unsigned int frddr_type = spdifout_get_frddr_type(bitwidth); - unsigned int offset, reg; + unsigned int offset, reg, i, chmask = 0; - pr_info("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n", + for (i = 0; i < channels; i++) + chmask |= (1 << i); + + pr_debug("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n", (spdif_id == 0) ? "a":"b", fifo_id, frddr_type, @@ -419,7 +423,7 @@ void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth) reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id; audiobus_update_bits(reg, 0x3<<21|0x1<<20|0x1<<19|0xff<<4, - 0x0<<21|0<<20|0<<19|0x3<<4); + 0x0<<21|0<<20|0<<19|chmask<<4); offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1; reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdif_id; @@ -454,7 +458,7 @@ void spdifout_enable(int spdif_id, bool is_enable) { unsigned int offset, reg; - pr_info("spdif_%s is set to %s\n", + pr_debug("spdif_%s is set to %s\n", (spdif_id == 0) ? "a":"b", is_enable ? "enable":"disable"); @@ -471,7 +475,7 @@ void spdifout_enable(int spdif_id, bool is_enable) } void spdifout_samesource_set(int spdif_index, int fifo_id, - int bitwidth, bool is_enable) + int bitwidth, int channels, bool is_enable) { int spdif_id; @@ -485,7 +489,7 @@ void spdifout_samesource_set(int spdif_index, int fifo_id, spdifout_clk_ctrl(spdif_id, /*is_enable*/true); if (is_enable) - spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth); + spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth, channels); } int spdifin_get_sample_rate(void) @@ -528,6 +532,11 @@ int spdifin_get_audio_type(void) return (val >> 16) & 0xff; } +void spdifin_set_src(int src) +{ + audiobus_update_bits(EE_AUDIO_SPDIFIN_CTRL0, 0x3 << 4, src << 4); +} + void spdif_set_channel_status_info( struct iec958_chsts *chsts, int spdif_id) { @@ -589,7 +598,7 @@ void spdif_set_channel_status_info( void spdifout_play_with_zerodata(unsigned int spdif_id) { - pr_info("%s, spdif id:%d enable:%d\n", + pr_debug("%s, spdif id:%d enable:%d\n", __func__, spdif_id, spdifout_is_enable(spdif_id)); @@ -626,7 +635,8 @@ void spdifout_play_with_zerodata(unsigned int spdif_id) #endif /* spdif ctrl */ - spdifout_fifo_ctrl(spdif_id, frddr_index, bitwidth); + spdifout_fifo_ctrl(spdif_id, + frddr_index, bitwidth, runtime.channels); /* channel status info */ spdif_get_channel_status_info(&chsts, sample_rate); @@ -645,7 +655,7 @@ void spdifout_play_with_zerodata(unsigned int spdif_id) void spdifout_play_with_zerodata_free(unsigned int spdif_id) { - pr_info("%s, spdif id:%d\n", + pr_debug("%s, spdif id:%d\n", __func__, spdif_id); diff --git a/sound/soc/amlogic/auge/spdif_hw.h b/sound/soc/amlogic/auge/spdif_hw.h index 51d5e0b52fff..3e133f620fba 100644 --- a/sound/soc/amlogic/auge/spdif_hw.h +++ b/sound/soc/amlogic/auge/spdif_hw.h @@ -74,7 +74,7 @@ extern void aml_spdifout_get_aed_info(int spdifout_id, extern void spdifout_to_hdmitx_ctrl(int spdif_index); extern void spdifout_samesource_set(int spdif_index, int fifo_id, - int bitwidth, bool is_enable); + int bitwidth, int channels, bool is_enable); extern void spdifout_enable(int spdif_id, bool is_enable); extern int spdifin_get_sample_rate(void); @@ -88,4 +88,5 @@ extern void spdif_set_channel_status_info( extern void spdifout_play_with_zerodata(unsigned int spdif_id); extern void spdifout_play_with_zerodata_free(unsigned int spdif_id); +extern void spdifin_set_src(int src); #endif diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index fb3ef019b050..f227be4751dd 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -14,7 +14,7 @@ * more details. * */ - +#define DEBUG #include #include #include @@ -38,10 +38,11 @@ #include "ddr_mngr.h" #include "tdm_hw.h" +#include "sharebuffer.h" +#include "vad.h" /*#define __PTM_TDM_CLK__*/ -#include "sharebuffer.h" #define DRV_NAME "aml_tdm" @@ -55,22 +56,22 @@ static void dump_pcm_setting(struct pcm_setting *setting) if (setting == NULL) return; - pr_info("dump_pcm_setting(%p)\n", setting); - pr_info("\tpcm_mode(%d)\n", setting->pcm_mode); - pr_info("\tsysclk(%d)\n", setting->sysclk); - pr_info("\tsysclk_bclk_ratio(%d)\n", setting->sysclk_bclk_ratio); - pr_info("\tbclk(%d)\n", setting->bclk); - pr_info("\tbclk_lrclk_ratio(%d)\n", setting->bclk_lrclk_ratio); - pr_info("\tlrclk(%d)\n", setting->lrclk); - pr_info("\ttx_mask(%#x)\n", setting->tx_mask); - pr_info("\trx_mask(%#x)\n", setting->rx_mask); - pr_info("\tslots(%d)\n", setting->slots); - pr_info("\tslot_width(%d)\n", setting->slot_width); - pr_info("\tlane_mask_in(%#x)\n", setting->lane_mask_in); - pr_info("\tlane_mask_out(%#x)\n", setting->lane_mask_out); - pr_info("\tlane_oe_mask_in(%#x)\n", setting->lane_oe_mask_in); - pr_info("\tlane_oe_mask_out(%#x)\n", setting->lane_oe_mask_out); - pr_info("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in); + pr_debug("dump_pcm_setting(%p)\n", setting); + pr_debug("\tpcm_mode(%d)\n", setting->pcm_mode); + pr_debug("\tsysclk(%d)\n", setting->sysclk); + pr_debug("\tsysclk_bclk_ratio(%d)\n", setting->sysclk_bclk_ratio); + pr_debug("\tbclk(%d)\n", setting->bclk); + pr_debug("\tbclk_lrclk_ratio(%d)\n", setting->bclk_lrclk_ratio); + pr_debug("\tlrclk(%d)\n", setting->lrclk); + pr_debug("\ttx_mask(%#x)\n", setting->tx_mask); + pr_debug("\trx_mask(%#x)\n", setting->rx_mask); + pr_debug("\tslots(%d)\n", setting->slots); + pr_debug("\tslot_width(%d)\n", setting->slot_width); + pr_debug("\tlane_mask_in(%#x)\n", setting->lane_mask_in); + pr_debug("\tlane_mask_out(%#x)\n", setting->lane_mask_out); + pr_debug("\tlane_oe_mask_in(%#x)\n", setting->lane_oe_mask_in); + pr_debug("\tlane_oe_mask_out(%#x)\n", setting->lane_oe_mask_out); + pr_debug("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in); } struct tdm_chipinfo { @@ -115,6 +116,9 @@ struct aml_tdm { /* virtual link for i2s to hdmitx */ int i2s2hdmitx; int acodec_adc; + uint last_mpll_freq; + uint last_mclk_freq; + uint last_fmt; }; static const struct snd_pcm_hardware aml_tdm_hardware = { @@ -367,33 +371,6 @@ struct snd_soc_platform_driver aml_tdm_platform = { .pcm_new = aml_tdm_new, }; -static int aml_dai_tdm_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai) -{ - struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - - ret = clk_prepare_enable(p_tdm->mclk); - if (ret) { - pr_err("Can't enable mclk: %d\n", ret); - goto err; - } - - return ret; -err: - pr_err("failed enable clock\n"); - return ret; -} - -static void aml_dai_tdm_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai) -{ - struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - - /* disable clock and gate */ - clk_disable_unprepare(p_tdm->mclk); -} - static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { @@ -403,7 +380,6 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, bit_depth = snd_pcm_format_width(runtime->format); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { struct frddr *fr = p_tdm->fddr; enum frddr_dest dst; @@ -448,7 +424,9 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, p_tdm->id); return -EINVAL; } - aml_frddr_set_format(fr, bit_depth - 1, + aml_frddr_set_format(fr, + runtime->channels, + bit_depth - 1, tdmout_get_frddr_type(bit_depth)); aml_frddr_select_dst(fr, dst); aml_frddr_set_fifos(fr, 0x40, 0x20); @@ -459,6 +437,10 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, unsigned int toddr_type; struct toddr_fmt fmt; + if (vad_tdm_is_running(p_tdm->id) + && pm_audio_is_suspend()) + return 0; + switch (bit_depth) { case 8: case 16: @@ -542,6 +524,16 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && vad_tdm_is_running(p_tdm->id) + && pm_audio_is_suspend()) { + pm_audio_set_suspend(false); + /* VAD switch to alsa buffer */ + vad_update_buffer(0); + break; + } + /* reset fifo here. * If not, xrun will cause channel mapping mismatch */ @@ -561,6 +553,14 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && vad_tdm_is_running(p_tdm->id) + && pm_audio_is_suspend()) { + /* switch to VAD buffer */ + vad_update_buffer(1); + break; + } + aml_tdm_enable(p_tdm->actrl, substream->stream, p_tdm->id, false); @@ -727,6 +727,11 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, return ret; } + /* Must enabe channel number for VAD */ + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && (vad_tdm_is_running(p_tdm->id))) + tdmin_set_chnum_en(p_tdm->actrl, p_tdm->id, true); + /* share buffer trigger */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && p_tdm->chipinfo @@ -744,6 +749,15 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, rate * ratio * mux); } + if (!p_tdm->contns_clk && !IS_ERR(p_tdm->mclk)) { + pr_debug("%s(), enable mclk for %s", __func__, cpu_dai->name); + ret = clk_prepare_enable(p_tdm->mclk); + if (ret) { + pr_err("Can't enable mclk: %d\n", ret); + return ret; + } + } + return 0; } @@ -758,6 +772,11 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream, aml_tdm_set_channel_mask(p_tdm->actrl, substream->stream, p_tdm->id, i, 0); + /* Disable channel number for VAD */ + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && (vad_tdm_is_running(p_tdm->id))) + tdmin_set_chnum_en(p_tdm->actrl, p_tdm->id, false); + /* share buffer free */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && p_tdm->chipinfo @@ -769,6 +788,12 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream, fr, p_tdm->samesource_sel); } + /* disable clock and gate */ + if (!p_tdm->contns_clk && !IS_ERR(p_tdm->mclk)) { + pr_info("%s(), disable mclk for %s", __func__, cpu_dai->name); + clk_disable_unprepare(p_tdm->mclk); + } + return 0; } @@ -776,8 +801,14 @@ static int aml_dai_set_tdm_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - pr_info("asoc aml_dai_set_tdm_fmt, %#x, %p, id(%d), clksel(%d)\n", + pr_debug("asoc aml_dai_set_tdm_fmt, %#x, %p, id(%d), clksel(%d)\n", fmt, p_tdm, p_tdm->id, p_tdm->clk_sel); + if (p_tdm->last_fmt == fmt) { + pr_debug("%s(), fmt not change\n", __func__); + goto capture; + } else + p_tdm->last_fmt = fmt; + switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { case SND_SOC_DAIFMT_CONT: p_tdm->contns_clk = true; @@ -794,9 +825,9 @@ static int aml_dai_set_tdm_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) aml_tdm_set_format(p_tdm->actrl, &(p_tdm->setting), p_tdm->clk_sel, p_tdm->id, fmt, - cpu_dai->capture_active, - cpu_dai->playback_active); + 1, 1); +capture: /* update skew for ACODEC_ADC */ if (cpu_dai->capture_active && p_tdm->chipinfo @@ -832,6 +863,7 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai, { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); unsigned int ratio = aml_mpll_mclk_ratio(freq); + unsigned int mpll_freq = 0; p_tdm->setting.sysclk = freq; @@ -844,10 +876,22 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai, ratio = 20; #endif - clk_set_rate(p_tdm->clk, freq * ratio); - clk_set_rate(p_tdm->mclk, freq); + mpll_freq = freq * ratio; + if (mpll_freq != p_tdm->last_mpll_freq) { + clk_set_rate(p_tdm->clk, mpll_freq); + p_tdm->last_mpll_freq = mpll_freq; + } else { + pr_debug("%s(), mpll no change, keep clk\n", __func__); + } - pr_info("set mclk:%d, mpll:%d, get mclk:%lu, mpll:%lu\n", + if (freq != p_tdm->last_mclk_freq) { + clk_set_rate(p_tdm->mclk, freq); + p_tdm->last_mclk_freq = freq; + } else { + pr_debug("%s(), mclk no change, keep clk\n", __func__); + } + + pr_debug("set mclk:%d, mpll:%d, get mclk:%lu, mpll:%lu\n", freq, freq * ratio, clk_get_rate(p_tdm->mclk), @@ -868,10 +912,10 @@ static int aml_dai_set_bclk_ratio(struct snd_soc_dai *cpu_dai, if (p_tdm->setting.pcm_mode == SND_SOC_DAIFMT_I2S || p_tdm->setting.pcm_mode == SND_SOC_DAIFMT_LEFT_J) { - pr_info("aml_dai_set_bclk_ratio, select I2S mode\n"); + pr_debug("aml_dai_set_bclk_ratio, select I2S mode\n"); lrclk_hi = bclk_ratio / 2; } else { - pr_info("aml_dai_set_bclk_ratio, select TDM mode\n"); + pr_debug("aml_dai_set_bclk_ratio, select TDM mode\n"); } aml_tdm_set_bclk_ratio(p_tdm->actrl, p_tdm->clk_sel, lrclk_hi, bclk_ratio); @@ -914,15 +958,15 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, lanes_oe_in_cnt = pop_count(p_tdm->setting.lane_oe_mask_in); lanes_lb_cnt = pop_count(p_tdm->setting.lane_lb_mask_in); - pr_info("%s(), txmask(%#x), rxmask(%#x)\n", + pr_debug("%s(), txmask(%#x), rxmask(%#x)\n", __func__, tx_mask, rx_mask); - pr_info("\tlanes_out_cnt(%d), lanes_in_cnt(%d)\n", + pr_debug("\tlanes_out_cnt(%d), lanes_in_cnt(%d)\n", lanes_out_cnt, lanes_in_cnt); - pr_info("\tlanes_oe_out_cnt(%d), lanes_oe_in_cnt(%d)\n", + pr_debug("\tlanes_oe_out_cnt(%d), lanes_oe_in_cnt(%d)\n", lanes_oe_out_cnt, lanes_oe_in_cnt); - pr_info("\tlanes_lb_cnt(%d)\n", + pr_debug("\tlanes_lb_cnt(%d)\n", lanes_lb_cnt); - pr_info("\tslots(%d), slot_width(%d)\n", + pr_debug("\tslots(%d), slot_width(%d)\n", slots, slot_width); p_tdm->setting.tx_mask = tx_mask; p_tdm->setting.rx_mask = rx_mask; @@ -971,7 +1015,7 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, } else { if (lanes_lb_cnt) in_src = p_tdm->id + 3; - if (lanes_in_cnt && lanes_in_cnt <= 3) + if (lanes_in_cnt && lanes_in_cnt <= 4) in_src = p_tdm->id; if (in_src > 5) { pr_err("unknown src(%d) for tdmin\n", in_src); @@ -1020,9 +1064,22 @@ static int aml_dai_tdm_remove(struct snd_soc_dai *cpu_dai) return 0; } +static int aml_dai_tdm_mute_stream(struct snd_soc_dai *cpu_dai, + int mute, int stream) +{ + struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + pr_debug("tdm playback mute: %d\n", mute); + aml_tdm_mute_playback(p_tdm->actrl, p_tdm->id, mute); + } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { + pr_debug("tdm capture mute: %d\n", mute); + aml_tdm_mute_capture(p_tdm->actrl, p_tdm->id, mute); + } + return 0; +} + static struct snd_soc_dai_ops aml_dai_tdm_ops = { - .startup = aml_dai_tdm_startup, - .shutdown = aml_dai_tdm_shutdown, .prepare = aml_dai_tdm_prepare, .trigger = aml_dai_tdm_trigger, .hw_params = aml_dai_tdm_hw_params, @@ -1032,6 +1089,7 @@ static struct snd_soc_dai_ops aml_dai_tdm_ops = { .set_bclk_ratio = aml_dai_set_bclk_ratio, .set_clkdiv = aml_dai_set_clkdiv, .set_tdm_slot = aml_dai_set_tdm_slot, + .mute_stream = aml_dai_tdm_mute_stream, }; #define AML_DAI_TDM_RATES (SNDRV_PCM_RATE_8000_384000) diff --git a/sound/soc/amlogic/auge/tdm_hw.c b/sound/soc/amlogic/auge/tdm_hw.c index c167b448480d..f8f89bc40264 100644 --- a/sound/soc/amlogic/auge/tdm_hw.c +++ b/sound/soc/amlogic/auge/tdm_hw.c @@ -188,6 +188,72 @@ void aml_tdm_fifo_ctrl( } +static void aml_clk_set_tdmout_by_id( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + unsigned int sclk_sel, + unsigned int lrclk_sel, + bool sclk_ws_inv, + bool is_master, + bool binv) +{ + unsigned int val_sclk_ws_inv = 0; + unsigned int reg = EE_AUDIO_CLK_TDMOUT_A_CTRL + tdm_index; + + /* This is just a copy from previous setting. WHY??? */ + val_sclk_ws_inv = sclk_ws_inv && is_master; + if (val_sclk_ws_inv) + aml_audiobus_update_bits(actrl, reg, + 0x3<<30|1<<28|0xf<<24|0xf<<20, + 0x3<<30|val_sclk_ws_inv<<28| + sclk_sel<<24|lrclk_sel<<20); + else + aml_audiobus_update_bits(actrl, reg, + 0x3<<30|1<<29|0xf<<24|0xf<<20, + 0x3<<30|binv<<29| + sclk_sel<<24|lrclk_sel<<20); +} + +static void aml_clk_set_tdmin_by_id( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + unsigned int sclk_sel, + unsigned int lrclk_sel) +{ + unsigned int reg = + EE_AUDIO_CLK_TDMIN_A_CTRL + tdm_index; + aml_audiobus_update_bits(actrl, + reg, + 0xff<<20, + sclk_sel<<24|lrclk_sel<<20); +} + +static void aml_tdmout_invert_lrclk( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + bool finv) +{ + unsigned int off_set = + EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1; + unsigned int reg_out = + EE_AUDIO_TDMOUT_A_CTRL1 + off_set * tdm_index; + aml_audiobus_update_bits(actrl, + reg_out, 0x1<<28, finv<<28); +} + +static void aml_tdmout_bclk_skew( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + unsigned int bclkout_skew) +{ + unsigned int off_set = + EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0; + unsigned int reg_out = + EE_AUDIO_TDMOUT_A_CTRL0 + off_set * tdm_index; + aml_audiobus_update_bits(actrl, + reg_out, 0x1f<<15, bclkout_skew<<15); +} + void aml_tdm_set_format( struct aml_audio_controller *actrl, struct pcm_setting *p_config, @@ -223,24 +289,7 @@ void aml_tdm_set_format( default: return; } - - //TODO: clk tree - reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id; - reg_in = EE_AUDIO_CLK_TDMIN_A_CTRL + id; - aml_audiobus_update_bits(actrl, - reg_out, - 0xff<<20, - valb<<24|valf<<20); - aml_audiobus_update_bits(actrl, - reg_in, - 0xff<<20, - valb<<24|valf<<20); - - if (p_config->sclk_ws_inv) - aml_audiobus_update_bits(actrl, - reg_out, - 1 << 28, - 0 << 28); + aml_clk_set_tdmin_by_id(actrl, id, valb, valf); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: @@ -355,27 +404,11 @@ void aml_tdm_set_format( /* TDM out */ if (playback_active) { - - reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id; - aml_audiobus_update_bits(actrl, reg_out, - 0x3<<30, 0x3<<30); - - if (p_config->sclk_ws_inv && master_mode) - aml_audiobus_update_bits(actrl, reg_out, - 0x1 << 28, - 0x1 << 28); - else - aml_audiobus_update_bits(actrl, reg_out, - 0x1<<29, binv<<29); - - off_set = EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1; - reg_out = EE_AUDIO_TDMOUT_A_CTRL1 + off_set * id; - aml_audiobus_update_bits(actrl, reg_out, 0x1<<28, finv<<28); - - off_set = EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0; - reg_out = EE_AUDIO_TDMOUT_A_CTRL0 + off_set * id; - aml_audiobus_update_bits(actrl, reg_out, - 0x1f<<15, bclkout_skew<<15); + aml_clk_set_tdmout_by_id(actrl, + id, valb, valf, + p_config->sclk_ws_inv, master_mode, binv); + aml_tdmout_invert_lrclk(actrl, id, finv); + aml_tdmout_bclk_skew(actrl, id, bclkout_skew); } /* TDM in */ @@ -492,6 +525,19 @@ void aml_update_tdmin_src( 0xf << 20, in_src << 20); } +void tdmin_set_chnum_en( + struct aml_audio_controller *actrl, + int index, bool enable) +{ + unsigned int reg, offset; + + offset = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL; + reg = EE_AUDIO_TDMIN_A_CTRL + offset * index; + + aml_audiobus_update_bits(actrl, reg, + 0x1 << 6, enable << 6); +} + void aml_tdm_set_channel_mask( struct aml_audio_controller *actrl, int stream, int index, int lane, int mask) @@ -647,3 +693,44 @@ void i2s_to_hdmitx_ctrl(int tdm_index) | tdm_index << 4 /* Bclk_sel */ ); } + +void aml_tdm_mute_playback( + struct aml_audio_controller *actrl, + int tdm_index, + bool mute) +{ + unsigned int offset, reg; + unsigned int mute_mask = 0xffffffff; + unsigned int mute_val = 0; + int i = 0, lanes = 4; + + if (mute) + mute_val = 0xffffffff; + + offset = EE_AUDIO_TDMOUT_B_MUTE0 + - EE_AUDIO_TDMOUT_A_MUTE0; + reg = EE_AUDIO_TDMOUT_A_MUTE0 + offset * tdm_index; + for (i = 0; i < lanes; i++) + aml_audiobus_update_bits(actrl, reg + i, mute_mask, mute_val); +} + +void aml_tdm_mute_capture( + struct aml_audio_controller *actrl, + int tdm_index, + bool mute) +{ + unsigned int offset, reg; + unsigned int mute_mask = 0xffffffff; + unsigned int mute_val = 0; + int i = 0, lanes = 4; + + if (mute) + mute_val = 0xffffffff; + + offset = EE_AUDIO_TDMIN_B_MUTE0 + - EE_AUDIO_TDMIN_A_MUTE0; + reg = EE_AUDIO_TDMIN_A_MUTE0 + offset * tdm_index; + for (i = 0; i < lanes; i++) + aml_audiobus_update_bits(actrl, reg + i, mute_mask, mute_val); +} + diff --git a/sound/soc/amlogic/auge/tdm_hw.h b/sound/soc/amlogic/auge/tdm_hw.h index 7e47302aba75..85fe6303434f 100644 --- a/sound/soc/amlogic/auge/tdm_hw.h +++ b/sound/soc/amlogic/auge/tdm_hw.h @@ -107,6 +107,10 @@ extern void aml_update_tdmin_src( struct aml_audio_controller *actrl, int index, int in_src); +extern void tdmin_set_chnum_en( + struct aml_audio_controller *actrl, + int index, bool enable); + extern void aml_tdm_set_channel_mask( struct aml_audio_controller *actrl, int stream, int index, int lanes, int mask); @@ -138,4 +142,12 @@ extern void aml_tdm_clk_pad_select( int tdm_index, int clk_sel); extern void i2s_to_hdmitx_ctrl(int tdm_index); +void aml_tdm_mute_playback( + struct aml_audio_controller *actrl, + int index, + bool mute); +void aml_tdm_mute_capture( + struct aml_audio_controller *actrl, + int tdm_index, + bool mute); #endif diff --git a/sound/soc/amlogic/auge/vad.c b/sound/soc/amlogic/auge/vad.c new file mode 100644 index 000000000000..6738fdf63b97 --- /dev/null +++ b/sound/soc/amlogic/auge/vad.c @@ -0,0 +1,786 @@ +/* + * sound/soc/amlogic/auge/vad.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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. + */ +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "vad_hw_coeff.c" +#include "vad_hw.h" +#include "vad.h" + +#define DRV_NAME "VAD" + +#define DMA_BUFFER_BYTES_MAX (2 * 1024 * 1024) + +enum vad_level { + LEVEL_USER, + LEVEL_KERNEL, +}; + +struct vad { + struct aml_audio_controller *actrl; + struct device *dev; + + struct clk *gate; + struct clk *pll; + struct clk *clk; + + struct toddr *tddr; + + struct tasklet_struct tasklet; + + struct snd_dma_buffer dma_buffer; + unsigned int start_last; + unsigned int end_last; + unsigned int addr; + + int switch_buffer; + + /* vad flag interrupt */ + int irq_wakeup; + /* frame sync interrupt */ + int irq_fs; + /* data source select + * Data src sel: + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + * 5: loopback_b; + * 6: tdmin_lb; + * 7: loopback_a; + */ + int src; + /* Enable */ + int en; + + /* user space or kernel space to check hot word + * 1: check hot word in kernel + * 0: check hot word in user space + */ + enum vad_level level; +}; + +static struct vad *s_vad; + +static struct vad *get_vad(void) +{ + struct vad *p_vad; + + p_vad = s_vad; + + if (!p_vad) { + pr_debug("Not init vad\n"); + return NULL; + } + + return p_vad; +} + +static bool vad_is_enable(void) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad) + return false; + + return p_vad->en; +} + +static bool vad_src_check(enum vad_src src) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad) + return false; + + if (p_vad->src == src) + return true; + + return false; +} + +bool vad_tdm_is_running(int tdm_idx) +{ + enum vad_src src; + + if (tdm_idx > 2) + return false; + + src = (enum vad_src)tdm_idx; + + if (vad_is_enable() && vad_src_check(src)) + return true; + + return false; +} + +bool vad_pdm_is_running(void) +{ + if (vad_is_enable() && vad_src_check(VAD_SRC_PDMIN)) + return true; + + return false; +} + +static void vad_notify_user_space(struct device *dev) +{ + pr_info("Notify to wake up user space\n"); + + pm_wakeup_event(dev, 2000); +} + +static int vad_engine_check(void) +{ + return 1; +} + +/* Check buffer in kernel for VAD */ +static void vad_transfer_buffer_output(struct vad *p_vad) +{ + + for (;;) { + if (vad_engine_check()) { + vad_notify_user_space(p_vad->dev); + break; + } + } +} + +static void vad_tasklet(unsigned long data) +{ + struct vad *p_vad = (struct vad *)data; + + vad_transfer_buffer_output(p_vad); +} + +static irqreturn_t vad_wakeup_isr(int irq, void *data) +{ + struct vad *p_vad = (struct vad *)data; + + pr_info("%s\n", __func__); + + if (p_vad->level == LEVEL_KERNEL) + tasklet_schedule(&p_vad->tasklet); + + return IRQ_HANDLED; +} + +static irqreturn_t vad_fs_isr(int irq, void *data) +{ + return IRQ_HANDLED; +} + +static int vad_set_clks(struct vad *p_vad, bool enable) +{ + if (enable) { + int ret = 0; + + /* enable clock gate */ + ret = clk_prepare_enable(p_vad->gate); + + /* enable clock */ + ret = clk_prepare_enable(p_vad->pll); + if (ret) { + pr_err("Can't enable vad pll: %d\n", ret); + return -EINVAL; + } + + clk_set_rate(p_vad->clk, 25000000); + ret = clk_prepare_enable(p_vad->clk); + if (ret) { + pr_err("Can't enable vad clk: %d\n", ret); + return -EINVAL; + } + } else { + /* disable clock and gate */ + clk_disable_unprepare(p_vad->clk); + clk_disable_unprepare(p_vad->pll); + clk_disable_unprepare(p_vad->gate); + } + + return 0; +} + +static int vad_init(struct vad *p_vad) +{ + int ret = 0, flag = 0; + + /* malloc buffer */ + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + p_vad->dev, + DMA_BUFFER_BYTES_MAX, + &p_vad->dma_buffer); + if (ret) { + dev_err(p_vad->dev, "Cannot allocate buffer(s)\n"); + return ret; + } + + /* register irq */ + if (p_vad->level == LEVEL_KERNEL) { + flag = IRQF_SHARED | IRQF_NO_SUSPEND; + + tasklet_init(&p_vad->tasklet, vad_tasklet, + (unsigned long)p_vad); + + } else if (p_vad->level == LEVEL_USER) + flag = IRQF_SHARED; + + ret = request_irq(p_vad->irq_wakeup, + vad_wakeup_isr, flag, "vad_wakeup", + p_vad); + if (ret) { + dev_err(p_vad->dev, "failed to claim irq_wakeup %u\n", + p_vad->irq_wakeup); + return -ENXIO; + } + + ret = request_irq(p_vad->irq_fs, + vad_fs_isr, 0, "vad_fs", + p_vad); + if (ret) { + dev_err(p_vad->dev, "failed to claim irq_fs %u\n", + p_vad->irq_fs); + return -ENXIO; + } + + /* clock ready */ + vad_set_clks(p_vad, true); + + return ret; +} + +static void vad_deinit(struct vad *p_vad) +{ + if (p_vad->level == LEVEL_KERNEL) + tasklet_kill(&p_vad->tasklet); + + /* free irq */ + free_irq(p_vad->irq_wakeup, p_vad); + free_irq(p_vad->irq_fs, p_vad); + + /* free buffer */ + snd_dma_free_pages(&p_vad->dma_buffer); + + /* clock disabled */ + vad_set_clks(p_vad, false); +} + +void vad_update_buffer(int isvad) +{ + struct vad *p_vad = get_vad(); + unsigned int start, end, addr; + unsigned int rd_th; + + if (!p_vad || !p_vad->en || !p_vad->tddr) + return; + + addr = aml_toddr_get_position(p_vad->tddr); + + if (isvad) { /* switch to vad buffer */ + struct toddr *tddr = p_vad->tddr; + + p_vad->start_last = tddr->start_addr; + p_vad->end_last = tddr->end_addr; + + rd_th = 0x100; + + pr_debug("Switch to VAD buffer\n"); + pr_debug("\t ASAL start:%d, end:%d, bytes:%d, current:%d\n", + tddr->start_addr, tddr->end_addr, + tddr->end_addr - tddr->start_addr, addr); + + start = p_vad->dma_buffer.addr; + end = start + p_vad->dma_buffer.bytes - 8; + + pr_debug("\t VAD start:%d, end:%d, bytes:%d\n", + start, end, + end - start); + } else { + pr_debug("Switch to ALSA buffer\n"); + + //addr = aml_toddr_get_addr(p_vad->tddr, VAD_WAKEUP_ADDR); + addr = aml_toddr_get_position(p_vad->tddr); + + start = p_vad->start_last; + end = p_vad->end_last; + + rd_th = 0x40; + + vad_set_trunk_data_readable(true); + } + + p_vad->addr = addr; + aml_toddr_set_buf(p_vad->tddr, start, end); + aml_toddr_force_finish(p_vad->tddr); + aml_toddr_update_fifos_rd_th(p_vad->tddr, rd_th); +} + +int vad_transfer_chunk_data(unsigned long data, int frames) +{ + struct vad *p_vad = get_vad(); + char __user *buf = (char __user *)data; + unsigned char *hwbuf; + int bytes; + int start, end, addr, size; + int chnum, bytes_per_sample; + + if (!buf || !p_vad || !p_vad->en || !p_vad->tddr) + return 0; + + size = p_vad->dma_buffer.bytes; + start = p_vad->dma_buffer.addr; + end = start + size - 8; + addr = p_vad->addr; + hwbuf = p_vad->dma_buffer.area; + + if (addr < start || addr > end) + return 0; + + chnum = p_vad->tddr->channels; + /* bytes for each sample */ + bytes_per_sample = p_vad->tddr->bitdepth >> 3; + + bytes = frames * chnum * bytes_per_sample < size ? + frames * chnum * bytes_per_sample : size; + + pr_debug("%s dma bytes:%d, wanted bytes:%d, actual bytes:%d\n", + __func__, + size, + frames * chnum * bytes_per_sample, + bytes); + + pr_debug("%s dma bytes:%d, start:%d, end:%d, current:%d\n", + __func__, + size, + start, + end, + addr); + + if (addr - start >= bytes) { + if (copy_to_user(buf, + hwbuf + addr - bytes - start, + bytes)) + return 0; + } else { + int tmp_bytes = bytes - (addr - start); + int tmp_offset = (end - tmp_bytes) - start; + + if (copy_to_user(buf, + hwbuf + tmp_offset, + tmp_bytes)) + return 0; + + if (copy_to_user(buf + tmp_bytes, + hwbuf, + addr - start)) + return 0; + } + + /* After data copied, reset dma buffer */ + memset(hwbuf, 0x0, size); + + return bytes / (chnum * bytes_per_sample); +} + +void vad_set_toddr_info(struct toddr *to) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad || !p_vad->en) + return; + + pr_debug("%s update vad toddr:%p\n", __func__, to); + + p_vad->tddr = to; +} + +void vad_enable(bool enable) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad || !p_vad->en) + return; + + /* Force VAD enable to set parameters */ + if (enable) { + int *p_de_coeff = vad_de_coeff; + int len_de = ARRAY_SIZE(vad_de_coeff); + int *p_win_coeff = vad_ram_coeff; + int len_ram = ARRAY_SIZE(vad_ram_coeff); + + vad_set_enable(true); + vad_set_ram_coeff(len_ram, p_win_coeff); + vad_set_de_params(len_de, p_de_coeff); + vad_set_pwd(); + vad_set_cep(); + vad_set_src(p_vad->src); + vad_set_in(); + + /* reset then enable VAD */ + vad_set_enable(false); + } + vad_set_enable(enable); +} + +static int vad_get_enable_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + ucontrol->value.integer.value[0] = p_vad->en; + + return 0; +} + +static int vad_set_enable_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + p_vad->en = ucontrol->value.integer.value[0]; + + if (p_vad->en) { + vad_init(p_vad); + + aml_set_vad(p_vad->en, p_vad->src); + } else { + aml_set_vad(p_vad->en, p_vad->src); + + vad_deinit(p_vad); + } + + return 0; +} + + +static const char *const vad_src_txt[] = { + "TDMIN_A", + "TDMIN_B", + "TDMIN_C", + "SPDIFIN", + "PDMIN", + "LOOPBACK_B", + "TDMIN_LB", + "LOOPBACK_A", +}; + +const struct soc_enum vad_src_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(vad_src_txt), + vad_src_txt); + +static int vad_get_src_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + ucontrol->value.integer.value[0] = p_vad->src; + + return 0; +} + +static int vad_set_src_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + p_vad->src = ucontrol->value.integer.value[0]; + + if (p_vad->en) + aml_set_vad(p_vad->en, p_vad->src); + + return 0; +} + +static int vad_get_switch_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + ucontrol->value.integer.value[0] = p_vad->switch_buffer; + + return 0; +} + +static int vad_set_switch_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + p_vad->switch_buffer = ucontrol->value.integer.value[0]; + + if (p_vad->en) + vad_update_buffer(p_vad->switch_buffer); + + return 0; +} + +static const struct snd_kcontrol_new vad_controls[] = { + SOC_SINGLE_BOOL_EXT("VAD enable", + 0, + vad_get_enable_enum, + vad_set_enable_enum), + + SOC_ENUM_EXT("VAD Source sel", + vad_src_enum, + vad_get_src_enum, + vad_set_src_enum), + + SOC_SINGLE_BOOL_EXT("VAD Switch", + 0, + vad_get_switch_enum, + vad_set_switch_enum), + +}; + +int card_add_vad_kcontrols(struct snd_soc_card *card) +{ + unsigned int idx; + int err; + + struct vad *p_vad = get_vad(); + + if (!p_vad) + return -ENODEV; + + for (idx = 0; idx < ARRAY_SIZE(vad_controls); idx++) { + err = snd_ctl_add(card->snd_card, + snd_ctl_new1(&vad_controls[idx], + p_vad)); + if (err < 0) + return err; + } + + return 0; +} + +static const struct of_device_id vad_device_id[] = { + { + .compatible = "amlogic, snd-vad", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, vad_device_id); + +static int vad_platform_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct device_node *node_prt = NULL; + struct platform_device *pdev_parent; + struct device *dev = &pdev->dev; + struct aml_audio_controller *actrl = NULL; + struct vad *p_vad = NULL; + int ret = 0; + + p_vad = devm_kzalloc(&pdev->dev, sizeof(struct vad), GFP_KERNEL); + if (!p_vad) + return -ENOMEM; + + p_vad->dev = dev; + dev_set_drvdata(dev, p_vad); + + /* get audio controller */ + node_prt = of_get_parent(node); + if (node_prt == NULL) + return -ENXIO; + + pdev_parent = of_find_device_by_node(node_prt); + of_node_put(node_prt); + actrl = (struct aml_audio_controller *) + platform_get_drvdata(pdev_parent); + p_vad->actrl = actrl; + + /* clock */ + p_vad->gate = devm_clk_get(&pdev->dev, "gate"); + if (IS_ERR(p_vad->gate)) { + dev_err(&pdev->dev, + "Can't get vad clock gate\n"); + return PTR_ERR(p_vad->gate); + } + p_vad->pll = devm_clk_get(&pdev->dev, "pll"); + if (IS_ERR(p_vad->pll)) { + dev_err(&pdev->dev, + "Can't retrieve vad pll clock\n"); + return PTR_ERR(p_vad->pll); + } + p_vad->clk = devm_clk_get(&pdev->dev, "clk"); + if (IS_ERR(p_vad->clk)) { + dev_err(&pdev->dev, + "Can't retrieve vad clock\n"); + return PTR_ERR(p_vad->clk); + } + ret = clk_set_parent(p_vad->clk, p_vad->pll); + if (ret) { + dev_err(&pdev->dev, + "Can't set p_vad->clk parent clock\n"); + return PTR_ERR(p_vad->clk); + } + + /* irqs */ + p_vad->irq_wakeup = platform_get_irq_byname(pdev, "irq_wakeup"); + if (p_vad->irq_wakeup < 0) { + dev_err(dev, "Failed to get irq_wakeup:%d\n", + p_vad->irq_wakeup); + return -ENXIO; + } + p_vad->irq_fs = platform_get_irq_byname(pdev, "irq_frame_sync"); + if (p_vad->irq_fs < 0) { + dev_err(dev, "Failed to get irq_frame_sync:%d\n", + p_vad->irq_fs); + return -ENXIO; + } + + /* data source select */ + ret = of_property_read_u32(node, "src", + &p_vad->src); + if (ret < 0) { + dev_err(dev, "Failed to get vad data src select:%d\n", + p_vad->src); + return -EINVAL; + } + /* to deal with hot word in user space or kernel space */ + ret = of_property_read_u32(node, "level", + &p_vad->level); + if (ret < 0) { + dev_info(dev, + "Failed to get vad level, default in user space\n"); + p_vad->level = 0; + } + + pr_info("%s vad data source sel:%d, level:%d\n", + __func__, + p_vad->src, + p_vad->level); + + s_vad = p_vad; + + device_init_wakeup(dev, 1); + + return 0; +} + +int vad_platform_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct device *dev = &pdev->dev; + struct vad *p_vad = dev_get_drvdata(dev); + + pr_info("%s\n", __func__); + + /* whether in freeze */ + if (is_pm_freeze_mode() + && vad_is_enable()) { + pr_info("%s, Entry in freeze\n", __func__); + + if (p_vad->level == LEVEL_USER) + dev_pm_set_wake_irq(dev, p_vad->irq_wakeup); + } + + return 0; +} + +int vad_platform_resume(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct vad *p_vad = dev_get_drvdata(dev); + + pr_info("%s\n", __func__); + + /* whether in freeze mode */ + if (is_pm_freeze_mode() + && vad_is_enable()) { + pr_info("%s, Exist from freeze\n", __func__); + + if (p_vad->level == LEVEL_USER) + dev_pm_clear_wake_irq(dev); + } + + return 0; +} + +struct platform_driver vad_driver = { + .driver = { + .name = DRV_NAME, + .of_match_table = vad_device_id, + }, + .probe = vad_platform_probe, + .suspend = vad_platform_suspend, + .resume = vad_platform_resume, +}; + +module_platform_driver(vad_driver); + +MODULE_AUTHOR("Amlogic, Inc."); +MODULE_DESCRIPTION("Amlogic Voice Activity Detection ASoc driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("Platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, vad_device_id); diff --git a/sound/soc/amlogic/auge/vad.h b/sound/soc/amlogic/auge/vad.h new file mode 100644 index 000000000000..cd094682eb15 --- /dev/null +++ b/sound/soc/amlogic/auge/vad.h @@ -0,0 +1,47 @@ +/* + * sound/soc/amlogic/auge/vad.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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. + * + */ + +#ifndef __VAD_H__ +#define __VAD_H__ + +#include "ddr_mngr.h" + +enum vad_src { + VAD_SRC_TDMIN_A, + VAD_SRC_TDMIN_B, + VAD_SRC_TDMIN_C, + VAD_SRC_SPDIFIN, + VAD_SRC_PDMIN, + VAD_SRC_LOOPBACK_B, + VAD_SRC_TDMIN_LB, + VAD_SRC_LOOPBACK_A, +}; + +extern void vad_update_buffer(int isvad); +extern int vad_transfer_chunk_data(unsigned long data, int frames); + +extern bool vad_tdm_is_running(int tdm_idx); +extern bool vad_pdm_is_running(void); + +extern void vad_enable(bool enable); +extern void vad_set_toddr_info(struct toddr *to); + +extern void vad_set_trunk_data_readable(bool en); + +extern int card_add_vad_kcontrols(struct snd_soc_card *card); + +#endif diff --git a/sound/soc/amlogic/auge/vad_dev.c b/sound/soc/amlogic/auge/vad_dev.c new file mode 100644 index 000000000000..9af68606481a --- /dev/null +++ b/sound/soc/amlogic/auge/vad_dev.c @@ -0,0 +1,175 @@ +/* + * sound/soc/amlogic/auge/vad_dev.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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. + * + */ +#define DEBUG + +#include +#include +#include +#include + +#include +#include + +#include + +#include "vad.h" + +#define DRV_NAME "vad" + +#define IOCTL_READI_SUSPENDED_FRAMES _IOR('Z', 0x0, struct snd_xferi) + +static bool readable; + +bool vad_is_trunk_data_readable(void) +{ + return readable; +} + +void vad_set_trunk_data_readable(bool en) +{ + readable = en; +} + +static ssize_t readable_show(struct class *cla, struct class_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", readable); +} + +static struct class_attribute vad_attrs[] = { + __ATTR_RO(readable), + + __ATTR_NULL +}; + +static struct class vad_class = { + .name = DRV_NAME, + .class_attrs = vad_attrs, +}; + +static int vad_open(struct inode *inode, struct file *file) +{ + pr_info("%s\n", __func__); + + return 0; +} + +static long vad_unlocked_ioctl( + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + if (cmd == IOCTL_READI_SUSPENDED_FRAMES) { + struct snd_xferi xferi; + struct snd_xferi __user *_xferi = + (struct snd_xferi __user *)arg; + int result; + + if (!vad_is_trunk_data_readable()) + return 0; + + if (put_user(0, &_xferi->result)) + return 0; + if (copy_from_user(&xferi, _xferi, sizeof(xferi))) + return 0; + + result = vad_transfer_chunk_data( + (unsigned long)xferi.buf, + xferi.frames); + + __put_user(result, &_xferi->result); + + pr_debug("VAD resume trunk data, frames:%lu, result:%d\n", + xferi.frames, + result); + + /* if audio data is read, waiting for next time */ + vad_set_trunk_data_readable(false); + + return result; + } + + return -ENOTTY; +} + + +#ifdef CONFIG_COMPAT +static long vad_ioctl_compat( + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + pr_info("%s\n", __func__); + return -ENOIOCTLCMD; +} +#else +#define vad_ioctl_compat NULL +#endif + +static const struct file_operations vad_fops = { + .owner = THIS_MODULE, + .open = vad_open, + .unlocked_ioctl = vad_unlocked_ioctl, + .compat_ioctl = vad_ioctl_compat, +}; + +static int __init vad_init(void) +{ + struct device *vad_dev; + struct class *p_vad_class; + int ret = 0; + + ret = register_chrdev(VAD_MAJOR, DRV_NAME, &vad_fops); + if (ret) { + pr_err("Can't register char devie for " DRV_NAME "\n"); + goto err0; + } + + ret = class_register(&vad_class); + if (ret < 0) { + pr_err("Create vad class failed\n"); + ret = -EEXIST; + goto err1; + } + + p_vad_class = &vad_class; + vad_dev = device_create(p_vad_class, + NULL, MKDEV(VAD_MAJOR, 0), + NULL, DRV_NAME); + if (vad_dev == NULL) { + ret = -EEXIST; + goto err2; + } + + pr_info("Register %s", DRV_NAME); + + return 0; +err2: + class_destroy(p_vad_class); +err1: + unregister_chrdev(VAD_MAJOR, DRV_NAME); +err0: + return ret; +} + +static void __exit vad_exit(void) +{ + unregister_chrdev(VAD_MAJOR, DRV_NAME); +} + +module_init(vad_init); +module_exit(vad_exit); diff --git a/sound/soc/amlogic/auge/vad_hw.c b/sound/soc/amlogic/auge/vad_hw.c new file mode 100644 index 000000000000..c122dd074b39 --- /dev/null +++ b/sound/soc/amlogic/auge/vad_hw.c @@ -0,0 +1,109 @@ +/* + * sound/soc/amlogic/auge/vad_hw.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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. + */ + +#include "vad_hw.h" + + +void vad_set_ram_coeff(int len, int *params) +{ + int i, ctrl_v; + + for (i = 0; i < len; i++) { + ctrl_v = 0x1 << 31 | (i << 0); + vad_write(VAD_LUT_WR, params[i]); + vad_write(VAD_LUT_CTRL, ctrl_v); + } +} + +/* parameters for downsample and emphasis filter */ +void vad_set_de_params(int len, int *params) +{ + int i; + + for (i = 0; i < len; i++) + vad_write(VAD_FIR_CTRL + i, params[i]); +} + +/* Power detection */ +void vad_set_pwd(void) +{ + /* frame for 32 ms */ + vad_write(VAD_FRAME_CTRL0, + 0x2 << 30 | + 0x1 << 24 | + 0x1 << 16); + + vad_write(VAD_FRAME_CTRL1, 0x00000d65); + vad_write(VAD_FRAME_CTRL2, 0xd00103ff); +} + +void vad_set_cep(void) +{ + vad_write(VAD_CEP_CTRL0, 0x11050000); + vad_write(VAD_CEP_CTRL1, 0x0000001b); + vad_write(VAD_CEP_CTRL2, 0xc001fd); + vad_write(VAD_CEP_CTRL3, 0x137f0000); + vad_write(VAD_CEP_CTRL4, 0x186d0000); + vad_write(VAD_CEP_CTRL5, 0xfd00f61); + vad_write(VAD_DEC_CTRL, 0x10030001); +} + +void vad_set_src(int src) +{ + audiobus_update_bits(EE_AUDIO_TOVAD_CTRL0, + 0x7 << 12, + src << 12); +} + +void vad_set_in(void) +{ + /* two channel enable */ + vad_write(VAD_IN_SEL0, 0x00000001); + vad_write(VAD_IN_SEL1, 0x00000002); + + vad_write(VAD_TO_DDR, 0xa0000719); +} + +void vad_set_enable(bool enable) +{ + audiobus_update_bits(EE_AUDIO_TOVAD_CTRL0, + 0x1 << 31 | 0x1 << 30, + enable << 31 | 0x1 << 30); + + if (enable) { + vad_write(VAD_TOP_CTRL0, 0x7ff); + vad_write(VAD_TOP_CTRL0, 0x0); + + vad_write(VAD_TOP_CTRL1, 0xff); + vad_write(VAD_TOP_CTRL1, 0x0); + + vad_update_bits(VAD_TOP_CTRL0, + 0xfff << 20, + 1 << 31 | /* vad_en */ + 1 << 30 | /* dec_fir_en */ + 1 << 29 | /* pre_emp_en */ + 1 << 28 | /* pre_ram_en */ + 1 << 27 | /* frame_his_en */ + 1 << 23 | /* ceps_ceps_en */ + 1 << 22 | /* ceps_spec_en */ + 0 << 20 /* two_channel_en */ + ); + } else { + vad_write(VAD_TOP_CTRL0, 0x0); + + vad_write(VAD_TOP_CTRL1, 0x0); + } +} diff --git a/sound/soc/amlogic/auge/vad_hw.h b/sound/soc/amlogic/auge/vad_hw.h new file mode 100644 index 000000000000..44a1224aeabc --- /dev/null +++ b/sound/soc/amlogic/auge/vad_hw.h @@ -0,0 +1,38 @@ +/* + * sound/soc/amlogic/auge/vad_hw.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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. + * + */ +#ifndef __VAD_HW_H__ +#define __VAD_HW_H__ +#include + +#include "regs.h" +#include "iomap.h" + +extern void vad_set_ram_coeff(int len, int *params); + + +extern void vad_set_de_params(int len, int *params); + +extern void vad_set_pwd(void); + +extern void vad_set_cep(void); + +extern void vad_set_src(int src); + +extern void vad_set_in(void); + +extern void vad_set_enable(bool enable); +#endif diff --git a/sound/soc/amlogic/auge/vad_hw_coeff.c b/sound/soc/amlogic/auge/vad_hw_coeff.c new file mode 100644 index 000000000000..e521b9883375 --- /dev/null +++ b/sound/soc/amlogic/auge/vad_hw_coeff.c @@ -0,0 +1,167 @@ +/* + * sound/soc/amlogic/auge/vad_hw_coeff.c + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * 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. + * + */ + +/* parameters for downsample and emphasis filter */ +static int vad_de_coeff[] = { + 0x31007f05, + 0x000003e6, + 0x0000070c, + 0x0716071a, + 0x071207fa, + 0x07d407b1, + 0x07a907d0, + 0x0728064c, + 0x06750671, + 0x075906b1, + 0x059404b4, + 0x04be0785, + 0x044c0361, + 0x024d0263, + 0x026a0000, +}; + +static int vad_ram_coeff[] = { + 0x00003A3D, + 0x00003A42, + 0x00003A50, + 0x00003A67, + 0x00003A87, + 0x00003AB0, + 0x00003AE2, + 0x00003B1D, + 0x00003B61, + 0x00003BAF, + 0x00003C05, + 0x00003C64, + 0x00003CCC, + 0x00003D3C, + 0x00003DB5, + 0x00003E37, + 0x00003EC2, + 0x00003F55, + 0x00003FF0, + 0x0000284A, + 0x0000289F, + 0x000028F9, + 0x00002957, + 0x000029B9, + 0x00002A1F, + 0x00002A88, + 0x00002AF5, + 0x00002B66, + 0x00002BDA, + 0x00002C52, + 0x00002CCE, + 0x00002D4D, + 0x00002DCF, + 0x00002E54, + 0x00002EDC, + 0x00002F68, + 0x00002FF6, + 0x00001844, + 0x0000188E, + 0x000018D9, + 0x00001926, + 0x00001974, + 0x000019C3, + 0x00001A14, + 0x00001A65, + 0x00001AB8, + 0x00001B0C, + 0x00001B60, + 0x00001BB6, + 0x00001C0C, + 0x00001C63, + 0x00001CBB, + 0x00001D14, + 0x00001D6D, + 0x00001DC7, + 0x00001E22, + 0x00001E7C, + 0x00001ED8, + 0x00001F34, + 0x00001F90, + 0x00001FEC, + 0x00000824, + 0x00000853, + 0x00000881, + 0x000008AF, + 0x000008DE, + 0x0000090C, + 0x0000093B, + 0x00000969, + 0x00000997, + 0x000009C5, + 0x000009F3, + 0x00000A20, + 0x00000A4E, + 0x00000A7B, + 0x00000AA7, + 0x00000AD4, + 0x00000B00, + 0x00000B2C, + 0x00000B57, + 0x00000B82, + 0x00000BAD, + 0x00000BD7, + 0x00000C00, + 0x00000C29, + 0x00000C52, + 0x00000C7A, + 0x00000CA1, + 0x00000CC8, + 0x00000CEE, + 0x00000D13, + 0x00000D38, + 0x00000D5C, + 0x00000D7F, + 0x00000DA2, + 0x00000DC3, + 0x00000DE4, + 0x00000E05, + 0x00000E24, + 0x00000E42, + 0x00000E60, + 0x00000E7C, + 0x00000E98, + 0x00000EB3, + 0x00000ECD, + 0x00000EE6, + 0x00000EFE, + 0x00000F15, + 0x00000F2B, + 0x00000F40, + 0x00000F54, + 0x00000F66, + 0x00000F78, + 0x00000F89, + 0x00000F99, + 0x00000FA7, + 0x00000FB5, + 0x00000FC1, + 0x00000FCD, + 0x00000FD7, + 0x00000FE0, + 0x00000FE8, + 0x00000FEF, + 0x00000FF4, + 0x00000FF9, + 0x00000FFC, + 0x00000FFF, + 0x00000FFF +}; + diff --git a/sound/soc/amlogic/common/spdif_info.c b/sound/soc/amlogic/common/spdif_info.c index c900c5fdb675..85bd5e2bb092 100644 --- a/sound/soc/amlogic/common/spdif_info.c +++ b/sound/soc/amlogic/common/spdif_info.c @@ -14,6 +14,7 @@ * more details. * */ +#define DEBUG #undef pr_fmt #define pr_fmt(fmt) "spdif_info: " fmt @@ -111,7 +112,7 @@ void spdif_get_channel_status_info( chsts->chstat1_r = 0xe00; } } - pr_info("rate: %d, channel status ch0_l:0x%x, ch0_r:0x%x, ch1_l:0x%x, ch1_r:0x%x\n", + pr_debug("rate: %d, channel status ch0_l:0x%x, ch0_r:0x%x, ch1_l:0x%x, ch1_r:0x%x\n", rate, chsts->chstat0_l, chsts->chstat0_r, diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 218ec12314d6..35a7a500f58f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -136,6 +136,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TAS571X if I2C select SND_SOC_TAS5720 if I2C select SND_SOC_TFA9879 if I2C + select SND_SOC_TAS5805 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER select SND_SOC_TLV320AIC26 if SPI_MASTER @@ -812,6 +813,15 @@ config SND_SOC_TAS5720 Enable support for Texas Instruments TAS5720L/M high-efficiency mono Class-D audio power amplifiers. +config SND_SOC_TAS5805 + tristate "Texas Instruments TAS5805 amplifiers" + depends on I2C + help + Enable support for Texas Instruments TAS5805 + Class-D audio power amplifiers. + control by I2C + Select this if your TAS5805 is connected to I2C bus. + config SND_SOC_TFA9879 tristate "NXP Semiconductors TFA9879 amplifier" depends on I2C diff --git a/sound/soc/codecs/amlogic/Kconfig b/sound/soc/codecs/amlogic/Kconfig index ac0d8467953e..b4cd38258572 100644 --- a/sound/soc/codecs/amlogic/Kconfig +++ b/sound/soc/codecs/amlogic/Kconfig @@ -68,6 +68,17 @@ config AMLOGIC_SND_CODEC_PMU3 AML PMU3 codec, this codec is internal +config AMLOGIC_SND_SOC_TAS5805 + bool "Texas Instruments TAS5805 amplifier" + depends on AMLOGIC_SND_SOC_CODECS + depends on I2C + default n + help + Enable support for Texas Instruments TAS5805 CODEC. + Select this if your TAS5805 is connected via an I2C bus. + Enable support for Texas Instruments TAS5805 CODEC. + Select this if your TAS5805 is connected via an I2C bus. + config AMLOGIC_SND_CODEC_TXLX_ACODEC bool "Amlogic Audio txlx acodec" depends on AMLOGIC_SND_SOC_CODECS diff --git a/sound/soc/codecs/amlogic/Makefile b/sound/soc/codecs/amlogic/Makefile index 915e6461f554..e1fdb3b653d7 100644 --- a/sound/soc/codecs/amlogic/Makefile +++ b/sound/soc/codecs/amlogic/Makefile @@ -18,6 +18,7 @@ snd-soc-pcm186x-objs := pcm186x.o pcm186x-i2c.o pcm186x-spi.o snd-soc-ssm3515-objs := ssm3515.o snd-soc-ssm3525-objs := ssm3525.o snd-soc-ad82584f-objs := ad82584f.o +snd-soc-tas5805-objs := tas5805.o # Amlogic obj-$(CONFIG_AMLOGIC_SND_CODEC_DUMMY_CODEC) += snd-soc-dummy_codec.o @@ -39,3 +40,4 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_TAS575X) += tas575x.o obj-$(CONFIG_AMLOGIC_SND_SOC_ES7243) += es7243.o obj-$(CONFIG_AMLOGIC_SND_SOC_AD82584F) += ad82584f.o obj-$(CONFIG_AMLOGIC_SND_SOC_CS42528) += cs42528.o +obj-$(CONFIG_AMLOGIC_SND_SOC_TAS5805) += snd-soc-tas5805.o diff --git a/sound/soc/codecs/amlogic/ad82584f.c b/sound/soc/codecs/amlogic/ad82584f.c index b30cf815b38f..88fea3497960 100644 --- a/sound/soc/codecs/amlogic/ad82584f.c +++ b/sound/soc/codecs/amlogic/ad82584f.c @@ -36,12 +36,15 @@ static const DECLARE_TLV_DB_SCALE(mvol_tlv, -10300, 50, 1); static const DECLARE_TLV_DB_SCALE(chvol_tlv, -10300, 50, 1); static const struct snd_kcontrol_new ad82584f_snd_controls[] = { - SOC_SINGLE_TLV("Master Volume", MVOL, 0, + SOC_SINGLE_TLV("AMP Master Volume", MVOL, 0, 0xff, 1, mvol_tlv), - SOC_SINGLE_TLV("Ch1 Volume", C1VOL, 0, + SOC_SINGLE_TLV("AMP Ch1 Volume", C1VOL, 0, 0xff, 1, chvol_tlv), - SOC_SINGLE_TLV("Ch2 Volume", C2VOL, 0, + SOC_SINGLE_TLV("AMP Ch2 Volume", C2VOL, 0, 0xff, 1, chvol_tlv), + + SOC_SINGLE("AMP Ch1 Switch", MUTE, 5, 1, 1), + SOC_SINGLE("AMP Ch2 Switch", MUTE, 4, 1, 1), }; static int ad82584f_reg_init(struct snd_soc_codec *codec); @@ -52,7 +55,7 @@ static const struct reg_default ad82584f_reg_defaults[AD82584F_REGISTER_COUNT] = { {0x00, 0x00},//##State_Control_1 {0x01, 0x04},//##State_Control_2 - {0x02, 0x00},//##State_Control_3 + {0x02, 0x30},//##State_Control_3 {0x03, 0x4e},//##Master_volume_control {0x04, 0x00},//##Channel_1_volume_control {0x05, 0x00},//##Channel_2_volume_control @@ -190,7 +193,7 @@ struct reg_default ad82584f_reg_defaults[AD82584F_REGISTER_COUNT] = { static const int m_reg_tab[AD82584F_REGISTER_COUNT][2] = { {0x00, 0x00},//##State_Control_1 {0x01, 0x04},//##State_Control_2 - {0x02, 0x00},//##State_Control_3 + {0x02, 0x30},//##State_Control_3 {0x03, 0x4e},//##Master_volume_control {0x04, 0x00},//##Channel_1_volume_control {0x05, 0x00},//##Channel_2_volume_control @@ -591,6 +594,12 @@ struct ad82584f_priv { struct regmap *regmap; struct snd_soc_codec *codec; struct ad82584f_platform_data *pdata; + + unsigned char Ch1_vol; + unsigned char Ch2_vol; + unsigned char master_vol; + unsigned char mute_val; + #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend early_suspend; #endif @@ -809,7 +818,7 @@ static int ad82584f_init(struct snd_soc_codec *codec) ad82584f_set_eq_drc(codec); /*unmute,default power-on is mute.*/ - snd_soc_write(codec, 0x02, 0x00); + /*snd_soc_write(codec, 0x02, 0x00);*/ return 0; } @@ -844,8 +853,16 @@ static int ad82584f_remove(struct snd_soc_codec *codec) #ifdef CONFIG_PM static int ad82584f_suspend(struct snd_soc_codec *codec) { + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + dev_info(codec->dev, "ad82584f_suspend!\n"); + /* save volume */ + ad82584f->Ch1_vol = snd_soc_read(codec, C1VOL); + ad82584f->Ch2_vol = snd_soc_read(codec, C2VOL); + ad82584f->master_vol = snd_soc_read(codec, MVOL); + ad82584f->mute_val = snd_soc_read(codec, MUTE); + ad82584f_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -853,9 +870,17 @@ static int ad82584f_suspend(struct snd_soc_codec *codec) static int ad82584f_resume(struct snd_soc_codec *codec) { + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + dev_info(codec->dev, "ad82584f_resume!\n"); ad82584f_init(codec); + + snd_soc_write(codec, C1VOL, ad82584f->Ch1_vol); + snd_soc_write(codec, C2VOL, ad82584f->Ch2_vol); + snd_soc_write(codec, MVOL, ad82584f->master_vol); + snd_soc_write(codec, MUTE, ad82584f->mute_val); + ad82584f_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; diff --git a/sound/soc/codecs/amlogic/ad82584f.h b/sound/soc/codecs/amlogic/ad82584f.h index f363938a84f2..fd149b8bbf0c 100644 --- a/sound/soc/codecs/amlogic/ad82584f.h +++ b/sound/soc/codecs/amlogic/ad82584f.h @@ -1,6 +1,7 @@ #ifndef _AD82584F_H #define _AD82584F_H +#define MUTE 0x02 #define MVOL 0x03 #define C1VOL 0x04 #define C2VOL 0x05 diff --git a/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c b/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c index d2673b244fe2..174babef5a71 100644 --- a/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c +++ b/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c @@ -129,7 +129,8 @@ static int aml_DAC_Gain_set_enum( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); u32 reg_addr = ACODEC_1; u32 val = snd_soc_read(codec, reg_addr); @@ -177,7 +178,8 @@ static int aml_DAC2_Gain_set_enum( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); u32 reg_addr = ACODEC_7; u32 val = snd_soc_read(codec, reg_addr); @@ -784,6 +786,12 @@ static int aml_tl1_acodec_probe(struct platform_device *pdev) pr_info("aml_tl1_acodec tdmout_index=%d\n", aml_acodec->tdmout_index); + of_property_read_u32( + pdev->dev.of_node, + "dat1_ch_sel", + &aml_acodec->dat1_ch_sel); + pr_info("aml_tl1_acodec dat1_ch_sel=%d\n", + aml_acodec->dat1_ch_sel); of_property_read_u32( pdev->dev.of_node, "tdmin_index", diff --git a/sound/soc/codecs/amlogic/tas5707.c b/sound/soc/codecs/amlogic/tas5707.c index 38c9d5d1c2e3..a8d765401baf 100644 --- a/sound/soc/codecs/amlogic/tas5707.c +++ b/sound/soc/codecs/amlogic/tas5707.c @@ -185,6 +185,7 @@ static const struct snd_kcontrol_new tas5707_snd_controls[] = { 0xff, 1, chvol_tlv), SOC_SINGLE("Ch1 Switch", DDX_SOFT_MUTE, 0, 1, 1), SOC_SINGLE("Ch2 Switch", DDX_SOFT_MUTE, 1, 1, 1), + SOC_SINGLE("Shutdown Switch", DDX_SYS_CTL_2, 6, 1, 1), SOC_SINGLE_RANGE("Fine Master Volume", DDX_CHANNEL3_VOL, 0, 0x80, 0x83, 0), SOC_SINGLE_BOOL_EXT("Set EQ Enable", 0, diff --git a/sound/soc/codecs/amlogic/tas5805.c b/sound/soc/codecs/amlogic/tas5805.c new file mode 100644 index 000000000000..36f11cf2c519 --- /dev/null +++ b/sound/soc/codecs/amlogic/tas5805.c @@ -0,0 +1,547 @@ +/* + * Driver for the TAS5805M Audio Amplifier + * + * Author: Andy Liu + * + * 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tas5805.h" + +#define TAS5805M_DRV_NAME "tas5805m" + +#define TAS5805M_RATES (SNDRV_PCM_RATE_8000 | \ + SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000) +#define TAS5805M_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define TAS5805M_REG_00 (0x00) +#define TAS5805M_REG_03 (0x03) +#define TAS5805M_REG_24 (0x24) +#define TAS5805M_REG_25 (0x25) +#define TAS5805M_REG_26 (0x26) +#define TAS5805M_REG_27 (0x27) +#define TAS5805M_REG_28 (0x28) +#define TAS5805M_REG_29 (0x29) +#define TAS5805M_REG_2A (0x2a) +#define TAS5805M_REG_2B (0x2b) +#define TAS5805M_REG_35 (0x35) +#define TAS5805M_REG_7F (0x7f) + +#define TAS5805M_PAGE_00 (0x00) +#define TAS5805M_PAGE_2A (0x2a) + +#define TAS5805M_BOOK_00 (0x00) +#define TAS5805M_BOOK_8C (0x8c) + +#define TAS5805M_VOLUME_MAX (158) +#define TAS5805M_VOLUME_MIN (0) + +const uint32_t tas5805m_volume[] = { + 0x0000001B, //0, -110dB + 0x0000001E, //1, -109dB + 0x00000021, //2, -108dB + 0x00000025, //3, -107dB + 0x0000002A, //4, -106dB + 0x0000002F, //5, -105dB + 0x00000035, //6, -104dB + 0x0000003B, //7, -103dB + 0x00000043, //8, -102dB + 0x0000004B, //9, -101dB + 0x00000054, //10, -100dB + 0x0000005E, //11, -99dB + 0x0000006A, //12, -98dB + 0x00000076, //13, -97dB + 0x00000085, //14, -96dB + 0x00000095, //15, -95dB + 0x000000A7, //16, -94dB + 0x000000BC, //17, -93dB + 0x000000D3, //18, -92dB + 0x000000EC, //19, -91dB + 0x00000109, //20, -90dB + 0x0000012A, //21, -89dB + 0x0000014E, //22, -88dB + 0x00000177, //23, -87dB + 0x000001A4, //24, -86dB + 0x000001D8, //25, -85dB + 0x00000211, //26, -84dB + 0x00000252, //27, -83dB + 0x0000029A, //28, -82dB + 0x000002EC, //29, -81dB + 0x00000347, //30, -80dB + 0x000003AD, //31, -79dB + 0x00000420, //32, -78dB + 0x000004A1, //33, -77dB + 0x00000532, //34, -76dB + 0x000005D4, //35, -75dB + 0x0000068A, //36, -74dB + 0x00000756, //37, -73dB + 0x0000083B, //38, -72dB + 0x0000093C, //39, -71dB + 0x00000A5D, //40, -70dB + 0x00000BA0, //41, -69dB + 0x00000D0C, //42, -68dB + 0x00000EA3, //43, -67dB + 0x0000106C, //44, -66dB + 0x0000126D, //45, -65dB + 0x000014AD, //46, -64dB + 0x00001733, //47, -63dB + 0x00001A07, //48, -62dB + 0x00001D34, //49, -61dB + 0x000020C5, //50, -60dB + 0x000024C4, //51, -59dB + 0x00002941, //52, -58dB + 0x00002E49, //53, -57dB + 0x000033EF, //54, -56dB + 0x00003A45, //55, -55dB + 0x00004161, //56, -54dB + 0x0000495C, //57, -53dB + 0x0000524F, //58, -52dB + 0x00005C5A, //59, -51dB + 0x0000679F, //60, -50dB + 0x00007444, //61, -49dB + 0x00008274, //62, -48dB + 0x0000925F, //63, -47dB + 0x0000A43B, //64, -46dB + 0x0000B845, //65, -45dB + 0x0000CEC1, //66, -44dB + 0x0000E7FB, //67, -43dB + 0x00010449, //68, -42dB + 0x0001240C, //69, -41dB + 0x000147AE, //70, -40dB + 0x00016FAA, //71, -39dB + 0x00019C86, //72, -38dB + 0x0001CEDC, //73, -37dB + 0x00020756, //74, -36dB + 0x000246B5, //75, -35dB + 0x00028DCF, //76, -34dB + 0x0002DD96, //77, -33dB + 0x00033718, //78, -32dB + 0x00039B87, //79, -31dB + 0x00040C37, //80, -30dB + 0x00048AA7, //81, -29dB + 0x00051884, //82, -28dB + 0x0005B7B1, //83, -27dB + 0x00066A4A, //84, -26dB + 0x000732AE, //85, -25dB + 0x00081385, //86, -24dB + 0x00090FCC, //87, -23dB + 0x000A2ADB, //88, -22dB + 0x000B6873, //89, -21dB + 0x000CCCCD, //90, -20dB + 0x000E5CA1, //91, -19dB + 0x00101D3F, //92, -18dB + 0x0012149A, //93, -17dB + 0x00144961, //94, -16dB + 0x0016C311, //95, -15dB + 0x00198A13, //96, -14dB + 0x001CA7D7, //97, -13dB + 0x002026F3, //98, -12dB + 0x00241347, //99, -11dB + 0x00287A27, //100, -10dB + 0x002D6A86, //101, -9dB + 0x0032F52D, //102, -8dB + 0x00392CEE, //103, -7dB + 0x004026E7, //104, -6dB + 0x0047FACD, //105, -5dB + 0x0050C336, //106, -4dB + 0x005A9DF8, //107, -3dB + 0x0065AC8C, //108, -2dB + 0x00721483, //109, -1dB + 0x00800000, //110, 0dB + 0x008F9E4D, //111, 1dB + 0x00A12478, //112, 2dB + 0x00B4CE08, //113, 3dB + 0x00CADDC8, //114, 4dB + 0x00E39EA9, //115, 5dB + 0x00FF64C1, //116, 6dB + 0x011E8E6A, //117, 7dB + 0x0141857F, //118, 8dB + 0x0168C0C6, //119, 9dB + 0x0194C584, //120, 10dB + 0x01C62940, //121, 11dB + 0x01FD93C2, //122, 12dB + 0x023BC148, //123, 13dB + 0x02818508, //124, 14dB + 0x02CFCC01, //125, 15dB + 0x0327A01A, //126, 16dB + 0x038A2BAD, //127, 17dB + 0x03F8BD7A, //128, 18dB + 0x0474CD1B, //129, 19dB + 0x05000000, //130, 20dB + 0x059C2F02, //131, 21dB + 0x064B6CAE, //132, 22dB + 0x07100C4D, //133, 23dB + 0x07ECA9CD, //134, 24dB + 0x08E43299, //135, 25dB + 0x09F9EF8E, //136, 26dB + 0x0B319025, //137, 27dB + 0x0C8F36F2, //138, 28dB + 0x0E1787B8, //139, 29dB + 0x0FCFB725, //140, 30dB + 0x11BD9C84, //141, 31dB + 0x13E7C594, //142, 32dB + 0x16558CCB, //143, 33dB + 0x190F3254, //144, 34dB + 0x1C1DF80E, //145, 35dB + 0x1F8C4107, //146, 36dB + 0x2365B4BF, //147, 37dB + 0x27B766C2, //148, 38dB + 0x2C900313, //149, 39dB + 0x32000000, //150, 40dB + 0x3819D612, //151, 41dB + 0x3EF23ECA, //152, 42dB + 0x46A07B07, //153, 43dB + 0x4F3EA203, //154, 44dB + 0x58E9F9F9, //155, 45dB + 0x63C35B8E, //156, 46dB + 0x6FEFA16D, //157, 47dB + 0x7D982575, //158, 48dB +}; + +struct tas5805m_priv { + struct regmap *regmap; + + struct mutex lock; + + int vol; + int mute; +}; + +const struct regmap_config tas5805m_regmap = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, +}; + +static int tas5805m_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->access = + (SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE); + uinfo->count = 1; + + uinfo->value.integer.min = TAS5805M_VOLUME_MIN; + uinfo->value.integer.max = TAS5805M_VOLUME_MAX; + uinfo->value.integer.step = 1; + + return 0; +} + +static int tas5805m_mute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->access = + (SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE); + uinfo->count = 1; + + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + uinfo->value.integer.step = 1; + + return 0; +} + +static int tas5805m_vol_locked_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + ucontrol->value.integer.value[0] = tas5805m->vol; + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static inline int get_volume_index(int vol) +{ + int index; + + index = vol; + + if (index < TAS5805M_VOLUME_MIN) + index = TAS5805M_VOLUME_MIN; + + if (index > TAS5805M_VOLUME_MAX) + index = TAS5805M_VOLUME_MAX; + + return index; +} + +static void tas5805m_set_volume(struct snd_soc_codec *codec, int vol) +{ + unsigned int index; + uint32_t volume_hex; + uint8_t byte4; + uint8_t byte3; + uint8_t byte2; + uint8_t byte1; + + index = get_volume_index(vol); + volume_hex = tas5805m_volume[index]; + + byte4 = ((volume_hex >> 24) & 0xFF); + byte3 = ((volume_hex >> 16) & 0xFF); + byte2 = ((volume_hex >> 8) & 0xFF); + byte1 = ((volume_hex >> 0) & 0xFF); + + //w 58 00 00 + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + //w 58 7f 8c + snd_soc_write(codec, TAS5805M_REG_7F, TAS5805M_BOOK_8C); + //w 58 00 2a + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_2A); + //w 58 24 xx xx xx xx + snd_soc_write(codec, TAS5805M_REG_24, byte4); + snd_soc_write(codec, TAS5805M_REG_25, byte3); + snd_soc_write(codec, TAS5805M_REG_26, byte2); + snd_soc_write(codec, TAS5805M_REG_27, byte1); + //w 58 28 xx xx xx xx + snd_soc_write(codec, TAS5805M_REG_28, byte4); + snd_soc_write(codec, TAS5805M_REG_29, byte3); + snd_soc_write(codec, TAS5805M_REG_2A, byte2); + snd_soc_write(codec, TAS5805M_REG_2B, byte1); +} + +static int tas5805m_vol_locked_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + + tas5805m->vol = ucontrol->value.integer.value[0]; + tas5805m_set_volume(codec, tas5805m->vol); + + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static int tas5805m_mute(struct snd_soc_codec *codec, int mute) +{ + u8 reg03_value = 0; + u8 reg35_value = 0; +// struct snd_soc_codec *codec = dai->codec; + + if (mute) { + //mute both left & right channels + reg03_value = 0x0b; + reg35_value = 0x00; + } else { + //unmute + reg03_value = 0x03; + reg35_value = 0x11; + } + + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_REG_7F, TAS5805M_BOOK_00); + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_REG_03, reg03_value); + snd_soc_write(codec, TAS5805M_REG_35, reg35_value); + + return 0; +} + +static int tas5805m_mute_locked_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + + tas5805m->mute = ucontrol->value.integer.value[0]; + tas5805m_mute(codec, tas5805m->mute); + + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static int tas5805m_mute_locked_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + ucontrol->value.integer.value[0] = tas5805m->mute; + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static const struct snd_kcontrol_new tas5805m_vol_control[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Volume", + .info = tas5805m_vol_info, + .get = tas5805m_vol_locked_get, + .put = tas5805m_vol_locked_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Maser Volume Mute", + .info = tas5805m_mute_info, + .get = tas5805m_mute_locked_get, + .put = tas5805m_mute_locked_put, + } +}; + +static int tas5805m_snd_probe(struct snd_soc_codec *codec) +{ + int ret; + + ret = snd_soc_add_codec_controls(codec, tas5805m_vol_control, 2); + + return ret; +} + +static struct snd_soc_codec_driver soc_codec_tas5805m = { + .probe = tas5805m_snd_probe, +}; + +static const struct snd_soc_dai_ops tas5805m_dai_ops = { + //.digital_mute = tas5805m_mute, +}; + +static struct snd_soc_dai_driver tas5805m_dai = { + .name = "tas5805m-amplifier", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, + .rates = TAS5805M_RATES, + .formats = TAS5805M_FORMATS, + }, + .ops = &tas5805m_dai_ops, +}; + +static int tas5805m_probe(struct device *dev, struct regmap *regmap) +{ + struct tas5805m_priv *tas5805m; + int ret; + + tas5805m = devm_kzalloc(dev, sizeof(struct tas5805m_priv), GFP_KERNEL); + if (!tas5805m) + return -ENOMEM; + + dev_set_drvdata(dev, tas5805m); + tas5805m->regmap = regmap; + tas5805m->vol = 100; //100, -10dB + + mutex_init(&tas5805m->lock); + + ret = + regmap_register_patch(regmap, tas5805m_init_sequence, + ARRAY_SIZE(tas5805m_init_sequence)); + if (ret != 0) { + dev_err(dev, "Failed to initialize TAS5805M: %d\n", ret); + goto err; + + } + + ret = + snd_soc_register_codec(dev, &soc_codec_tas5805m, &tas5805m_dai, 1); + if (ret != 0) { + dev_err(dev, "Failed to register CODEC: %d\n", ret); + goto err; + } + + return 0; + +err: + return ret; + +} + +static int tas5805m_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + struct regmap_config config = tas5805m_regmap; + + regmap = devm_regmap_init_i2c(i2c, &config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return tas5805m_probe(&i2c->dev, regmap); +} + +static int tas5805m_remove(struct device *dev) +{ + snd_soc_unregister_codec(dev); + + return 0; +} + +static int tas5805m_i2c_remove(struct i2c_client *i2c) +{ + tas5805m_remove(&i2c->dev); + + return 0; +} + +static const struct i2c_device_id tas5805m_i2c_id[] = { + {"tas5805",}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tas5805m_i2c_id); + +#ifdef CONFIG_OF +static const struct of_device_id tas5805m_of_match[] = { + {.compatible = "ti,tas5805",}, + {} +}; + +MODULE_DEVICE_TABLE(of, tas5805m_of_match); +#endif + +static struct i2c_driver tas5805m_i2c_driver = { + .probe = tas5805m_i2c_probe, + .remove = tas5805m_i2c_remove, + .id_table = tas5805m_i2c_id, + .driver = { + .name = TAS5805M_DRV_NAME, + .of_match_table = tas5805m_of_match, + }, +}; + +module_i2c_driver(tas5805m_i2c_driver); + +MODULE_AUTHOR("Andy Liu "); +MODULE_DESCRIPTION("TAS5805M Audio Amplifier Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/amlogic/tas5805.h b/sound/soc/codecs/amlogic/tas5805.h new file mode 100644 index 000000000000..ba6066204b12 --- /dev/null +++ b/sound/soc/codecs/amlogic/tas5805.h @@ -0,0 +1,1880 @@ +#include +static const struct reg_sequence tas5805m_init_sequence[] = { + {0x00, 0x00}, + {0x7f, 0x00}, + {0x03, 0x02}, + {0x01, 0x11}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x29, 0x7c}, + {0x03, 0x02}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x29, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x46, 0x11}, + {0x03, 0x0f}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x66, 0x85}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x24, 0x00}, + {0x25, 0x28}, + {0x26, 0x7a}, + {0x27, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x28, 0x00}, + {0x29, 0x28}, + {0x2a, 0x7a}, + {0x2b, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x0b}, + {0x28, 0x00}, + {0x29, 0x80}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x0b}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x18, 0x00}, + {0x19, 0x80}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x24, 0x00}, + {0x25, 0x80}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x24, 0x00}, + {0x25, 0x28}, + {0x26, 0x7a}, + {0x27, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x28, 0x00}, + {0x29, 0x28}, + {0x2a, 0x7a}, + {0x2b, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x30, 0x00}, + {0x31, 0xe2}, + {0x32, 0xc4}, + {0x33, 0x6b}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x14, 0x00}, + {0x15, 0x80}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x1c, 0x00}, + {0x1d, 0x80}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x2c, 0x00}, + {0x2d, 0x80}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x34, 0x00}, + {0x35, 0x80}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x4c, 0x00}, + {0x4d, 0x80}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x57}, + {0x5f, 0x62}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x60, 0x00}, + {0x61, 0x03}, + {0x62, 0x69}, + {0x63, 0xd0}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x64, 0x00}, + {0x65, 0xce}, + {0x66, 0xc0}, + {0x67, 0x8a}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x68, 0x40}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x6c, 0x05}, + {0x6d, 0x1f}, + {0x6e, 0x97}, + {0x6f, 0x37}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x18, 0x7a}, + {0x19, 0xe0}, + {0x1a, 0x68}, + {0x1b, 0xc9}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0xae}, + {0x1f, 0xc3}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x2c, 0x00}, + {0x2d, 0x80}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x31}, + {0x48, 0x40}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x32}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x33}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x34}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x35}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x29}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x08, 0x00}, + {0x09, 0x80}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x48, 0x7f}, + {0x49, 0xff}, + {0x4a, 0xff}, + {0x4b, 0xff}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x58, 0x00}, + {0x59, 0x06}, + {0x5a, 0xd3}, + {0x5b, 0x72}, + {0x5c, 0x00}, + {0x5d, 0x02}, + {0x5e, 0xbb}, + {0x5f, 0x06}, + {0x60, 0x00}, + {0x61, 0x03}, + {0x62, 0x69}, + {0x63, 0xc5}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0xf9}, + {0x71, 0xda}, + {0x72, 0xbc}, + {0x73, 0x21}, + {0x74, 0xfc}, + {0x75, 0x58}, + {0x76, 0x8b}, + {0x77, 0x89}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2b}, + {0x34, 0x00}, + {0x35, 0x06}, + {0x36, 0xd3}, + {0x37, 0x72}, + {0x38, 0x00}, + {0x39, 0x02}, + {0x3a, 0xbb}, + {0x3b, 0x06}, + {0x3c, 0x00}, + {0x3d, 0x03}, + {0x3e, 0x69}, + {0x3f, 0xc5}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0xf9}, + {0x4d, 0xda}, + {0x4e, 0xbc}, + {0x4f, 0x21}, + {0x50, 0xfc}, + {0x51, 0x58}, + {0x52, 0x8b}, + {0x53, 0x89}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x34, 0x7f}, + {0x35, 0xff}, + {0x36, 0xff}, + {0x37, 0xff}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x30, 0x00}, + {0x31, 0x06}, + {0x32, 0xd3}, + {0x33, 0x72}, + {0x34, 0x00}, + {0x35, 0x02}, + {0x36, 0xbb}, + {0x37, 0x06}, + {0x38, 0x00}, + {0x39, 0x03}, + {0x3a, 0x69}, + {0x3b, 0xc5}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0xf9}, + {0x49, 0xda}, + {0x4a, 0xbc}, + {0x4b, 0x21}, + {0x4c, 0xfc}, + {0x4d, 0x58}, + {0x4e, 0x8b}, + {0x4f, 0x89}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x5c, 0x7f}, + {0x5d, 0xff}, + {0x5e, 0xff}, + {0x5f, 0xff}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x70, 0x7f}, + {0x71, 0xff}, + {0x72, 0xff}, + {0x73, 0xff}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2b}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2b}, + {0x0c, 0x7f}, + {0x0d, 0xff}, + {0x0e, 0xff}, + {0x0f, 0xff}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2b}, + {0x20, 0x7f}, + {0x21, 0xff}, + {0x22, 0xff}, + {0x23, 0xff}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2e}, + {0x40, 0x7f}, + {0x41, 0xff}, + {0x42, 0xff}, + {0x43, 0xff}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2e}, + {0x54, 0x7f}, + {0x55, 0xff}, + {0x56, 0xff}, + {0x57, 0xff}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x18, 0x00}, + {0x19, 0x80}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x1c, 0x40}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x20, 0x40}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, +//Register Tuning + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x30, 0x00}, + {0x60, 0x00}, + {0x62, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x4c, 0x30}, + {0x4d, 0x30}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x02, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x03, 0x03}, + {0x35, 0x11}, +};